数学建模--时间序列预测模型的七种经典算法的Python实现

目录

1.开篇版权提示

2.时间序列介绍 

3.项目数据处理

4.项目数据划分+可视化

5.时间预测序列经典算法1:朴素法

6.时间预测序列经典算法2: 简单平均法

7.时间预测序列经典算法3:移动平均法

8.时间预测序列经典算法4:简单指数法 

9.时间预测序列经典算法5:Holt线性趋势法

10.时间预测序列经典算法6:Holt-Winters季节性预测算法

11.时间预测序列经典算法7:自回归移动平均(ARIMA)算法

12.参考文章和致谢


1.开篇版权提示

"""
开篇提示:
这篇文章的绝大部分代码都不是我自己书写的,而是来自:https://www.cnblogs.com/lfri/articles/12243268.html#gallery-5的文章中。
由于目前很多的时间序列预测模型的文章中都没有给出相关的数据集,所以我不能够很好的进行对应的学习和代码的运行
而这篇文章,给出了对应的数据集,所以我就通过这篇文章来对于时间序列预测模型有一个更好的理解,在这里对于这位作者表示不尽的感谢!
如果有涉及到版权问题,请及时联系我对文章做相应的修改或者删除!
再次申明:
代码文章出处:https://www.cnblogs.com/lfri/articles/12243268.html#gallery-5
本人仅作学习参考使用,本篇博客也仅作相关的理解研究的标注,需要更深的理解交流请跳转上述网址出处,本人不胜感激!
"""

2.时间序列介绍 

时间序列介绍
"""
时间预测序列模型是一个非常强大的预测模型算法,其体现在对于根据先前的数据经验的整理学习来完成对于未来的合理预测和计算,是数学建模中一种基础的预测算法。
文章将通过一个项目的处理解决来对于7种时间序列预测的模型算法的研究并且对比分析它们的优缺点和不足之处
"""
实践项目题目
"""
Question:
假设给出了过去两年不同时间段的乘客的数量,要求你根据这些数据(2012 年 8 月至 2014 年 8月),需要用这些数据预测接下来 7 个月的乘客数量。
注意:数据集保存在时间预测模型材料包中,详见:time_data.csv
"""

3.项目数据处理

"""
首先我们通过pandas对于数据集有一个简单的了解,该数据集是由18288个数据组构成的,其中包括了其ID,Datetime和Count数据
通过df.head(10)我们查阅了前10列的元素,对于数据集有了相应的理解。
"""
import pandas as pd 
import numpy as np 
import matplotlib.pyplot as plt
df = pd.read_csv('C:\\Users\\Zeng Zhong Yan\\Desktop\\时间预测模型材料包\\time_data.csv')
df.head()
df.shape#(18288, 3)
print(df.head(10))

4.项目数据划分+可视化

"""
现在我们需要进行进一步的处理:
我们将前11856个元素,也就是从2012 年8月-2013年12月的数据单独拿出来制作一个数据集,以此作为训练集
我们再将剩余的元素拿出来作为作为测试集,用来检测模型的精确程度。
接下来我们将完成3个步骤:
#1.对于训练数据和测试数据进行步划分
#2.对于数据进行一个采样划分
#3.进行可视化绘图
"""
import pandas as pd
import matplotlib.pyplot as pltdf = pd.read_csv('C:\\Users\\Zeng Zhong Yan\\Desktop\\时间预测模型材料包\\time_data.csv', nrows=11856)
#对于训练数据和测试数据进行步划分
train = df[0:10392]
test = df[10392:]#对于数据进行一个采样划分
df['Timestamp'] = pd.to_datetime(df['Datetime'], format='%d-%m-%Y %H:%M')  # 4位年用Y,2位年用y
df.index = df['Timestamp']
df = df.resample('D').mean() #按天采样,计算均值train['Timestamp'] = pd.to_datetime(train['Datetime'], format='%d-%m-%Y %H:%M')
train.index = train['Timestamp']
train = train.resample('D').mean() #test['Timestamp'] = pd.to_datetime(test['Datetime'], format='%d-%m-%Y %H:%M')
test.index = test['Timestamp']
test = test.resample('D').mean()#绘制测试集和训练集的点在图片上,进行可视化后知道数据是如何变化的
train.Count.plot( title= 'Daily Ridership', fontsize=14)
test.Count.plot(title= 'Daily Ridership', fontsize=14)
plt.savefig('C:/Users/Zeng Zhong Yan/Desktop/时间序列1.png', dpi=500, bbox_inches='tight')
plt.show()

