题外话:前段时间做了一点时间序列预测,积累了一点经验,写出来与大家分享一下。能力有限,若是有错误,请指正。本文理论内容不会特别多。
1.时间序列预测
时间序列预测,主要就是依靠过去和现在的数据,分析两者之间的关系,然后利用得到的这个关系去预测未来的数据。现在主要运用在股票和人口等的预测上。个人觉得时间序列预测与其他预测不同的,通常时间序列预测只有1维数据,所以很多机器学习方法不能直接使用。
2.时间序列预测模型
下面来说一下我做时间序列预测时用到的模型,首先是很简单的灰色预测模型,之后是非常普遍的ARIMA系列模型。
2.1灰色模型
灰色预测模型(Gray Model),这种模型的思想很简单,常用来对数据进行预测,在时间序列预测上的应用不是特别多。关于这个模型具体可以参考参考:https://blog.csdn.net/qq547276542/article/details/77865341
关于这个模型,我想说明的只有一点,就是这个模型的预测结果,无论是对训练集的拟合结果,还是预测的结果,除了第一组数据能够准确预测意外,其余的预测数据都呈单调递增或递减趋势。这点可以用理论证明:
由上述内容可以知道,灰色模型的预测值计算表达式为:
$$x^{(0)}(k+1)=x^{(1)}(k+1)-x^{(1)}(k)$$
$$=[(x^{(0)}(1)-\frac{b}{a}){\rm e}^{-ak}+\frac{b}{a}]-[(x^{(0)}(1)-\frac{b}{a}){\rm e}^{-a(k-1)}+\frac{b}{a}]$$
$$=(x^{(0)}(1)-\frac{b}{a})(1-{\rm e}^{a})({\rm e}^{-ak})$$
为了方便我把上式改写成了常见的方程形式如下:
$$y=(m-\frac{b}{a})(1-{\rm e}^{a}){\rm e}^{-ax}$$
对上式求一阶导数得到:
$$y^{'}=-a(m-\frac{b}{a})(1-{\rm e }^a) {\rm e }^{-ax}$$
简单的分析就可以知道,上式的符号不会发生变化,所以可以得到上面递增递减的结论。
2.2 ARMA、ARIMA模型
ARMA模型全程为自动回归积分滑动平均模型(Autoregressive Integrated Moving Average Model),网上对这个模型的介绍以及使用介绍的都非常多了,这里就省略了。因为刚开始做ARIMA实验的时候,对这个模型不太了解,所以我的实验参考了这篇博客。
https://www.cnblogs.com/foley/p/5582358.html
在具体的实验里,我们采用的拟合方式是把时间序列划分成3个序列(trend,seasonal,residual),然后对其中的各个部分分别进行拟合。但我们在实验中发现seasonal序列是一个有规律的序列(如下图,从图中可以看出从1949-01-01到1949-12-01所对应的数据与195-01-01到1950-12-01的数据一一对应,这12个数据重复出现。),所以对这个序列并没有进行拟合而直接使用。
对剩余的两部分分别拟合后。在把拟合后得到的三个序列相加就可以得到最终的拟合结果。并使用最终的模型预测未来5个月的数据。具体代码如下:
from statsmodels.tsa.arima_model import ARMA
import statsmodels as sm
import pandas as pd
import matplotlib as mpl
import matplotlib.pyplot as plt
from statsmodels.tsa.seasonal import seasonal_decompose
from statsmodels.tsa.stattools import adfuller
if __name__ == '__main__':
mpl.rcParams['font.sans-serif'] = 'SimHei'
mpl.rcParams['axes.unicode_minus'] = False
data=pd.read_csv('AirPassengers.csv',header=0,names=['date','peo_num'])
data = pd.Series(data["peo_num"].values, \
index=pd.DatetimeIndex(data["date"].values, freq='MS'))
decomposition=seasonal_decompose(data,model='additive')
trend=decomposition.trend
seasonal=decomposition.seasonal
residual=decomposition.resid
#对三部分分别进行拟合
trend.dropna(inplace=True)
trend_diff=trend.diff(periods=2)
trend_diff.dropna(inplace=True)
#分别对三部分进行拟合z
order_trend=sm.tsa.stattools.arma_order_select_ic(trend_diff)['bic_min_order']
#order_trend=(3,2)
model_trend=ARMA(trend_diff,order_trend)
result_trend=model_trend.fit()
predict_trend=result_trend.predict()+trend.shift(2)
forecast_trend,_,_=result_trend.forecast(11)
forecast_trend=pd.Series(forecast_trend,\
index=pd.DatetimeIndex(start='1960-07-01',end='1961-05-01',freq='MS'))
trend_predict=pd.concat([predict_trend,forecast_trend],axis=0)
for i in range(11,0,-1):
trend_predict.values[-i]+=trend_predict[-i-2]
value_seasonal=[]
for i in range(5):
value_seasonal.append(seasonal.values[i])
forecast_seasonal=pd.Series(value_seasonal,\
index=pd.DatetimeIndex(start='1961-01-01',end='1961-05-01',freq='MS'))
seasonal_predict=pd.concat([seasonal,forecast_seasonal],axis=0)
residual.dropna(inplace=True)
order_residual=sm.tsa.stattools.arma_order_select_ic(residual)['bic_min_order']
model_residual=ARMA(residual,order_residual)
result_residual=model_residual.fit()
predict_residual=result_residual.predict()
forecast_residual,_,_=result_residual.forecast(11)
forecast_residual=pd.Series(forecast_residual,\
index=pd.DatetimeIndex(start='1960-07-01',end='1961-05-01',freq='MS'))
residual_predict=pd.concat([predict_residual,forecast_residual],axis=0)
test_data=trend_predict+seasonal_predict+residual_predict
print(test_data)
data.plot(label='train_data',legend=True)
test_data.plot(label='forecast_data',legend=True)
plt.show()
关于代码中的几点需要做如下说明:
首先:在使用ARMA模型做预测的时候,从最开始的做差分,再到训练模型时选定的AR、MR阶数都导致了最终模型得到了训练数据的缺失。AirPassenger中的数据日期是从1949-01-01到1960-12-01,而在trend部分拟合时,result_trend.predict()输出的数据是从1949-07-01到1960-06-01,所以在trend部分预测时,不止预测了从1961-01-01到1961-05-01这部分的数据,还补充预测了1960-07-01到1960-12-01这部分的数据。
其次,我们投入到ARMA模型的数据是做了差分运算的数据,并且result_trend.predict()和result_trend.forecast()给出的数据也都是差分的数据。所以我们要对得到的数据进行还原。
接着,代码中并没有给出判断序列是否已经是平稳序列的代码,这部分可以参考上述博客。
最后,在上述代码中,确定ARMA的阶数时使用了python中已经写好的函数arma_order_select_ic,在这个函数运行时可能会抛出一些异常,如下:
目前这些异常是因为阶数选择不合适而导致的。在这个实验中,我们选择的是不会引起这些异常阶数对,所以在trend部分拟合是,我们没有选择arma_order_select_ic函数给出的‘bic_min_order’(在实验中为(2,2)),而选择了(3,2)
最终预测结果图如下。从图片显示的结果来看,预测的效果还不错。
最后要说明的时,由于ARMA模型的预测结果收敛速度很快(跟ARMA的阶数有关),所以这里只预测了5个月。预测的月份越多,结果越不准确。
题外话:前段时间做了一点时间序列预测,积累了一点经验,写出来与大家分享一下。能力有限,若是有错误,请指正。本文理论内容不会特别多。1.时间序列预测时间序列预测,主要就是依靠过去和现在的数据,分析两者之间的关系,然后利用得到的这个关系去预测未来的数据。现在主要运用在股票和人口等的预测上。个人觉得时间序列预测与其他预测不同的,通常时间序列预测只有1维数据,所以很多机器学习方法不能直接使用。...
文章目录prophet 安装数据集下载
prophet 实战导入包pandas 读取 csv 数据画个图拆分数据集从日期中拆分特征使用 prophet 训练和
预测
prophet 学到了什么放大图
prophet 安装
prophet 是facebook 开源的一款
时间
序列
预测
工具包,直接用 conda 安装 fbprophet 即可
prophet 的官网:https://facebook.github.io/prophet/
prophet 中文意思是“先知”
prophet 的输入一般具有两列:ds和y
ds(datestamp) 列应为 Pandas 可以识别的日期格式,日期应为YYYY-
时间
序列
分析:
时间
序列
表示基于
时间
顺序的一系列数据。 它可以是秒、分钟、小时、天、周、月、年。 未来的数据将取决于它以前的值。
在现实世界的案例中,我们主要有两种类型的
时间
序列
分析——
单变量
时间
序列
多元
时间
序列
对于单变量
时间
序列
数据,我们将使用单列进行
预测
。
正如我们所见,只有一列,因此即将到来
创建Date
time
1. pd.date_range(start= '2018-05-01', end= '2018-12-31')
2. pd.date_range(start='2018-05-01' ,periods = 100)# 产生100个Date
time
3. pd.date_range(start='2018-05-01' ,periods = 100,freq = 'W')#每...
Pandas Dataframe中diff()函数进行一阶差分操作的详解--使用实例解释diff差分操作
diff函数是从数学上来说,是将数据与平移后的数据进行比较得出的差异数据。从操作的意义上来说,是两条临近记录的差值,也就是一阶差分。下面用举例子的方式,将diff的功能进行阐述:
现在有一个DataFrame类型的数据df,如下:
现在对df进行一阶差分操作:df.diff(),得到...
时间
序列
算法
time
series
data mining 主要包括decompose(分析数据的各个成分,例如趋势,周期性),
prediction
(
预测
未来的值),classification(对有序数据
序列
的feature提取与分类),clustering(相似数列聚类)等。
时间
序列
的
预测
常用的思路:
1、计算平均值
2、exponential smoothing指数衰减
LSTM神经网络是一种在
时间
序列
预测
中广泛应用的深度学习模型。在复现"lstm-neural-network-for-
time
-
series
-
prediction
"这个项目时,可以按照以下步骤进行:
1. 导入所需的Python库,包括Keras和Numpy等。
2. 准备数据集,包括训练集和测试集。可以使用已有的
时间
序列
数据,如股票价格或天气数据。
3. 对数据进行预处理。可以使用特征缩放、平滑或差分等方法来准备数据输入。
4. 构建LSTM模型。可以使用Keras库中的LSTM类来构建模型,通过设置不同的参数来调整模型的结构和性能。
5. 编译和训练模型。使用适当的损失函数和优化器编译模型,并使用训练集进行迭代训练。
6. 进行
预测
和评估。使用训练好的模型对测试集进行
预测
,计算
预测
值与真实值之间的差异,评估模型的性能。
7. 可以根据需要进行调整和优化。如调整模型结构、参数调优、使用其他技术来提高模型的准确性。
此项目的核心是使用LSTM神经网络对
时间
序列
数据进行
预测
。通过使用适当的数据预处理和模型构建,可以提高模型的
预测
准确性。最终的目标是根据已有的
时间
序列
数据对未来的趋势进行
预测
。