【数据分析】基于时间序列的预测方法(2021 |
您所在的位置:网站首页 › 风铃是哪里的特产 › 【数据分析】基于时间序列的预测方法(2021 |
时间序列预测
目录
时间序列预测 1.时间序列介绍 2.原始数据集 3.导入数据 4.检测时间序列的*稳性 5.如何使时间序列*稳 5.1 估计和消除趋势 5.1.1 对数转换 5.1.2 移动*均 5.2 消除趋势和季节性 5.2.1 差异化 5.2.2 分解 6.预测时间序列 6.1 AR Model 6.2 MA Model 6.3 Combined Model 6.4 恢复到原始比例 1.时间序列介绍时间序列(Time Series,TS)是数据科学中比较有意思的一个领域。顾名思义,TS是按固定时间间隔收集的数据点的集合。对这些数据进行分析以确定长期趋势,以便预测未来或执行其他形式的分析。但是TS又与常规回归问题不同。 它是时间相关的。因此,在这种情况下,“观测值是独立的线性回归模型”这个基本假设不成立。 随着趋势的增加或减少,大多数TS具有某种形式的季节性趋势,即特定时间范围内的变化。例如,一件羊毛夹克的销量,随着时间不断向前推进,我们会发现在冬季总是有更高的销量。 2.原始数据集我们以一家超市某种物品的销量作为模拟分析的对象。第一列是字符串格式的日期(从20200101到20200523),第二列是销量情况。 导入数据,输出前几个数据看一下格式。 data = pd.read_csv('Sales.csv') print(data.head()) data.dtypes
parse_dates:指定包含时间信息的列。如上所述,列名称为“日期”。 index_col:对TS数据使用Pandas的一个关键思想是索引必须是描述时间信息的变量。因此,此参数告诉Pandas使用“日期”列作为索引。 date_parser:指定了一个将输入字符串转换为datetime变量的函数。默认情况下,Pandas读取格式为“ YYYY-MM-DD HH:MM:SS”的数据。如果数据不是这种格式,则必须手动定义格式。因此,可以使用类似于此处定义的dataparse函数的功能。 我们可以看到数据以时间对象为索引。 data.index
如果TS的统计特性(例如均值,方差)随时间保持恒定,则称TS是固定的。大多数TS模型都是在TS固定的前提下工作的。所以在一般情况下,我们可以认为,如果某个TS随时间具有特定的行为,那么将来很有可能会遵循相同的行为。而且,与非*稳序列相比,*稳序列有关的理论更加成熟并且更易于实现。 *稳性有着非常严格的标准定义。但是,出于实际考虑,如果该序列随时间具有不变的统计特性,则可以假定该序列是*稳的。本文提到的*稳性需满足: 恒定均值 恒定方差 不依赖时间的自协方差 原始销量变化趋势图。 plt.plot(ts)
绘制移动统计数据:通过绘制移动*均值或移动方差趋势图,判断其是否随时间变化。 Dickey-Fuller检验:这是用于检查*稳性的统计检验之一。这里的零假设是TS是非*稳的。测试结果包括测试统计量和一些差异置信度的临界值。如果“检验统计量”小于“临界值”,我们可以拒绝原假设并说该序列是*稳的。 下面的test_stationarity()函数则包含了上面提到的两种方法。 !pip install statsmodels from statsmodels.tsa.stattools import adfuller def test_stationarity(timeseries): #Determing rolling statistics rolmean = timeseries.rolling(window=12).mean() rolstd = timeseries.rolling(window=12).std() #Plot rolling statistics: orig = plt.plot(timeseries, color='blue',label='Original') mean = plt.plot(rolmean, color='red', label='Rolling Mean') std = plt.plot(rolstd, color='black', label = 'Rolling Std') plt.legend(loc='best') plt.title('Rolling Mean & Standard Deviation') plt.show(block=False) #Perform Dickey-Fuller test: print('Results of Dickey-Fuller Test:') dftest = adfuller(timeseries, autolag='AIC') dfoutput = pd.Series(dftest[0:4], index=['Test Statistic','p-value','#Lags Used','Number of Observations Used']) for key,value in dftest[4].items(): dfoutput['Critical Value (%s)'%key] = value print(dfoutput) test_stationarity(ts)
尽管在许多TS模型中都采用了*稳性假设,但实际的时间序列几乎没有一个是*稳的。所幸我们已经找到了一些使时间序列*稳的方法。实际上,要使一个时间序列完全固定几乎是不可能的,但是我们尝试使其尽可能接**稳。 导致TS不*稳的背后原因主要有两个: 趋势——均值随时间变化。例如,乘客数量随时间增长。 季节性——在特定时间范围内的变化。例如,由于加薪或节日的影响,人们可能会在特定月份购买汽车。 基本原理 是对时间序列中的趋势和季节性建模或估计,并将其从序列中删除以得到固定的时间序列。然后在该时间序列上实施统计预测技术。最后一步则是通过应用趋势和季节性约束将预测值转换为原始比例。 下面会讨论多种方法。有的可能效果很好,而有的可能效果不好。但是,我们的目的是掌握所有的方法,而不是仅仅关注眼前的问题。 5.1 估计和消除趋势 5.1.1 对数转换减小趋势的常用技巧是转换。例如,在上文原始数据趋势图中,我们可以清楚地看到存在明显的上升趋势。因此,我们可以应用变换来惩罚较高的值。可以取对数,*方根,立方根等。为简单起见,在这里进行对数转换(注意下图中纵坐标的变化)。 ts_log = np.log(ts) plt.plot(ts_log)
聚类。在一段时间内取*均值,例如每月/每周*均值。 *滑。取滑动*均值 多项式拟合。拟合回归模型。 下面会讨论移动*均技术。 5.1.2 移动*均在这种方法中,我们根据时间序列的频率取“k”个连续值的*均值。在这里,我们将参数设置为12,即最*12天的数据。 moving_avg = ts_log.rolling(12).mean() plt.plot(ts_log) plt.plot(moving_avg,color ='red')
但是,该方法的缺点是必须严格定义时间段。比如,我们可以采用月*均值,但是在复杂的情况下(例如预测股票价格),很难得出一个数字。因此,我们采用“加权移动*均”,其中,最新值的权重更高。分配权重的技术有多种,流行的是 指数加权移动*均 ,其中权重通过衰减因子分配给所有先前的值。 expwighted_avg = pd.DataFrame.ewm(ts_log,halflife = 12).mean() plt.plot(ts_log) plt.plot(expwighted_avg,color ='red')
前面讨论的简单趋势减少技术并不能在所有情况下都有效,尤其是季节性高的情况下。接下来讨论消除趋势和季节性的两种方法: 差异化:以特定的时间差来差异化。 分解:对趋势和季节性建模,并将其从模型中删除。 5.2.1 差异化在这项技术中,我们将特定时刻的观测值与前一时刻的观测值进行了差异。这在改善*稳性方面效果很好。此处使用一次偏移进行差异化。 ts_log_diff = ts_log - ts_log.shift() plt.plot(ts_log_diff)
这种方法对趋势和季节性分别建模,然后返回序列的残余部分。 from statsmodels.tsa.seasonal import seasonal_decompose decomposition = seasonal_decompose(ts_log) trend = decomposition.trend seasonal = decomposition.seasonal residual = decomposition.resid plt.subplot(411) plt.plot(ts_log, label='Original') plt.legend(loc='best') plt.subplot(412) plt.plot(trend, label='Trend') plt.legend(loc='best') plt.subplot(413) plt.plot(seasonal,label='Seasonality') plt.legend(loc='best') plt.subplot(414) plt.plot(residual, label='Residuals') plt.legend(loc='best') plt.tight_layout()
上面谈到的这些不同的技术都可以使TS趋于*稳。现在让我们在差分后的TS上建立模型。这是一种非常流行的技术,并且在这种情况下,将噪声和季节性重新添加到预测残差中相对较容易。执行了趋势和季节性估计技术后,可能出现两种情况: 在数值之间没有相关性的一个严格的*稳序列。这是简单的情况,其中我们可以将残差建模为白噪声,但这是非常罕见的。 数值之间有重大依赖性的时间序列。在这种情况下,我们需要使用ARIMA之类的统计模型来预测数据。 ARIMA,即自回归移动*均模型,对*稳时间序列的预测只是一个线性(如线性回归)方程。预测变量取决于ARIMA模型的参数(p,d,q): AR(Auto-Regressive,自回归)项的数量(p):AR项是因变量的滞后值。例如,如果p为5,则x(t)的预测变量为x(t-1)…x(t-5)。 MA(Moving Average,移动*均)项的数量(q): MA项是预测方程式中的滞后预测误差。例如,如果q为5,则x(t)的预测变量将为e(t-1)….e(t-5),其中e(i)是第i个瞬时移动*均值与实际值之间的差。 差异数(d):这些是非季节性差异数,即在这种情况下,我们采用一阶差分。因此,我们可以传递该变量并置d = 0,或者传递原始变量并置d = 1。两者都会产生相同的结果。 如何确定“ p”和“ q”的值呢? 自相关函数(Autocorrelation Function,ACF):它是TS与自身滞后版本之间的相关性的度量。例如,在滞后值为5,ACF会将时间点“t(1)”…“t(2)”处的序列与时间点“t(1)-5”……“ t(2)-5”处的序列进行比较。 局部自相关函数(Partial Autocorrelation Function,PACF):此方法在消除了TS与自身滞后版本之间的比较差异后,测量二者的相关性。例如,它将检查滞后值为5的相关性,但删除滞后值为1到4的影响。 差分后,绘制TS的ACF和PACF图。 #ACF and PACF plots: from statsmodels.tsa.stattools import acf, pacf lag_acf = acf(ts_log_diff, nlags=20) lag_pacf = pacf(ts_log_diff, nlags=20, method='ols') #Plot ACF: plt.subplot(121) plt.plot(lag_acf) plt.axhline(y=0,linestyle='--',color='gray') plt.axhline(y=-1.96/np.sqrt(len(ts_log_diff)),linestyle='--',color='gray') plt.axhline(y=1.96/np.sqrt(len(ts_log_diff)),linestyle='--',color='gray') plt.title('Autocorrelation Function') #Plot PACF: plt.subplot(122) plt.plot(lag_pacf) plt.axhline(y=0,linestyle='--',color='gray') plt.axhline(y=-1.96/np.sqrt(len(ts_log_diff)),linestyle='--',color='gray') plt.axhline(y=1.96/np.sqrt(len(ts_log_diff)),linestyle='--',color='gray') plt.title('Partial Autocorrelation Function') plt.tight_layout()
p – PACF的滞后值图表首次超过上限置信区间。如果密切注意,在这种情况下,p = 2。 q – ACF图表首次超过上限置信区间的滞后值。如果您密切注意,在这种情况下,q = 2。 下面3个不同的ARIMA模型,将分别考虑单独情况和综合情况,并输出RSS。这里的RSS是指残差值,而不是实际的序列。 from statsmodels.tsa.arima_model import ARIMA 6.1 AR Model model = ARIMA(ts_log, order=(2, 1, 0)) results_AR = model.fit(disp=-1) plt.plot(ts_log_diff) plt.plot(results_AR.fittedvalues, color='red') plt.title('RSS: %.4f'% sum((results_AR.fittedvalues-ts_log_diff)**2))
由于组合模型提供了最佳结果,因此我们将其缩放回原始值并查看其在该位置的性能如何。第一步是将预测结果存储为单独的序列并进行观察。 predictions_ARIMA_diff = pd.Series(results_ARIMA.fittedvalues, copy=True) predictions_ARIMA_diff.head()
|
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |