一、相关概念
1、ARIMA模型是一种流行且广泛使用的时间序列预测统计方法。ARIMA是AutoRegressive Integrated Moving Average的缩写。它是一类模型,它捕获时间序列数据中的一套不同的标准时间结构。
AR:自回归。一种模型,它使用观察与一些滞后观察之间的依赖关系。使用原始观察的差分(例如,从前一时间步骤的观察中减去观察值)以使时间序列静止。
MA:移动平均线。使用应用于滞后观察的移动平均模型中的观察和残差之间的依赖关系的模型。
ARIMA模型的参数定义如下:
p:模型中包含的滞后观察数,也称为滞后顺序。 d:原始观测值的差异次数,也称为差分程度。 q:移动平均窗口的大小,也称为移动平均值的顺序。
二、建模流程
1、读取数据
df = pd.read_csv('data/train.csv', encoding='utf-8',header=None,names=['timestamp','value','label'])
2、数据观察
data = df[‘value’]
plt.figure(figsize = (10, 6))
plt.plot(df.index, data)
plt.show()
3、数据平稳性检测、数据平稳
data_diff = data.diff()
data_diff = data_diff.dropna()
plt.plot(data_diff)
plt.show()
平稳性检测ADF。(Test Statistic、p-value、Number of Observations Used、Critical Value (1%)、Critical Value (5%)、Critical Value (10%))如果p_value比0.05小,表明序列平稳;比0.05大,表明非平稳;如果接近0.05,根据t和临界值判断,比临界值小表明稳定,反之,非稳定。
from statsmodels.tsa.stattools import adfuller
adfuller(data_diff)
4、画ACF、PACF,确定p,q值
p的值就是ACF第一次穿过上置信区间时的横轴值。q的值就是PACF第一次穿过上置信区间的横轴值。
lag_acf = acf(ts_diff_1,nlags=50)
lag_pacf = pacf(ts_diff_1,nlags=50)
plt.plot(lag_acf)
plt.show()
plt.plot(lag_pacf)
plt.axhline(y=-1.96/np.sqrt(len(ts_diff_1)),linestyle='--',color='gray')
plt.axhline(y=1.96/np.sqrt(len(ts_diff_1)),linestyle='--',color='gray')
plt.show()
5、 模型训练
def train_model(train_value,order,interval,bias,save_model_path,save_bias_path):
# 差分数据
diff = difference(train_value, interval)
# 拟合模型
model = ARIMA(diff, order=order) # order为元组(p,d,q)
model_fit = model.fit(trend='nc', disp=0)
# 保存模型
model_fit.save(save_model_path) # model.pkl
np.save(save_bias_path, [bias]) # model_bias.npy
print('模型model保存成功!')
print('残差偏执bias保存成功!')
6、模型测试
# 模型在训练集上验证
def test_model(train_value,test_value,order,interval,model_path,bias_path):
model,bias=load_model(model_path,bias_path)
predictions = list()
history = [x for x in train_value]
yhat = float(model.forecast()[0])
yhat = bias + inverse_difference(history, yhat, interval)
predictions.append(yhat)
history.append(test_value[0])
print('>Predicted=%.3f, Expected=%3.f' % (yhat, test_value[0]))
# rolling forecasts
result = [[test_value[0],yhat[0]]]
for i in range(1, len(test_value)):
# difference data
diff = difference(history, interval)
# predict
model = ARIMA(diff, order=order)
model_fit = model.fit(trend='nc', disp=0)
yhat = model_fit.forecast()[0]
yhat = bias + inverse_difference(history, yhat, interval)
predictions.append(yhat)
# observation
obs = test_value[i]
history.append(obs)
print('>Predicted=%.3f, Expected=%3.f' % (yhat, obs))
# print(yhat[0],type(yhat))
result.append([obs,yhat[0]])
# report performance
mse = mean_squared_error(test_value, predictions)
rmse = sqrt(mse)
df_res = pd.DataFrame(data=result)
df_res.to_csv('prediction.csv',index=False,header=None)
plt.figure(facecolor='white', figsize=(20, 6))
plt.plot(predictions, lw=0.5, color='blue', label='Predict')
plt.plot(test_value, lw=0.5, color='red', label='Original')
plt.legend(loc='best')
plt.title('RMSE: %.4f' % rmse)
plt.show()
# 单值预测
def predict(model_path,bias_path,data,interval):
model, bias = load_model(model_path, bias_path)
yhat = float(model.forecast()[0])
yhat = bias + inverse_difference(data['value'],yhat,interval)
return yhat