摘要:作者天瓊,數據游戲優勝隊伍成員介紹本文整理記錄了參與的一次小型數據分析競賽數據游戲,競賽目標是預測年月日股閉市時招商銀行的股價。日發現的數據有錯誤,需要手工矯正日該數據恢復正常。而函數,是對樣本外的數據進行預測。
作者:天瓊,「數據游戲」優勝隊伍成員
介紹本文整理記錄了參與的一次小型數據分析競賽「數據游戲」,競賽目標是預測2019年5月15日A股閉市時招商銀行600036的股價。
主要思路是利用ARIMA算法做時間序列預測。
使用的數據是公開的數據集 tushare。
拿到題目和數據之后,首先結合既往經歷,覺得想要預測準股價,本身是一個不可能的事情,尤其是A股。
影響股價的因素非常復雜而且不透明,以及金融投資領域具有的反身性理論,使得這次預測更多偏向于實驗性質,同時對競爭結果不要有過高的期望。
預測得準,是你的運氣;預測的爛,也不會影響你從中學到什么。學習第一,比賽第二吧。
鑒于以上,本次預測只使用了close的時間序列。更多的數據其實并沒有什么用。
首先了解下本文的 ARIMA 建模過程獲取時間序列數據 ;
觀察數據是否為平穩時間序列;
對于非平穩時間序列要先進行d階差分運算,轉化為平穩時間序列;
對處理得到的平穩時間序列,求它的階數p,q;
根據ARIMA算法建模,ARIMA(data, order=(p, d, q))
模型檢驗和調優
預測
初學的小伙伴們可能對這個過程并不熟悉,沒關系,先背下來。
對Python不熟悉的小伙伴們, 我給大家總結了幾句車轱轆話,大家先強行了解下。
獲取時間序列數據:
data = pd.read_excel(‘600036.xlsx’, index=None) train = data[‘close’]
觀察數據是否為平穩時間序列;對于非平穩時間序列要先進行d階差分運算,轉化為平穩時間序列;
adf_data = sts.adfuller(train) diff = train.diff(1)
對處理得到的平穩時間序列,求它的階數p, q
sm.tsa.arma_order_select_ic(train, max_ar=8, max_ma=8, ic=[‘aic’, ‘bic’, ‘hqic’])
根據ARIMA算法建模
ARMAModel = sm.tsa.ARIMA(train, order=(4,1,2)).fit()
模型檢驗和調優
train_shift = train.shift(1) pred_recover = predicts.add(train_shift) np.sqrt( sum( (pred_recover -train) ** 2)/train.size )
預測
f = ARMAModel.forecast(3)
以上,是本文的核心代碼,大家如果一時看不懂,可以跳過。
可以看看下面更詳細的步驟。
# 導入必須的模塊 import tushare as ts #使用的公開的數據 import numpy as np import pandas as pd import matplotlib.pyplot as plt import statsmodels.api as sm import statsmodels.tsa.stattools as sts import wconfig as wc #自定義打印輸出控制模塊,與本次競賽無關 wc.dispy() # 導入數據,從去年1月開始即可 data = ts.get_hist_data("600036", start="2018-01-08", end="2019-05-10").sort_index() #data = ts.get_hist_data("600036", start="2018-04-01").sort_index().reset_index() # 數據安全和源數據備份 #data.to_excel("600036.xlsx") # 源數據可靠性檢查。12日發現tushare的數據有錯誤,需要手工矯正(13日該數據恢復正常)。 print("tushare中5月10日close股價為: %.2f元,與實際不符!" % (data["close"]["2019-05-10"])) data["close"]["2019-05-10"]=33.61 print("當日實際收盤價應為: %.2f元" % data["close"]["2019-05-10"]) # 只取 close 字段作為訓練數據 train = data["close"] train.index = pd.to_datetime(train.index) # 將字符串索引轉換成時間索引 train.tail() train.tail().index
tushare中5月10日close股價為: 33.48元,與實際不符!檢驗時間序列的穩定性
當日實際收盤價應為: 33.61元
ARIMA算法要求時間序列穩定,所以在建模之前,要先檢驗時間序列的穩定性。
adfuller就是用來干這個的。
adfuller 全稱 Augmented Dickey–Fuller test, 即擴展迪基-福勒檢驗,用來測試平穩性。
def tagADF(t): result = pd.DataFrame(index=["Test Statistic Value", "p-value", "Lags Used", "Number of Observations Used", "Critical Value(1%)", "Critical Value(5%)", "Critical Value(10%)"], columns=["value"] ) result["value"]["Test Statistic Value"]=t[0] result["value"]["p-value"]=t[1] result["value"]["Lags Used"]=t[2] result["value"]["Number of Observations Used"] = t[3] result["value"]["Critical Value(1%)"]=t[4]["1%"] result["value"]["Critical Value(5%)"]=t[4]["5%"] result["value"]["Critical Value(10%)"]=t[4]["10%"] print("t is:", t) return result
adfuller檢驗是檢查時間序列平穩性的統計測試之一。 這里的零假設是:序列 train 是非平穩的。
測試結果包括測試統計和差異置信水平的一些關鍵值。 如果測試結果中的 P-value 小于臨界值,我們可以拒絕原假設并說該序列是平穩的。
adf_data = sts.adfuller(train) tagADF(adf_data)
檢驗結果顯示,p-value=0.414, 遠遠大于5%的臨界值,說明零假設是成立的,即序列 train 是非平穩的。
t is: (-1.7325346908056185, 0.4144323576685054, 0, 322, {‘1%’: -3.4508226600665037, ‘5%’: -2.870558121868621, ‘10%’: -2.571574731684734}, 523.9067372199033)時間序列平穩化
為了讓時間序列平穩,需要對 train 序列做差分運算:
# df.diff 差分運算,默認是后一行減前一行 # http://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.diff.html?highlight=diff#pandas.DataFrame.diff diff = train.diff(1).dropna() # df.dropna 刪除有缺失值的行 plt.figure(figsize=(11,6)) # 指定顯示大小 plt.plot(diff, label="Diff") # 繪制趨勢圖 plt.legend(loc=0) # 顯示圖例,loc指定圖例位置,0為最佳位置。
關于時間序列穩定性的判斷標準,可參考這篇博客:https://blog.csdn.net/u012735...
檢驗差分數據的平穩性檢驗差分后數據的平穩性,和第一次驗證方法相同
adf_Data1 = sts.adfuller(diff) tagADF(adf_Data1) # p-value很小,零假設不成立,因此,diff數據序列符合平穩性要求。確定ARIMA的階數p,q
在這里,先簡單解釋下自己對 ARIMA 算法的理解。不正確的地方請大家指點。
ARIMA算法認為時間序列上 t 時刻的值由2部分構成,第一部分是由之前p項歷史值決定的,比如15日的收盤價是12日,13日,14日的收盤價的線性回歸,用AR§表示。
但是這個線性回歸的輸出值肯定和15日的實際收盤價有一個誤差,假設是e。
所以第二部分就是如果表示這個 e 。
這個e 可以認為是之前q項誤差的線性回歸,用MA(q)表示。
兩部分合起來就是ARMA。
然后為了讓時間序列平穩,再加個d 階差分操作功能,就變成了ARIMA算法。
所以在使用 ARIMA 算法之前,需要先確定(p, d, q)的值。
確定ARIMA的階數p,q # ARMA(p,q)是AR(p)和MA(q)模型的組合,關于p和q的選擇,一種方法是觀察自相關圖ACF和偏相關圖PACF, # 另一種方法是通過借助AIC、BIC等統計量自動確定。 ic = sm.tsa.arma_order_select_ic( train, max_ar=8, max_ma=8, ic=["aic", "bic", "hqic"] ) ic建立模型并擬合數據
注意ARIMA的參數中,輸入數據 應該是原始數據 train,ARIMA 會根據 d 的值,對原始數據做 d 階差分運算。
d的含義是,輸入序列需要先經過一個d階的差分,變成一個平穩序列后才能進行數據擬合。
ARMAModel = sm.tsa.ARIMA(train, order=(4,1,2)).fit() # order=(p,d,q) # fittedvalues和diff對比 plt.figure(figsize=(11, 6)) plt.plot(diff, "r", label="Orig") plt.plot(ARMAModel.fittedvalues, "g",label="ARMA Model") plt.legend()模型評估和調優
# 樣本內預測 predicts = ARMAModel.predict() # 因為預測數據是根據差分值算的,所以要對它一階差分還原 train_shift = train.shift(1) # shift是指series往后平移1個時刻 pred_recover = predicts.add(train_shift).dropna() #這里add是指兩列相加,按index對齊 # 模型評價指標 1:計算 score delta = ARMAModel.fittedvalues - diff score = 1 - delta.var()/train.var() print("score: ", score) # 模型評價指標 2:使用均方根誤差(RMSE)來評估模型樣本內擬合的好壞。 #利用該準則進行判別時,需要剔除“非預測”數據的影響。 train_vs = train[pred_recover.index] # 過濾沒有預測的記錄 plt.figure(figsize=(11, 6)) train_vs.plot(label="Original") pred_recover.plot(label="Predict") plt.legend(loc="best") plt.title("RMSE: %.4f"% np.sqrt(sum((pred_recover-train_vs)**2)/train_vs.size)) plt.show()
# 局部數據觀察 train_t = train_vs.tail(15) pred_t = pred_recover.tail(15) plt.figure(figsize=(11, 6)) train_t.plot(label="Original") pred_t.plot(label="Predict") plt.legend(loc="best") plt.title("RMSE: %.4f"% np.sqrt(sum((pred_t-train_t)**2)/train_t.size)) plt.show()預測目標
使用 forecast 對樣本外的時間序列進行預測。
關于foreast和predict的區別:
predict 可以對樣本內和樣本外的進行預測,結果是一樣的。
舉例說明:forecast(10),表示對未來10個點進行預測,但是可以用model.fittedvalues查看樣本內點的擬合值;
而predict(start,end)里面的參數0表示樣本內的第一個數,以此類推。
如果想要預測樣本外的數,需要將start設置為len(data)+1,即數據長度+1,才表示預測樣本外的第一個數字。
而 forecast函數,是對樣本外的數據進行預測。
但是這兩個函數的預測結果是一樣的。
另外,需要提到的是,ARIMA算法一般只能預測一點點,越長越不準確,即便是簡單的正弦函數也不能準確預測。
# 預測15日close股價,即10日之后的第三個交易日的收盤價 # 但是通過上面的局部數據觀察發現,預測的數據趨勢會延遲1個交易日,所以就取f[0][1] f = ARMAModel.forecast(3) # 樣本外預測 print("5月15日close時的股價為:%.2f 元" % f[0][1]) #----結束-----
5月15日close時的股價為:33.82 元。
順便安利下這次參與的小競賽「數據游戲」,是由個人發起、異步社區(郵電出版社)贊助的活動。
總體來說,這個比賽氛圍適中,沒有太大的心理負擔。
所以感覺比較適合打算初入的小伙伴,參與之后,這樣的經驗對以后的學習進階和職業發展都有好處。
Ad Time學習更多數據科學知識請關注微信公眾號:read_csv
參與數據科學活動請加 QQ 群:759677734
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/20039.html
摘要:作者天瓊,數據游戲優勝隊伍成員介紹本文整理記錄了參與的一次小型數據分析競賽數據游戲,競賽目標是預測年月日股閉市時招商銀行的股價。日發現的數據有錯誤,需要手工矯正日該數據恢復正常。而函數,是對樣本外的數據進行預測。 作者:天瓊,「數據游戲」優勝隊伍成員 介紹 本文整理記錄了參與的一次小型數據分析競賽「數據游戲」,競賽目標是預測2019年5月15日A股閉市時招商銀行600036的股價。 主...
摘要:本次比賽將使用模型來預測招商銀行三天后的收盤價,也就是利用月日前的數據,來預測月日的收盤價。按照個交易日的模式,將數據變成一個,,的張量表。在實際使用時進行模型載入,分別查看預測結果。 作者:瘋貓子,「數據游戲」優勝隊伍成員 摘要 LSTM模型是RNN的一種,其特點是在單一循環神經網絡的基礎上,構建出了長短記憶門,也就是可以長時間發現和記憶長依賴關系。本次比賽將使用LSTM模型來預測招...
閱讀 2043·2021-09-07 10:14
閱讀 1477·2019-08-30 15:53
閱讀 2269·2019-08-30 12:43
閱讀 2860·2019-08-29 16:37
閱讀 753·2019-08-26 13:29
閱讀 1999·2019-08-26 13:28
閱讀 437·2019-08-23 18:33
閱讀 3500·2019-08-23 16:09