5.时间预测序列经典算法1:朴素法

"""
经典算法1:朴素法
朴素法的思想告诉我们,如果一个对象的变化很平稳,只会进行一般的波动,那么我们就可以预测t+1天的数值y(t+1)=y(t)
所以我们可以设想,朴素法预测之后的图像应该失调平稳的直线。
如下图所示,我们可以明显的发现朴素法的预测明显差距过大了,显然这很不合适。
朴素法并不适合变化很大的数据集,最适合稳定性很高的数据集。
"""
dd = np.asarray(train['Count'])
y_hat = test.copy()
y_hat['naive'] = dd[len(dd) - 1]
plt.plot(train.index, train['Count'], label='Train')
plt.plot(test.index, test['Count'], label='Test')
plt.plot(y_hat.index, y_hat['naive'], label='Naive Forecast')
plt.legend(loc='best')
plt.title("Naive Forecast")
plt.savefig('C:/Users/Zeng Zhong Yan/Desktop/时间序列2.png', dpi=500, bbox_inches='tight')
plt.show()

"""
朴素法到底有多大的误差呢?
我们计算下均方根误差,检查模型在测试数据集上的准确率,结果发现均方误差RMS=43.91640614391676
"""
from sklearn.metrics import mean_squared_error
from math import sqrtrms = sqrt(mean_squared_error(test['Count'], y_hat['naive']))
print("均方误差RMS=",rms)

6.时间预测序列经典算法2: 简单平均法

"""
经典算法2:简答平均法
对象的数值会随机上涨和下跌,平均值一般会比较稳定,保持一致。
我们经常会遇到一些数据集,虽然在一定时期内出现小幅变动,但每个时间段的平均值确实保持不变。
这种情况下,我们可以预测出第二天的预测值大致和过去天数的价格平均值一致。
这种将预期值等同于之前所有观测点的平均值的预测方法就叫简单平均法。
公式y(t+1)=sum(y(i))/n(i=1,2,3,4.....n)
"""
y_hat_avg = test.copy()
y_hat_avg['avg_forecast'] = train['Count'].mean()
plt.plot(train['Count'], label='Train')
plt.plot(test['Count'], label='Test')
plt.plot(y_hat_avg['avg_forecast'], label='Average Forecast')
plt.legend(loc='best')
plt.savefig('C:/Users/Zeng Zhong Yan/Desktop/时间序列3.png', dpi=500, bbox_inches='tight')
plt.show()

 

7.时间预测序列经典算法3:移动平均法

"""
经典算法3:移动平均法
研究的数据在一段时间内大幅上涨,但后来又趋于平稳。我们也经常会遇到这种数据集,比如价格或销售额某段时间大幅上升或下降。
这样的话对于整体平均数的计算的值显然是不合理的,因为极大极小的数已经影响到平均数合理的大小了。
如果我们这时用之前的简单平均法,就得使用所有先前数据的平均值,但在这里使用之前的所有数据是说不通的,因为用开始阶段的价格值会大幅影响接下来日期的预测值。
因此我们对于时间进行分段截取,分别计算切断时间的平均值,这样会显得更加合理一些。
很明显这里的逻辑是划分窗口区,这种用某些窗口期计算平均值的预测方法就叫移动平均法。
"""

8.时间预测序列经典算法4:简单指数法 

