摘要:本次比賽將使用模型來預測招商銀行三天后的收盤價,也就是利用月日前的數據,來預測月日的收盤價。按照個交易日的模式,將數據變成一個,,的張量表。在實際使用時進行模型載入,分別查看預測結果。
作者:瘋貓子,「數據游戲」優勝隊伍成員
摘要LSTM模型是RNN的一種,其特點是在單一循環神經網絡的基礎上,構建出了長短記憶門,也就是可以長時間發現和記憶長依賴關系。本次比賽將使用LSTM模型來預測招商銀行三天后的收盤價,也就是利用5月10日前的數據,來預測5月15日的收盤價。
一、模型選擇股價價格的預測其實是一件極其不靠譜的事情。很多專業機構和量化交易的個人都是極力在規避價格預測這種做法的。
原因有二:一是股市(無論哪個國家,哪種性質)隨機突發事件太多,且突發事件對股市的影響力也是高度隨機和不可預測的,也就是所謂的噪音多到讓你懷疑人生。二是,連續變量作為預測目標是個糟糕的設計,因為這會使得預測空間太大,而導致所搜空間無限大。這個見解來自于強化學習,強化學習的一個技術要點就是把預測空間有限化,即便客觀世界是連續而無限的,也需要采用類似于Tile coding的技術使其離散化,有限化。本著迎難而上,不成功也可以提高自己的初衷,嘗試開始著手解決這一難題。
選擇LSTM模型作為主算法來采用,是參考了kaggle上一個長期項目,預測美股收盤價的一個項目,其中第三名就是采用LSTM的。拿來測試之后,具有一定預測作用,但是預測精度不高,且性能不穩定。然后小組討論后,是否就采用這個基本模型為核心,開展算法升級,得到一致同意后,于是確定了LSTM算法為核心算法,并做再次開發。
二、模型升級LSTM模型之所有能夠具有預測股價的能力,主要的還是模型本身捕捉了價格序列中的時序要素中所透射出來的信息。對于模型進行預測本身是完全沒有問題的,而這次模型升級的根本目標是提升預測精度。
關于模型升級主要來自于兩方面的,一是通過對模型的優化,二是優化數據。
(一)升級LSTMLSTM模型大概有6種變形形式,主要的特點就是針對不同數據輸入的類型。這里我選用了Multiple Input模型,也就是多序列輸入,單序列輸出。選擇這個模型,對數據的構建也有非常好的促進作用,可以構建一個張量(多維數組),這個張量是一個5維張量,每個維度是一個特征數據,同時還可以按照N天的方式形成數據切片,這種設計基于兩個原因:
一是數據中包含了大量信息,而越多的特征數據,提供的信息越多,多因子的雛形。
二是在保持多特征數據的基礎上,保留的時間序列的特點。也就是在不增加特征的情況,將特征信息成倍增加。
這種數據處理模式極大的優于ML的諸多算法。ML的諸多算法還是以單一樣本為切片輸入所有維度的數據,在時序構建方面是有所欠缺的。
(二)升級數據集數據是從大智慧中取出的數據,數據時間段是2010年1月1日—2019年5月10日,數據包含open(開盤價)、close(收盤價)、volume(成交量)、turnover(成交額度)、return(日收益率)。特征選擇了5個,原因是增加特征必然增加數據的獲取難度,多因子模型的構建是基于豐富的數據供應基礎上,在目前的這個比賽中,是不具備這個條件,所以只用4個基本特征數據加一個收益率的衍生變量。
按照N個交易日的模式,將數據變成一個(M,N,5)的張量表。
三、代碼解析# 引入各種工具包 import pandas as pd import numpy as np np.set_printoptions(threshold=np.inf) #設置np數據在打印時能夠完整輸出,方便觀察 from keras.models import Sequential from keras.layers import LSTM,Dense import keras import matplotlib.pyplot as plt # 全局參數,所有要調整的參數都在這里 dim=300 #輸出維度數,也是LSTM的網絡節點數 epochs=400 #訓練代數(可以理解為訓練次數) days=20 #讀取多少天的數據作為一次預測。例如讀取20天的歷史數據來預測未來1天的情況 batch_size = 535 #訓練批次大小,就是一次性讀取多少個樣本進行一次運算,越大運算速度越快,但是占用內存和顯存越大,根據自己的機器性能設置。同時該參數還決定梯度下降算法的下降步長數。 開始構建網絡, n_steps = days #輸入張量的維度數 n_features = 5 #輸入張量的維度 model_2 = Sequential() # 激活函數用relu model_2.add(LSTM(dim, activation="relu",input_shape=(n_steps, n_features))) # 輸出層使用全連接層,只要一個輸出節點 model_2.add(Dense(1)) #選擇優化器和損失函數,優化器為線性規劃算法,損失函數用的是高維空間測定距離的函數 model_2.compile(optimizer="rmsprop", loss="mse")
接下來開始構建數據,主要分為三個步驟完成
第一步導入數據
第二步生成數據切片,以及監督學習的標簽,也就是三天后的收盤價。拆分訓練序列訓練集、測試集、標簽
第三步載入模型進行訓練
數據導入的基本操作,順便觀察下數據集的情況。
data = pd.read_csv("600036.csv") data.head() data.info()RangeIndex: 2250 entries, 0 to 2249 Data columns (total 5 columns): open 2250 non-null float64 close 2250 non-null float64 volume 2250 non-null int64 turnover 2250 non-null int64 return 2250 non-null float64 dtypes: float64(3), int64(2) memory usage: 88.0 KB
構建兩個處理數據生成張量表的函數,一個用帶標簽輸出,另外一個只處理輸入數據集,生成20x5的切片數據。
def processData(data,lb): X,Y = [],[] for i in range(len(data)-lb-1): X.append(data[i:(i+lb),0]) try: Y.append(data[(i+2+lb),0]) except: Y.append(data[(i+lb),0]) return np.array(X),np.array(Y) def pData(data,lb): X,Y = [],[] for i in range(len(data)-lb-1): X.append(data[i:(i+lb)]) return np.array(X)
開始處理數據,同時對數據進行特征縮放處理,因為后面需要對特征縮放的數據進行逆運算,所以,要定義兩個不同的特征縮放函數,否則后面針對輸出標簽逆運算會無法進行。
對數據進行特征縮放處理,將數據縮放到0-1區間內,這樣可以加快訓練結果的快速收斂。
from sklearn.preprocessing import MinMaxScaler close = data["close"] cl = np.array(close) cl = cl.reshape(cl.shape[0],1) scl = MinMaxScaler() sc2 = MinMaxScaler() cl = scl.fit_transform(cl) # 生成標簽 _,y = processData(cl,days) X = data.values X = sc2.fit_transform(X) X = pData(X,days)
對數據集進行訓練集和測試集的拆分,我在這里偷了個懶,只生成了兩組數據集。
y_train,y_test = y[:int(y.shape[0]*0.80)],y[int(y.shape[0]*0.80):] X_train,X_test = X[:int(X.shape[0]*0.80)],X[int(X.shape[0]*0.80):]
拆分出來的數據是這個樣子的
y_train的數據結構為: (1783,)
y_test的數據結構為: (446,)
X_train的數據結構為: (1783, 20, 5) # 1783個20x5的數據切片
X_test的數據結構為: (446, 20, 5) # 446個20x5的數據切片
張量表的結構為:(一個切片)
#執行模型訓練 History = model_2.fit( X_train,y_train,batch_size=batch_size, epochs=epochs,validation_data=(X_test,y_test),shuffle=False) # 顯示訓練過程 plt.plot(history.history["loss"]) plt.plot(history.history["val_loss"])
模型訓練過程中的loss值,一個真實值的loss,一個是預測值的loss,可以明顯的看到,兩個loss已經快速收斂,但是預測值的loss并不穩定。在這種情況下,如果模型使用精確度來進行評估,明顯已經不符合實際要求。故需要重新找到模型性能評估的方法。
模型訓練完畢之后,需要對訓練模型進行效果評估,大概的評估思路分為三步:
第一步單值預測檢驗
第二步序列預測檢驗
第三步用統計檢驗方法中的T檢驗對預測性能進行評估
#隨機從測試集中抽取一個單一數據切片進行預測 act = [] pred = [] import random i=random.randint(0,250) Xt = model_2.predict(X_test[i].reshape(1,days,5)) print("預測值:{0}, 實際值:{1}".format(Xt,y_test[i].reshape(-1,1))) pred.append(Xt) act.append(y_test[i])
預測值:[[0.7393236]], 實際值:[[0.74340618]]
# 將測試集中的所有切片以序列的方式進行預測,查看預測結果與真實值的擬合情況。 Xt = model_2.predict(X_test) fig = plt.gcf() plt.plot(y_test.reshape(-1,1),label="y_test") plt.plot(Xt,label="Forecast") plt.legend() # T檢驗中的差值統計,查看差值序列在統計挺行上的綜合表現 a = y_test.reshape(-1,1) b = Xt c = a - b #實際值減去預測值 c = pd.DataFrame(c) c.describe()
統計指標說明:
mean:代表測試集驗證后的結果與真實情況的差值序列的平均值,也就是整體差異水平。正負無所謂,越趨近0越好。通過上述的結果來看,這次訓練的模型預測結果于真實情況的整體誤差已經小于1%,
std:標準差,代表均值在正負兩個方向的分散程度,越小越好,說明結果比較集中,誤差比較小,通過以上結果來看分散度僅有4.33%,在95%的置信度下。
模型保存因為在訓練模型時,確保能夠產生最大的隨機數,并未設置隨機數種子。如果遇到性能較好的結果就運行下面的代碼,以便將模型保存在本地。方便評估模型訓練的最優參數。
path="my_model_2" # 請自行設置存儲路徑及文件名,例如:D:股票my_model model_2.save(path+".h5",include_optimizer=True) # 保存模型本體 model_2.save_weights(path + "_weights.h5") # 保存模型權重模型載入執行預測
說明:
由于神經網絡依靠隨機數,未設置隨機數種子,所以每次訓練結果均不相同。所以將性能較好的模型進行存儲。
在實際使用時進行模型載入,分別查看預測結果。取最佳模型。
載入數據預測5月15日的close數值
filepath = "my_model_1" my_model = keras.models.load_model(filepath+".h5") p_1 = my_model.predict(X_test) p_1 = scl.inverse_transform(p_1) print("5月15日的close為:",p_1[-1])
5月15日的close為: [33.819942]
總結該模型最優參數組合,是通過幾十次的反復訓練所的得到的。在這個過程中還做了大量的調整和比對試驗,就不做贅述,只將總結到的要點進行歸納闡述:
因為構建的張量維度數并不是十分大,所以在網絡的設計上,一個LSTM層加一個全連接層就已經足夠了。如果我們的維度數可以增加到上百個,這個情況就可以繼續增加隱藏層的數量,同時使用dropout層,丟棄部分冗余。
對于LSTM模型,在做預測的時候,不能只給一個切片(單值)數據,這個預測的結果很大概率會產生偏差。正確的做法,應該是給一個切片序列,而你要預測的內容必須放置到最后一個。因為實驗發現,LSTM模型的運行原理中,會根據上下連接的數據切片修正自己的長短記憶內容,也就是具備一定的推理能力,在使用這個模型時,需要給與足夠的數據,讓模型能夠進行推理。
Y值(標簽)的構建同樣需要和X值(輸入)的設計進行關聯,因為這關系到你的訓練數據是離散化,還是序列化,也關系到你的訓練方式是可以離散化,還是序列化(時序化)。非常重要。這也是針對預測目標反推需要選擇哪些數據組成數組的宗旨。
Ad Time了解更多「數據游戲」可以關注微信公眾號數據科學與技術(read_csv) 或加入 QQ 群 759677734
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/43823.html
摘要:本次比賽將使用模型來預測招商銀行三天后的收盤價,也就是利用月日前的數據,來預測月日的收盤價。按照個交易日的模式,將數據變成一個,,的張量表。在實際使用時進行模型載入,分別查看預測結果。 作者:瘋貓子,「數據游戲」優勝隊伍成員 摘要 LSTM模型是RNN的一種,其特點是在單一循環神經網絡的基礎上,構建出了長短記憶門,也就是可以長時間發現和記憶長依賴關系。本次比賽將使用LSTM模型來預測招...
摘要:作者,數據游戲優勝隊伍成員前陣子報名參加了數據游戲比賽,題目是預測月號星期三招商銀行的股價,截止時間是在月號星期天。 作者:Max,「數據游戲」優勝隊伍成員 前陣子報名參加了「數據游戲」比賽,題目是預測5月15號(星期三)招商銀行的股價,截止時間是在5月12號(星期天)。在本次預測中,我用到的是嶺回歸。 嶺回歸 嶺回歸是回歸的一種,它解決回歸中重大疑難問題:排除多重共線性,進行變量的選...
閱讀 964·2023-04-26 02:56
閱讀 9437·2021-11-23 09:51
閱讀 1850·2021-09-26 10:14
閱讀 2980·2019-08-29 13:09
閱讀 2154·2019-08-26 13:29
閱讀 571·2019-08-26 12:02
閱讀 3562·2019-08-26 10:42
閱讀 3000·2019-08-23 18:18