题外话:前段时间做了一点时间序列预测,积累了一点经验,写出来与大家分享一下。能力有限,若是有错误,请指正。本文理论内容不会特别多。

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神经网络对 时间 序列 数据进行 预测 。通过使用适当的数据预处理和模型构建,可以提高模型的 预测 准确性。最终的目标是根据已有的 时间 序列 数据对未来的趋势进行 预测