今天來介紹一下如何使用時序ARIMA模型,預測未來一定情況的波動變化。以股票價格波動為例,我們選取某支股票每日的收盤價。
先來介紹下什麼是ARIMA。ARIMA(AutoregRessive Integrated Moving Average),自回歸差分移動平均模型,通過采用過去的觀測結果,并考慮差分、自回歸和移動平均分量來分離信号和噪聲。
ARIMA,自回歸差分移動平均模型,通過采用過去的觀測結果,并考慮差分、自回歸和移動平均分量來分離信号和噪聲。
自回歸模型AR
自回歸模型描述目前值與曆史值之間的關系,用變量自身的曆史時間資料對自身進行預測。自回歸模型必須滿足平穩性(平穩性要求序列的均值和方差不發生明顯變化)的要求。自回歸模型首先需要确定一個階數p,表示用幾期的曆史值來預測目前值。p階自回歸模型的公式定義為:
移動平均模型MA
差分法
使用差分法可以使得資料更平穩,常用的方法就是一階差分法和二階差分法。
将自回歸模型、移動平均模型和差分法結合,我們就得到了差分自回歸移動平均模型ARIMA(p,d,q),其中:
p是自回歸(AR)的項數,用來擷取自變量,之前的p個數值當作自變量
d是差分(I)的系數,差分的意思就是後一行減前一行。d=1的意思,做一次差分。目的是為了使時間序列平穩
q是移動平均(MA)的項數,意思每一行被自身和自身之前的q-1行的平均數取代,為了使其光滑
注意:如果d=0時,ARIMA退化成ARMA模型
1. 使用akshare第三方庫,擷取股票資訊
import akshare as ak
import talib
import numpy as np
import pandas as pd
import matplotlib.pylab as plt
import seaborn as sns
from statsmodels.tsa.arima_model import ARIMA,ARMA
from statsmodels.graphics.tsaplots import plot_acf, plot_pacf
from sklearn.metrics import mean_squared_error
from math import sqrt
from matplotlib.pyplot import MultipleLocator
import warnings
import matplotlib.ticker as ticker
#from matplotlib import pyplot
warnings.filterwarnings("ignore")
"""
date:交易日期
open:代表開盤價
high:當天最高價
low:當天最低價
close:當天收盤價
volume:當天成交量(元)
outstanding_share:流動股本(股)
turnover:換手率
"""
def get_codeData(code="sz002241"):
df = ak.stock_zh_a_daily(symbol=code, start_date="20100101", end_date="20210314", adjust="qfq")
return df
df = get_codeData(code="sz000789")
2. 利用股票的每日收盤價,作為我們的時序資料。由于原始資料太多,按照每一周來采樣,更好預測,并取每一周的均值。
這裡"W-MON"是從上周二統計到這周一,并打上這周一的标簽。例如:
日 一 二 三 四 五 六
10 11 12 13 14 15 16
17 18 19 20 21 22 23
如果使用resample函數和參數"W_MON",那麼:
date, quantity
2016-7-18, 354
意味着7-12、7-13、7-14、7-15、7-16、7-17、7-18這7天的資料結合在一起,成為7月18日周一這個時間戳的資料。
而如果使用resample函數和參數"W_SUN",那麼:
date, quantity
2016-7-17, 301
意味着7-11、7-12、7-13、7-14、7-15、7-16、7-17這7天的資料結合在一起,成為7月18日周一這個時間戳的資料。
lit = ['close']
df = df[lit]
plt.plot(df['close'])
plt.title('股市每日收盤價')
plt.show()
df_w = df['close'].resample('W-MON').mean()
df_train_test = df_w['2015':'2021']
3. 劃分訓練集和測試集後,使用訓練集來訓練模型,對測試集中的資料進行測試。這裡采用的是one-step的預測,即:每一次隻預測下一天的情況,然後将這一天的真實資料加入history中,再同樣預測下一天,最後使用MRSE來評估模型的性能
size = int(len(df_train_test) * 0.9)
train, test = df_train_test[0:size], df_train_test[size:len(df_train_test)]
print(len(train), len(test))
history = [x for x in train]
predictions = list()
# walk-forward validation
for t in range(len(test)):
model = ARIMA(history, order=(1,1,1), missing='drop')
model_fit = model.fit()
output = model_fit.forecast()[0]
predictions.append(output)
history.append(test[t])
print('predicted=%f, expected=%f' % (output, test[t]))
rmse = sqrt(mean_squared_error(test, predictions))
print('Test RMSE: %.3f' % rmse)
fig, ax = plt.subplots(1,1)
plt.plot(test.values, color='blue', label='Origin')
plt.plot(predictions, color='red', label='Predcition RMSE:%.3f' % rmse)
plt.title('sz000789 Price Prediction')
plt.xlabel('Time(Weeks)')
plt.ylabel('Price')
ax.xaxis.set_major_locator(ticker.MultipleLocator(base=100))
plt.xticks(range(len(test)), test.index, rotation=90)
plt.legend()
plt.show()
結果如下所示:模型性能RMSE 0.639
本文簡要介紹了如何使用ARIMA模型進行預測的流程,其中對于如何標明模型參數p,d,q部分本文先暫且不表,之後會用另外的文章做詳細介紹。
如果這篇文章對于你有幫助,歡迎點贊、評論和轉發,是對我最大的支援!
參考資料:
1. https://blog.csdn.net/u010770993/article/details/70312504
2. http://sofasofa.io/forum_main_post.php?postid=1000324