面向初学者的指南:创建时间序列预测 (使用Python)


https://blog.csdn.net/orDream/article/details/100013682
上面这一篇是对
https://www.analyticsvidhya.com/blog/2016/02/time-series-forecasting-codes-python/
的翻译,但是版本已经过低部分代码已经失效,该博主对博文内容也不完全且有错误,在此对其python的部分做了更正和补充。
具体的错误可以查看https://www.cnblogs.com/xingnie/p/12248732.html
 
#加载和处理时间序列

2
import pandas as pd
import numpy as np
import matplotlib.pylab as plt
%matplotlib inline
from matplotlib.pylab import rcParams
rcParams['figure.figsize'] = 15, 6
 
No output

3
data = pd.read_csv('AirPassengers.csv')
print(data.head(n = 10))
# 默认 n为5)
print('\n Data Types:')
print(data.dtypes)

 
     Month  #Passengers
0  1949-01          112
1  1949-02          118
2  1949-03          132
3  1949-04          129
4  1949-05          121
5  1949-06          135
6  1949-07          148
7  1949-08          148
8  1949-09          136
9  1949-10          119

 Data Types:
Month          object
#Passengers     int64
dtype: object

5
#数据类型是“object”和“int”,所以它仍然不是作为TS对象读取的。
#为了将数据读取为时间序列,我们必须将特殊参数传递给read_csv命令:
dateparse = lambda dates: pd.datetime.strptime(dates, '%Y-%m')
data = pd.read_csv('AirPassengers.csv', parse_dates=['Month'], index_col='Month',date_parser=dateparse)
print(data.head())

#parse_dates:指定包含日期-时间信息的列。正如我们上面所说,列名是’ Month '。
#index_col:将panda用于TS数据背后的一个关键思想是,索引必须是描述日期-时间信息的变量。所以这个参数告诉熊猫使用“Month”列作为索引。
#date_parser:指定一个函数,该函数将输入字符串转换为datetime变量。默认情况下,熊猫读取的数据格式为“YYYY-MM-DD HH:MM:SS”。如果数据不是这种格式,则必须手动定义格式。类似于这里定义的dataparse函数可以用于此目的。

 
            #Passengers
Month                  
1949-01-01          112
1949-02-01          118
1949-03-01          132
1949-04-01          129
1949-05-01          121

6
#可以看到数据的索引是time对象,列是#passenger。我们可以用以下命令交叉检查索引的数据类型
data.index
6
DatetimeIndex(['1949-01-01', '1949-02-01', '1949-03-01', '1949-04-01',
               '1949-05-01', '1949-06-01', '1949-07-01', '1949-08-01',
               '1949-09-01', '1949-10-01',
               ...
               '1960-03-01', '1960-04-01', '1960-05-01', '1960-06-01',
               '1960-07-01', '1960-08-01', '1960-09-01', '1960-10-01',
               '1960-11-01', '1960-12-01'],
              dtype='datetime64[ns]', name='Month', length=144, freq=None)

7
#dtype= 'datetime[ns] ’ 确认它是一个datetime对象。作为个人偏好,我将把列转换成一个Series对象,以防止每次使用TS时引用列名。
ts = data['#Passengers'] 
ts.head(10)
7
Month
1949-01-01    112
1949-02-01    118
1949-03-01    132
1949-04-01    129
1949-05-01    121
1949-06-01    135
1949-07-01    148
1949-08-01    148
1949-09-01    136
1949-10-01    119
Name: #Passengers, dtype: int64

 
# 如何选择选择Series对象中的一个特定值

8
#1. Specific the index as a string constant:
ts['1949-01-01']

#2. Import the datetime library and use 'datetime' function:
from datetime import datetime
ts[datetime(1949,1,1)]


8
112

9
#假设我们想要到1949年5月为止的所有数据。这可以通过两种方式实现:
#1. Specify the entire range:
ts['1949-01-01':'1949-05-01']

#2. Use ':' if one of the indices is at ends:
ts[:'1949-05-01']

