第一篇文章傳送門: Python爬取中國銀行外匯牌價(爬蟲 + PyFlux簡單預測分析)--(一)html
若是數據還沒獲取到的話請移步看第一篇文章(本篇文章默認數據已存儲在數據庫中)git
df['查詢時間'] = df['查詢時間'].apply(lambda x: x[:-9])
df['查詢時間'] = pd.to_datetime(df['查詢時間'], format="%Y-%m-%d")
df = df.groupby('查詢時間')['現匯賣出價'].mean()
df = df.to_frame()
print(df)
複製代碼
# 差分圖
fig = plt.figure(figsize=(12, 8))
ax1 = fig.add_subplot(111)
# 裏面的1表明了差分階數
diff1 = df.diff(1)
diff1.plot(ax=ax1)
plt.show()
# fig.savefig('./picture/1.jpg')
複製代碼
介紹一些自相關性和非自相關性:github
接下來選擇40個滯後作自相關和偏自相關的分析數據庫
# statmodels 自相關圖 偏相關圖
diff1 = diff1.dropna()
fig = plt.figure(figsize=(12, 8))
ax1 = fig.add_subplot(211)
fig = sm.graphics.tsa.plot_acf(diff1, lags=40, ax=ax1)
ax2 = fig.add_subplot(212)
fig = sm.graphics.tsa.plot_pacf(diff1, lags=40, ax=ax2)
fig.show()
# fig.savefig('./picture/acf_pacf.jpg')
複製代碼
接下來由看圖觀察定義ARMA模型的p(自相關係數), q(偏自相關係數)參數:app
能夠嘗試以下p, q參數的模型, 並輸出AIC,BIC,HQIC的結果機器學習
嘗試結果以下:post
模型選擇:學習
arma_mod22 = sm.tsa.ARMA(diff1, (3, 2)).fit()
# 輸出AIC,BIC和HQ準則結果
print(arma_mod22.aic, arma_mod22.bic, arma_mod22.hqic)
複製代碼
# 殘差(輸出形式爲DataFrame)
resid = arma_mod22.resid
# 殘差的ACF和PACF圖
fig = plt.figure(figsize=(12, 8))
ax1 = fig.add_subplot(211)
fig = sm.graphics.tsa.plot_acf(resid.values.squeeze(), lags=40, ax=ax1)
ax2 = fig.add_subplot(212)
fig = sm.graphics.tsa.plot_pacf(resid, lags=40, ax=ax2)
fig.show()
# fig.savefig('./picture/resid_acf_pacf.jpg')
複製代碼
# 殘差D-W檢驗
resid_dw_result = sm.stats.durbin_watson(arma_mod22.resid.values)
# 1.9933441709003574 接近於 2 因此殘差序列不存在自相關性。
print(resid_dw_result)
複製代碼
# 正態校驗 -> 基本符合正態分佈
fig = plt.figure(figsize=(12, 8))
ax = fig.add_subplot(111)
fig = sm.qqplot(resid, line='q', ax=ax, fit=True)
fig.show()
# fig.savefig('./picture/normal_distribution.jpg')
複製代碼
# 殘差序列Ljung-Box檢驗,也叫Q檢驗
r, q, p = sm.tsa.acf(resid.values.squeeze(), qstat=True)
data = np.c_[range(1, 41), r[1:], q, p]
table = pd.DataFrame(data, columns=['lag', "AC", "Q", "Prob(>Q)"])
temp_df = table.set_index('lag')
print(temp_df)
# Prob(>Q)的最小值: 0.025734615668093132, 最大值: 0.9874705305611844, 均值: 0.2782013984159408
prob_q_min = temp_df['Prob(>Q)'].min()
prob_q_max = temp_df['Prob(>Q)'].max()
prob_q_mean = temp_df['Prob(>Q)'].mean()
print("Prob(>Q)的最小值: {}, 最大值: {}, 均值: {}".format(prob_q_min, prob_q_max, prob_q_mean))
複製代碼
、
# 預測
predict_data = arma_mod22.predict('2018-11-09', '2018-11-14', dynamic=True)
# 畫預測圖
fig, ax = plt.subplots(figsize=(12, 8))
ax = diff1.ix['2018-01-01':].plot(ax=ax)
fig = arma_mod22.plot_predict('2018-11-09', '2018-11-14', dynamic=True, ax=ax, plot_insample=False)
fig.show()
# 結果預測
last_data = df['現匯賣出價'].values[-1]
# 還原結果
predict_data_list = predict_data.values.tolist()
restore_list = []
for d in predict_data_list:
last_data = last_data + d
restore_list.append(last_data)
predict_data = pd.DataFrame(restore_list, index=predict_data.index, columns=['現匯賣出價'])
print(predict_data)
複製代碼