"""
经典算法四:简单指数法
我们注意到简单平均法和加权移动平均法在选取时间点的思路上存在较大的差异。
我们就需要在这两种方法之间取一个折中的方法,在将所有数据考虑在内的同时也能给数据赋予不同非权重。
例如,相比更早时期内的观测值,它会给近期的观测值赋予更大的权重。按照这种原则工作的方法就叫做简单指数平滑法。
它通过加权平均值计算出预测值,其中权重随着观测值从早期到晚期的变化呈指数级下降,最小的权重和最早的观测值相关:
这样可能早期的指数所占的权重就更大,越晚期的指数所占的权重就越小
这样的话我们就得出了如下的计算公式:y(t+1)=a*y(t)+(1-a)*y(t-1)
"""
from statsmodels.tsa.api import SimpleExpSmoothingy_hat_avg = test.copy()
fit = SimpleExpSmoothing(np.asarray(train['Count'])).fit(smoothing_level=0.6, optimized=False)
y_hat_avg['SES'] = fit.forecast(len(test))
plt.plot(train['Count'], label='Train')
plt.plot(test['Count'], label='Test')
plt.plot(y_hat_avg['SES'], label='SES')
plt.legend(loc='best')
plt.savefig('C:/Users/Zeng Zhong Yan/Desktop/时间序列4.png', dpi=500, bbox_inches='tight')
plt.show()

9.时间预测序列经典算法5:Holt线性趋势法

"""
经典算法5:Holt线性趋势法
如果物对象的观测值是呈不断上涨的总体趋势的,我们在一段时间内观察到的数值的总体的模式。
每个时序数据集可以被划分为为相应的几个部分:趋势(Trend),季节性(Seasonal)和残差(Residual)。
通Holt线性趋势法,我们可以预测任何时期呈现变化趋势的曲线的预测值
"""
import statsmodels.api as sm
sm.tsa.seasonal_decompose(train['Count']).plot()
result = sm.tsa.stattools.adfuller(train['Count'])
plt.savefig('C:/Users/Zeng Zhong Yan/Desktop/时间序列100.png', dpi=500, bbox_inches='tight')
plt.show()

from statsmodels.tsa.api import Holty_hat_avg = test.copy()fit = Holt(np.asarray(train['Count'])).fit(smoothing_level=0.3, smoothing_slope=0.1)
y_hat_avg['Holt_linear'] = fit.forecast(len(test))plt.plot(train['Count'], label='Train')
plt.plot(test['Count'], label='Test')
plt.plot(y_hat_avg['Holt_linear'], label='Holt_linear')
plt.legend(loc='best')
plt.savefig('C:/Users/Zeng Zhong Yan/Desktop/时间序列6.png', dpi=500, bbox_inches='tight')
plt.show()

 

10.时间预测序列经典算法6:Holt-Winters季节性预测算法

"""
经典算法6:Holt-Winters季节性预测算法
我们之前在面临波动较大的数据的时候显得就是束手无策了,很显然前5种算法对于波动值的处理都不尽如人意!
所以造成了我们的预测有的时候就往往误差过大,预测不够精准!
我们之前讨论的5种模型在预测时并没有考虑到数据集的季节性,因此我们需要一种能考虑这种因素的方法。
应用到这种情况下的算法就叫做Holt-Winters季节性预测模型。
它是一种三次指数平滑预测,其背后的理念就是除了水平和趋势外,还将指数平滑应用到季节分量上。
Holt-Winters季节性预测模型由预测函数和三次平滑函数——一个是水平函数ℓt,一个是趋势函数bt,一个是季节分量 st,以及平滑参数α,β和γ。
在Holt-Winters算法中,我们采用的是相加和相乘的方法:
当季节性变化大致相同时,优先选择相加方法,
当季节变化的幅度与各时间段的水平成正比时,优先选择相乘的方法。
这样进行的预测值可能会更加合理一些!
"""
from statsmodels.tsa.api import ExponentialSmoothingy_hat_avg = test.copy()
fit1 = ExponentialSmoothing(np.asarray(train['Count']), seasonal_periods=7, trend='add', seasonal='add', ).fit()
y_hat_avg['Holt_Winter'] = fit1.forecast(len(test))
plt.figure(figsize=(16, 8))
plt.plot(train['Count'], label='Train')
plt.plot(test['Count'], label='Test')
plt.plot(y_hat_avg['Holt_Winter'], label='Holt_Winter')
plt.legend(loc='best')
plt.savefig('C:/Users/Zeng Zhong Yan/Desktop/时间序列7.png', dpi=500, bbox_inches='tight')
plt.show()

11.时间预测序列经典算法7:自回归移动平均(ARIMA)算法

"""
经典算法7:自回归移动平均(ARIMA)算法
ARIMA算法是前面提到的经典算法的集大成者,
首先我们考虑到可指数平滑模型都是基于数据中的趋势和季节性的描述,
同时我们考虑回归移动平均模型的目标是描述数据中彼此之间的关系。
综合的结果使得我们预测出来的值会更加的合理,预测值和对应的测试值拟合的越来越成功
"""
import statsmodels.api as smy_hat_avg = test.copy()
fit1 = sm.tsa.statespace.SARIMAX(train.Count, order=(2, 1, 4), seasonal_order=(0, 1, 1, 7)).fit()
y_hat_avg['SARIMA'] = fit1.predict(start="2013-11-1", end="2013-12-31", dynamic=True)
plt.figure(figsize=(16, 8))
plt.plot(train['Count'], label='Train')
plt.plot(test['Count'], label='Test')
plt.plot(y_hat_avg['SARIMA'], label='SARIMA')
plt.legend(loc='best')
plt.savefig('C:/Users/Zeng Zhong Yan/Desktop/时间序列8.png', dpi=500, bbox_inches='tight')
plt.show()

 

12.参考文章和致谢

"""
#参考文章和致谢:
首先代码主要来源于:https://www.cnblogs.com/lfri/articles/12243268.html#gallery-5
如果我在每一个算法中都有解释,如果还不能够明白,请跳转至原文章来进行学习,作者深入浅出的教学以及比较细致的类比和公式一定能过使你明白时间序列预测模型!
在这里我感谢这篇文章对我的帮助,首先是有完全的数据集可使用,其次是带我完整地进行了一次python的项目分析,使我受益匪浅!
再次感谢文章和作者对于我的启发和帮助!
"""

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/70264.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C++学习记录——삼십이 C++IO流

文章目录 1、C标准IO流2、C文件IO流1、二进制读写2、文本读写 3、stringstream 1、C标准IO流 C语言的printf和scanf无法很好的输入输出自定义类型,且还需要程序员自己确定类型,所以C就引入了输入流和输出流,是设备和内存之间的沟通。 其实io…

Matlab信号处理2:方波信号的合成与分解

周期信号可展开为傅里叶级数,因此方波信号可用若干谐波去拟合。以下是Matlab的实现: %% 方波信号的分解% 1.生成方波信号 % 方波信号周期、基波频率 T0 2; w0 (2 * pi) / T0; % 方波信号值为1的区间 T1 0.5; % 绘图周期:(2*n1)个周期 n …

java利用aop来记录接口的请求耗时、请求参数、请求url等详细信息