#与数字索引不同,这里 包含了结束索引。例如,如果我们将列表索引为[:5],那么它将返回索引处的值-[0,1,2,3,4]。但是这里的输出中包含索引 ‘1949-05-01’。
#索引必须按照范围排序。如果随机打乱索引,这将不起作用
9
Month
1949-01-01    112
1949-02-01    118
1949-03-01    132
1949-04-01    129
1949-05-01    121
Name: #Passengers, dtype: int64

10
#1949年所有值的例子。可以这样做:

ts['1949']
10
Month
1949-01-01    112
1949-02-01    118
1949-03-01    132
1949-04-01    129
1949-05-01    121
1949-06-01    135
1949-07-01    148
1949-08-01    148
1949-09-01    136
1949-10-01    119
1949-11-01    104
1949-12-01    118
Name: #Passengers, dtype: int64

 
# 检查时间序列平稳性
#常数平均值
#常数方差
#不依赖于时间的自协方差。

11
#简单地绘制数据图并进行可视化分析。数据可以使用以下命令绘制:
plt.plot(ts)
 
/Users/christopher/opt/anaconda3/lib/python3.7/site-packages/pandas/plotting/_matplotlib/converter.py:103: FutureWarning: Using an implicitly registered datetime converter for a matplotlib plotting method. The converter was registered by pandas on import. Future versions of pandas will require you to explicitly register matplotlib converters.

To register the converters:
	>>> from pandas.plotting import register_matplotlib_converters
	>>> register_matplotlib_converters()
  warnings.warn(msg, FutureWarning)
11
[<matplotlib.lines.Line2D at 0x10db131d0>]
 

 
很明显,数据中有一个总的 增长趋势,同时也有一些季节变化。然而,可能并不总是能够做出这样的视觉推断(我们稍后将看到这样的情况)。因此,更正式地说,我们可以使用以下方法检查平稳性:

绘制滚动统计:我们可以绘制移动平均或移动方差,看看它是否随时间而变化。我说的移动平均/方差是指在任何时刻t,我们取去年的平均/方差,即过去12个月。但这更像是一种视觉技巧。
Dickey-Fuller检验:这是检验平稳性的统计检验之一。这里零假设是 TS 是非平稳的。测试结果由 测试统计数据 和一些不同置信水平的临界值组成。如果“检验统计量”小于“临界值”,我们可以拒绝零假设,认为序列是平稳的。详情请参阅本文。
在这一点上,这些概念听起来可能不是很直观。我建议阅读前传的文章(查阅相关资料进一步深入理解)。如果你对一些理论统计学感兴趣,你可以参考Brockwell和Davis的 时间序列导论和预测。这本书的统计数据有点多,但如果你有阅读字里行间的技巧,你就能理解其中的概念,并间接地接触到统计数据。

14
#回到检查平稳性,我们将经常使用滚动统计图和Dickey-Fuller测试结果,所以我定义了一个函数,它接受TS作为输入并为我们生成它们。请注意,我画的是标准差而不是方差来保持单位接近均值。

from statsmodels.tsa.stattools import adfuller
def test_stationarity(timeseries):
    
    #Determing rolling statistics
    rolmean = timeseries.rolling(12).mean()
    rolstd = timeseries.rolling(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)
 
 
Results of Dickey-Fuller Test:
Test Statistic                   0.815369
p-value                          0.991880
#Lags Used                      13.000000
Number of Observations Used    130.000000
Critical Value (1%)             -3.481682
Critical Value (5%)             -2.884042
Critical Value (10%)            -2.578770
dtype: float64

 
虽然标准差的变化很小,但均值明显随时间增加,这不是一个平稳序列。此外,测试统计量远远超过临界值。注意,应该比较带符号的值,而不是绝对值。



 
4. 如何使时间序列平稳?

虽然在许多TS模型中采用了平稳性假设,但几乎没有一个实际的时间序列是平稳的。统计学家已经找到了使序列平稳的方法,我们现在就来讨论。实际上,让一个级数完全静止几乎是不可能的,但我们试着让它尽可能地接近。

让我们来理解是什么使TS非平稳。TS不稳定的主要原因有两个:

