数据准备
数据集(JetRail高铁的乘客数量)下载.
假设要解决一个时序问题:根据过往两年的数据(2012 年 8 月至 2014 年 8月),需要用这些数据预测接下来 7 个月的乘客数量。
import //代码效果参考:http://www.zidongmutanji.com/bxxx/173258.html
pandas as pdimport numpy as np
import matplotlib.pyplot as plt
df = pd.read_csv('train.csv')
df.head()
df.shape
依照上面的代码,我们获得了 2012-2014 年两年每个小时的乘客数量。为了解释每种方法的不同之处,以每天为单位构造和聚合了一个数据集。
从 2012 年 8 月- 2013 年 12 月的数据中构造一个数据集。
创建 train and test 文件用于建模。前 14 个月( 2012 年 8 月- 2013 年 10 月)用作训练数据,后两个月(2013 年 11 月 – 2013 年 12 月)用作测试数据。
以每天为单位聚合数据集。
import pandas as pd
import matplotlib.pyplot as plt
# Subsetting the dataset
# Index 11856 marks the end of year 2013
df = pd.read_csv('train.csv', nrows=11856)
# Creating train and test set
# Index 10392 marks the end of October 2013
train = df【0:10392】
test = df【10392:】
# Aggregating the dataset at daily level
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()
#Plotting data
train.Count.plot(figsize=(15,8), title= 'Daily Ridership', fontsize=14)
test.Count.plot(figsize=(15,8), title= 'Daily Ridership', fontsize=14)
plt.show()
我们将数据可视化(训练数据和测试数据一起),从而得知在一段时间内数据是如何变化的。
方法1:朴素法
假设 y 轴表示物品的价格,x 轴表示时间(天)
如果数据集在一段时间内都很稳定,我们想预测第二天的价格,可以取前面一天的价格,预测第二天的值。这种假设第一个预测点和上一个观察点相等的预测方法就叫朴素法。即 ^yt+1=ytyt+1^=yt\hat{y_{t+1}} = y_t
dd = np.asarray(train【'Count'】)
y_hat = test.copy()
y_hat【'naive'】 = dd【len(dd) - 1】
plt.figure(figsize=(12, 8))
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.show()
朴素法并不适合变化很大的数据集,最适合稳定性很高的数据集。我们计算下均方根误差,检查模型在测试数据集上的准确率:
from sklearn.metrics import mean_squared_error
from math import sqrt
rms = sqrt(mean_squared_error(test【'Count'】, y_hat【'naive'】))
print(rms)
最终均方误差RMS为:43.91640614391676
方法2:简单平均法
物品价格会随机上涨和下跌,平均价格会保持一致。我们经常会遇到一些数据集,虽然在一定时期内出现小幅变动,但每个时间段的平均值确实保持不变。这种情况下,我们可以预测出第二天的价格大致和过去天数的价格平均值一致。这种将预期值等同于之前所有观测点的平均值的预测方法就叫简单平均法。即^yx+1=1xx∑i=1yiy^x+1=1x∑i=1xyi\displaystyle \hat{y}{x+1} = \frac{1}{x} \sum{i=1}^xy_i
y_hat_avg = test.copy()
y_hat_avg【'avg_forecast'】 = train【'Count'】.mean()
plt.figure(figsize=(12,8))
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.show()
方法3:移动平均法
物品价格在一段时间内大幅上涨,但后来又趋于平稳。我们也经常会遇到这种数据集,比如价格或销售额某段时间大幅上升或下降。如果我们这时用之前的简单平均法,就得使用所有先前数据的平均值,但在这里使用之前的所有数据是说不通的,因为用开始阶段的价格值会大幅影响接下来日期的预测值。因此,我们只取最近几个时期的价格平均值。很明显这里的逻辑是只有最近的值最要紧。这种用某些窗口期计算平均值的预测方法就叫移动平均法。
计算移动平均值涉及到一个有时被称为“滑动窗口”的大小值p。使用简单的移动平均模型,我们可以根据之前数值的固定有限数p的平均值预测某个时序中的下一个值。这样,对于所有的 i p:
^yl=1p(yi?1+<span id="MJXc-