最近在项目里面需要对一些controller接口进行记录。记录的信息包括,接口的耗时、请求参数、请求url、是否成功、请求的ip地址。 最后利用aop切面编程。 Order(1) Aspect Component Slf4j public class BehaviorAop {AutowiredBehaviorService behaviorService;/**…

C语言结构体的初始化方式

逐个初始化字段:这是最直接的方式,你可以逐个为结构体的每个字段进行初始化。 struct Student { char name[50]; int age; float marks; }; struct Student student1 {"Alice", 20, 89.5}; 2.使用结构体字面值初始化:这种方…

Elasticsearch 分布式搜索——聚合

1.聚合的种类 聚合常见的有三类: **桶(Bucket)**聚合:用来对文档做分组 TermAggregation:按照文档字段值分组,例如按照品牌值分组、按照国家分组Date Histogram:按照日期阶梯分组,例…

用户忠诚度:小程序积分商城的用户保持方法

随着移动互联网的蓬勃发展,小程序积分商城已经成为了许多企业私域营销的热门选择。这个商城不仅可以吸引用户参与,还可以提高用户的忠诚度,进一步加深用户与品牌的互动关系。然而,要实现用户的忠诚度,需要一系列的策略…

C++的内存管理是怎样的?

目录 C的内存管理代码段数据段BSS段堆区映射区栈区 C的内存管理 在C中,虚拟内存分为代码段、数据段、BSS段、堆区、文件映射区、栈区六部分: 代码段 包括只读存储区和文本区,其中只读存储区存储字符串常量,文本区存储程序的机器代码。 数据…

生信豆芽菜-机器学习筛选特征基因

网址:http://www.sxdyc.com/mlscreenfeature 一、使用方法 1、准备数据 第一个文件:特征表达数据 第二个文件:分组信息,第一列为样本名,第二列为患者分组 第三个文件:分析基因名 2、选择机器学习的方…

【C语言】入门——结构体

目录 结构体 为什么有结构体? 1.结构体的声明 1.2结构体变量的访问和初始化 2.结构体成员的访问 结构体 struct 结构体类型 {//相关属性; }结构体变量; 结构体和数组不同,同一类型的数据的集合是数组; 结构体是多种类型的数据的集合&…

使用GPT-4生成训练数据微调GPT-3.5 RAG管道

OpenAI在2023年8月22日宣布,现在可以对GPT-3.5 Turbo进行微调了。也就是说,我们可以自定义自己的模型了。然后LlamaIndex就发布了0.8.7版本,集成了微调OpenAI gpt-3.5 turbo的功能 也就是说,我们现在可以使用GPT-4生成训练数据&a…

被百度判定为低质量网站了!如何整改?

我是卢松松,点点上面的头像,欢迎关注我哦! 先说结论:接受现实,不要幻想百度恢复了! 百度自9月初大批量删除百度资源平台权限以来,几乎90%(未经证实**,但数量确实不小)的网站都被取消了权限&am…

vue3中的reactive赋值问题

问题 当通过方法对reactive变量修改的时候,发现页面上的值没有及时更新? 解决方法 具体原因: 上面这样赋值检测不到,因为响应式的是它的属性,而不是它自身. 方法1: 单个赋值 如下: let obj reactive({name: zha…

MySql学习笔记07——存储引擎介绍

存储引擎 Mysql中特有的术语,Oracle中没有。 存储引擎就是一个表存储/组织数据的方式。不同的存储引擎,表存储数据的方式不同。 指定存储引擎 在建表的时候可以在最后小括号的")"的右边使用: ENGINE来指定存储引擎。 CHARSET来…

YOLO目标检测——火焰检测数据集+已标注xml和txt格式标签下载分享

实际项目应用:火灾预警系统、智能监控系统、工业安全管理、森林火灾监测以及城市规划和消防设计等应用场景中具有广泛的应用潜力,可以提高火灾检测的准确性和效率,保障人员和财产的安全。数据集说明:YOLO火焰目标检测数据集&#…

GuLi商城-前端基础Vue-整合ElementUI快速开发

npm安装 启动项目:npm run dev http://localhost:8082/#/hello

02-Tomcat打破双亲委派机制

Tomcat 如果使用默认的双亲委派类加载机制行不行? 我们思考一下:Tomcat是个web容器, 那么它要解决什么问题: 一个web容器可能需要部署两个应用程序,不同的应用程序可能会依赖同一个第三方类库的不同版本,…

记:一次关于paddlenlp、python、版本之间的兼容性问题

兼容版本 Python 3.10.8 absl-py1.4.0 accelerate0.19.0 addict2.4.0 aiofiles23.1.0 aiohttp3.8.3 aiosignal1.3.1 alembic1.10.4 aliyun-python-sdk-core2.13.36 aliyun-python-sdk-kms2.16.0 altair4.2.2 altgraph0.17.3 aniso86019.0.1 antlr4-python3-runtime4.9.3 anyi…

问道管理:华为产业链股再度拉升,捷荣技术6连板,华力创通3日大涨近70%

华为产业链股6日盘中再度拉升,到发稿,捷荣技能涨停斩获6连板,华映科技亦涨停收成3连板,华力创通大涨超19%,蓝箭电子涨约11%,力源信息涨超4%。 捷荣技能盘中再度涨停,近7日已累计大涨超90%。公司…

Pycharm通用设置个性化设置

Pycharm通用设置&个性化设置 通用设置取消打开Pycharm自动进入项目开启【Ctrl鼠标滑轮】放大缩小字体 个性化设置设置彩虹括号 通用设置 取消打开Pycharm自动进入项目 选择选择菜单【File】>【Settings】进入设置页面选择【Appearance & Behavior】>【System S…

Git使用经验总结3-删除远端提交记录

文章目录 1. 问题2. 解决方案3. 参考 1. 问题 如果将有问题的代码提交到代码仓库甚至已经push到远端,这个时候就得想办法把提交撤销。一种方案是使用git revert,不过会造成历史记录留存的问题,git revert实际上是将某个版本又重新提交了一遍…