随时间变化的趋势平均值。例如,在这个例子中,我们看到平均来说,乘客的数量随着时间在增长。
季节性——特定时间段的变化。由于工资的增加或节日的缘故,人们在特定的月份可能会有买车的倾向。
其基本原理是对序列中的趋势和季节性进行建模或估计,并将其从序列中去除,得到一个平稳序列。在此基础上,应用统计预测技术对该系列产品进行预测。最后一步是通过应用趋势和季节约束将预测值转换为原始规模。注意:我将讨论一些方法。有些可能在这种情况下工作得很好,而另一些则不然。但我们的想法是掌握所有的方法,而不是只关注手头的问题。让我们从趋势部分开始。



15
#估计和消除趋势

#减少趋势的首要技巧之一是转变。
#例如,在这种情况下,我们可以清楚地看到,有一个显著的积极趋势。
#所以我们可以用变换来惩罚更大的值而不是更小的值。可以取对数,平方根,立方根,等等。为了简单起见,我们在这里做一个对数变换:
ts_log = np.log(ts)
plt.plot(ts_log)


15
[<matplotlib.lines.Line2D at 0x1c23295710>]
 

 
在这个更简单的例子中,很容易看到数据中的正向趋势。但在有噪声的情况下,它不是很直观。因此,我们可以使用一些技术来估计或建模这种趋势,然后将其从系列中删除。有很多方法可以做到这一点,其中最常用的有:

汇总—取一段时间内的平均值,如月/周平均值
平滑——取滚动平均线
多项式拟合-拟合回归模型
我将在这里讨论平滑,您也应该尝试其他技术,这可能会解决其他问题。平滑是指采用滚动估计,即考虑过去的几个例子。有很多种方法,但我将在这里讨论其中的两种。

17
#移动平均数

#在这种方法中,我们根据时间序列的频率取“k”连续值的平均值。这里我们可以取过去一年的平均值,也就是最近12个值。panda定义了用于确定滚动统计数据的特定函数。

moving_avg = ts_log.rolling(12).mean()
plt.plot(ts_log)
plt.plot(moving_avg, color='red')
17
[<matplotlib.lines.Line2D at 0x1c26335890>]
 

19
#红线表示滚动平均值。从原级数中减去这个。注意,由于我们取最后12个值的平均值,所以前11个值没有定义滚动平均值。这可以观察到:

ts_log_moving_avg_diff = ts_log - moving_avg
ts_log_moving_avg_diff.head(12)
19
Month
1949-01-01         NaN
1949-02-01         NaN
1949-03-01         NaN
1949-04-01         NaN
1949-05-01         NaN
1949-06-01         NaN
1949-07-01         NaN
1949-08-01         NaN
1949-09-01         NaN
1949-10-01         NaN
1949-11-01         NaN
1949-12-01   -0.065494
Name: #Passengers, dtype: float64

20
#注意前11位是Nan。让我们删除这些NaN值,并检查这些图以测试平稳性

ts_log_moving_avg_diff.dropna(inplace=True)
test_stationarity(ts_log_moving_avg_diff)
 
 
Results of Dickey-Fuller Test:
Test Statistic                  -3.162908
p-value                          0.022235
#Lags Used                      13.000000
Number of Observations Used    119.000000
Critical Value (1%)             -3.486535
Critical Value (5%)             -2.886151
Critical Value (10%)            -2.579896
dtype: float64

 
这个级数看起来好多了。滚动值似乎略有变化,但没有特定的趋势。同时,检验统计量 小于5%的临界值 所以我们可以有95%的信心说这是一个平稳序列。

然而,这种特殊方法的缺点是必须严格定义时间段。在这种情况下,我们可以取年平均水平,但在预测股票价格等复杂情况下,很难得出一个数字。因此,我们采用“加权移动平均”,即赋予较近期值较高的权重。可以有许多技术来分配权重。

26
#一种流行的方法是 指数加权移动平均法,它将权重分配给所有具有衰减因子的先前值。在这里找到详细信息。这可以在panda中实现为:
expwighted_avg = pd.DataFrame.ewm(ts_log, halflife=12).mean()
plt.plot(ts_log)
plt.plot(expwighted_avg, color='red')
#注意,这里使用参数“半衰期”来定义指数衰减的数量。这只是一个假设,主要取决于业务领域。其他参数,如跨度和质心也可以用来定义衰减,这是讨论在上面共享的链接。
    
26
[<matplotlib.lines.Line2D at 0x1c2661c550>]
 

27
#现在,让我们把这个从级数中移除,并检查平稳性:

ts_log_ewma_diff = ts_log - expwighted_avg
test_stationarity(ts_log_ewma_diff)
 
 
Results of Dickey-Fuller Test:
Test Statistic                  -3.601262
p-value                          0.005737
#Lags Used                      13.000000
Number of Observations Used    130.000000
Critical Value (1%)             -3.481682
Critical Value (5%)             -2.884042
Critical Value (10%)            -2.578770
dtype: float64

 
#这个TS在平均值和标准差上的变化更小。同时,测试统计量 小于1%的临界值,优于前一种情况。注意,在这种情况下,不会缺少值,因为从一开始所有的值都是给定权重的。所以即使没有之前的值,它也能工作。


 
No output

 
消除趋势和季节性

前面讨论的简单趋势减少技术并不是在所有情况下都有效,特别是那些具有高季节性的技术。让我们讨论两种消除趋势和季节性的方法:

差分-在特定的时间间隔内进行差分
分解——对趋势和季节性进行建模,并将它们从模型中移除。


28
#差分处理趋势和季节性的最常见方法之一。在这种方法中,我们取某一时刻的观测值与前一时刻的观测值之差。这在提高平稳性方面很有效。一阶差分可以在 Pandas 中运行:

ts_log_diff = ts_log - ts_log.shift()
plt.plot(ts_log_diff)
28
[<matplotlib.lines.Line2D at 0x1c26ac1a50>]
 

29
#这似乎大大降低了趋势。让我们用我们的图来验证:

ts_log_diff.dropna(inplace=True)
test_stationarity(ts_log_diff)
#我们可以看到,平均值和std随时间的变化有很小的变化。此外,Dickey-Fuller检验统计量小于10%的临界值,因此TS是稳定的,有90%的置信度。我们也可以采取二阶或三阶的差异,这可能在某些应用中得到更好的结果。我把它们留给你去尝试。
 
 
Results of Dickey-Fuller Test:
Test Statistic                  -2.717131
p-value                          0.071121
#Lags Used                      14.000000
Number of Observations Used    128.000000
Critical Value (1%)             -3.482501
Critical Value (5%)             -2.884398
Critical Value (10%)            -2.578960
dtype: float64

30
#分解:
#在这种方法中,趋势和季节性分别建模,并返回系列的其余部分。我将跳过统计数据,来看一下结果:

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()
 

31
#这里我们可以看到趋势,季节性从数据中分离出来我们可以对残差进行建模。检验残差的平稳性:

ts_log_decompose = residual
ts_log_decompose.dropna(inplace=True)
test_stationarity(ts_log_decompose)
#Dickey-Fuller检验统计量显著低于1%的临界值(p值<0.05)。所以这个TS非常接近于静止。您还可以尝试高级分解技术,这些技术可以生成更好的结果。另外,您应该注意,在这种情况下,将残差转换为未来数据的原始值并不十分直观。
 
 
Results of Dickey-Fuller Test:
Test Statistic                -6.332387e+00
p-value                        2.885059e-08
#Lags Used                     9.000000e+00
Number of Observations Used    1.220000e+02
Critical Value (1%)           -3.485122e+00
Critical Value (5%)           -2.885538e+00
Critical Value (10%)          -2.579569e+00
dtype: float64

 
5.预测时间序列

我们看到了不同的技术它们都能很好地使 TS 静止。让我们在差分后的TS上做模型,因为这是一种非常流行的技术。此外,在这种情况下,在预测残差中添加噪声和季节性因素也相对容易。执行趋势和季节估计技术后,可以出现两种情况:

一个严格平稳的序列,各值之间不依赖。这是一个简单的例子,我们可以把残差建模为白噪声。但这种情况非常罕见。
值之间具有显著相关性的序列。在这种情况下,我们需要使用一些统计模型,如ARIMA来预测数据。
让我给你简单介绍一下ARIMA。我不会详细介绍技术细节,但是如果您希望更有效地应用这些概念,您应该详细了解这些概念。ARIMA代表自回归综合移动平均线。平稳时间序列的ARIMA预测只不过是一个线性(类似于线性回归)方程。预测因子依赖于ARIMA模型的参数(p,d,q):AR(自回归)项数§:

AR项只是因变量的滞后。例如,如果p是5,那么x(t)的预测器将是x(t-1)……x(t-5)。
MA(移动平均)项数(q): MA项是预测方程中的滞后预测误差。例如,如果q是5,x(t)的预测因子将是e(t-1)…e(t-5)其中e(i)是第i个时刻的移动平均线与实际值之间的差值。
差异数量(d):这些是非季节性差异的数量,即在本例中我们取一阶差异。所以我们要么传递这个变量,让d=0,要么传递原始变量,让d=1。两者将产生相同的结果。
这里的一个重要问题是如何确定“p”和“q”的值。我们用两个图来确定这些数字。让我们先讨论一下。

自相关函数(ACF):它是一种度量TS与自身滞后版本之间相关性的方法。例如,在滞后5时,ACF会将瞬时“t1”…“t2”的序列与瞬时“t1-5”…“t2”的序列进行比较(t1-5和t2是端点)。
部分自相关函数(PACF):该函数测量TS与自身滞后版本之间的相关性,但在消除了已经由中间比较解释的变化之后。在滞后5时,它将检查相关性,但删除已经由滞后1到滞后4解释的影响

32
#经差分后的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()

#在这个图中,0两边的虚线是置信区间。这些可以用来确定“p”和“q”的值如下:
#p - PACF图第一次越过上置信区间时的滞后值。如果你仔细观察,这里p=2。
#q - ACF图第一次越过上置信区间时的滞后值。如果你仔细观察,这里q=2。

 
/Users/christopher/opt/anaconda3/lib/python3.7/site-packages/statsmodels/tsa/stattools.py:541: FutureWarning: fft=True will become the default in a future version of statsmodels. To suppress this warning, explicitly set fft=False.
  warnings.warn(msg, FutureWarning)
 

 
现在,让我们制作3种不同的ARIMA模型,考虑单独的和组合的效果。我还将为每个人打印RSS。请注意,这里的RSS用于残差值,而不是实际的系列

33
from statsmodels.tsa.arima_model import ARIMA

#可以使用ARIMA的order参数指定p、d、q值,该参数接受一个元组(p、d、q)。让我们对这3种情况建模:

#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))
 
/Users/christopher/opt/anaconda3/lib/python3.7/site-packages/statsmodels/tsa/base/tsa_model.py:165: ValueWarning: No frequency information was provided, so inferred frequency MS will be used.
  % freq, ValueWarning)
/Users/christopher/opt/anaconda3/lib/python3.7/site-packages/statsmodels/tsa/base/tsa_model.py:165: ValueWarning: No frequency information was provided, so inferred frequency MS will be used.
  % freq, ValueWarning)
33
Text(0.5, 1.0, 'RSS: 1.5023')
 

34
#MA Model

model = ARIMA(ts_log, order=(0, 1, 2))  
results_MA = model.fit(disp=-1)  
plt.plot(ts_log_diff)
plt.plot(results_MA.fittedvalues, color='red')
plt.title('RSS: %.4f'% sum((results_MA.fittedvalues-ts_log_diff)**2))
 
/Users/christopher/opt/anaconda3/lib/python3.7/site-packages/statsmodels/tsa/base/tsa_model.py:165: ValueWarning: No frequency information was provided, so inferred frequency MS will be used.
  % freq, ValueWarning)
/Users/christopher/opt/anaconda3/lib/python3.7/site-packages/statsmodels/tsa/base/tsa_model.py:165: ValueWarning: No frequency information was provided, so inferred frequency MS will be used.
  % freq, ValueWarning)
34
Text(0.5, 1.0, 'RSS: 1.4721')
 

35
#Combined Model

model = ARIMA(ts_log, order=(2, 1, 2))  
results_ARIMA = model.fit(disp=-1)  
plt.plot(ts_log_diff)
plt.plot(results_ARIMA.fittedvalues, color='red')
plt.title('RSS: %.4f'% sum((results_ARIMA.fittedvalues-ts_log_diff)**2))
 
/Users/christopher/opt/anaconda3/lib/python3.7/site-packages/statsmodels/tsa/base/tsa_model.py:165: ValueWarning: No frequency information was provided, so inferred frequency MS will be used.
  % freq, ValueWarning)
/Users/christopher/opt/anaconda3/lib/python3.7/site-packages/statsmodels/tsa/base/tsa_model.py:165: ValueWarning: No frequency information was provided, so inferred frequency MS will be used.
  % freq, ValueWarning)
35
Text(0.5, 1.0, 'RSS: 1.0292')
 

 
# 在这里,我们可以看到AR和MA模型拥有几乎相同的RSS,但是合并起来要好得多。现在,我们只剩下最后一步,即将这些值恢复到原来的比例。

36
#回到原来的比例

#由于组合模型给出了最佳结果,因此我们可以将其缩放回原始值并查看其在那里的表现。第一步是将预测结果存储为单独的系列并观察它。

predictions_ARIMA_diff = pd.Series(results_ARIMA.fittedvalues, copy=True)
print(predictions_ARIMA_diff.head())
 
Month
1949-02-01    0.009580
1949-03-01    0.017491
1949-04-01    0.027670
1949-05-01   -0.004521
1949-06-01   -0.023890
dtype: float64

 
Notice that these start from ‘1949-02-01’ and not the first month. Why? This is because we took a lag by 1 and first element doesn’t have anything before it to subtract from. The way to convert the differencing to log scale is to add these differences consecutively to the base number. An easy way to do it is to first determine the cumulative sum at index and then add it to the base number. The cumulative sum can be found as:

39
predictions_ARIMA_diff_cumsum = predictions_ARIMA_diff.cumsum()
print(predictions_ARIMA_diff_cumsum.head())
 
Month
1949-02-01    0.009580
1949-03-01    0.027071
1949-04-01    0.054742
1949-05-01    0.050221
1949-06-01    0.026331
dtype: float64

40
#您可以使用以前的输出快速进行一些回溯计算,以检查这些计算是否正确。接下来我们要把它们加到底数上。为此,让我们创建一个以所有值为基数的系列,并将差异添加到其中。可以这样做:

predictions_ARIMA_log = pd.Series(ts_log.ix[0], index=ts_log.index)
predictions_ARIMA_log = predictions_ARIMA_log.add(predictions_ARIMA_diff_cumsum,fill_value=0)
predictions_ARIMA_log.head()
 
/Users/christopher/opt/anaconda3/lib/python3.7/site-packages/ipykernel_launcher.py:3: FutureWarning: 
.ix is deprecated. Please use
.loc for label based indexing or
.iloc for positional indexing

See the documentation here:
http://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#ix-indexer-is-deprecated
  This is separate from the ipykernel package so we can avoid doing imports until
40
Month
1949-01-01    4.718499
1949-02-01    4.728079
1949-03-01    4.745570
1949-04-01    4.773241
1949-05-01    4.768720
dtype: float64

41
#这里第一个元素是基数本身,并且从那里累加的值。最后一步是取指数并与原始系列进行比较。

predictions_ARIMA = np.exp(predictions_ARIMA_log)
plt.plot(ts)
plt.plot(predictions_ARIMA)
plt.title('RMSE: %.4f'% np.sqrt(sum((predictions_ARIMA-ts)**2)/len(ts)))
41
Text(0.5, 1.0, 'RMSE: 90.1045')
 

 
posted @ 2020-02-01 16:57  星涅爱别离  阅读(2203)  评论(0编辑  收藏  举报