利用 LSTM 神经网络预测股价走势
LSTM 神經(jīng)網(wǎng)絡(luò)
長(zhǎng)短期記憶 (LSTM) 神經(jīng)網(wǎng)絡(luò)屬于循環(huán)神經(jīng)網(wǎng)絡(luò)?(RNN) 的一種,特別適合處理和預(yù)測(cè)與時(shí)間序列相關(guān)的重要事件。以下面的句子作為一個(gè)上下文推測(cè)的例子:
“我從小在法國(guó)長(zhǎng)大,我會(huì)說(shuō)一口流利的??”由于同一句話(huà)前面提到”法國(guó)“這個(gè)國(guó)家,且后面提到“說(shuō)”這個(gè)動(dòng)作。因此,LSTM便能從”法國(guó)“以及”說(shuō)“這兩個(gè)長(zhǎng)短期記憶中重要的訊號(hào)推測(cè)出可能性較大的”法語(yǔ)“這個(gè)結(jié)果。
K線(xiàn)圖與此類(lèi)似,股價(jià)是隨著時(shí)間的流動(dòng)及重要訊號(hào)的出現(xiàn)而做出反應(yīng)的:
在價(jià)穩(wěn)量縮的盤(pán)整區(qū)間中突然出現(xiàn)一帶量突破的大紅K,表示股價(jià)可能要上漲了
在跳空缺口后出現(xiàn)島狀反轉(zhuǎn),表示股價(jià)可能要下跌了
在連漲幾天的走勢(shì)突然出現(xiàn)帶有長(zhǎng)上下影線(xiàn)的十字線(xiàn),表示股價(jià)有反轉(zhuǎn)的可能
LSTM 要做的事情就是找出一段時(shí)間區(qū)間的K棒當(dāng)中有沒(méi)有重要訊號(hào)(如帶量紅K)并學(xué)習(xí)預(yù)測(cè)之后股價(jià)的走勢(shì)。
LSTM 股價(jià)預(yù)測(cè)實(shí)例
數(shù)據(jù)是以鴻海(2317)從2013年初到2017年底每天的開(kāi)盤(pán)價(jià)、收盤(pán)價(jià)、最高價(jià)、最低價(jià)、以及成交量等數(shù)據(jù)。
首先將數(shù)據(jù)寫(xiě)入并存至pandas的DataFrame,另外對(duì)可能有N/A的row進(jìn)行剔除:
數(shù)據(jù)寫(xiě)入:
import?pandas?as?pdfoxconndf=?pd.read_csv('./foxconn_2013-2017.csv',?index_col=0?) foxconndf.dropna(how='any',inplace=True)為了避免原始數(shù)據(jù)太大或是太小沒(méi)有統(tǒng)一的范圍而導(dǎo)致 LSTM 在訓(xùn)練時(shí)難以收斂,我們以一個(gè)最小最大零一正規(guī)化方法對(duì)數(shù)據(jù)進(jìn)行修正:
from?sklearn?import?preprocessingdef?normalize(df):newdf=?df.copy()min_max_scaler?=?preprocessing.MinMaxScaler()newdf['open']?=?min_max_scaler.fit_transform(df.open.values.reshape(-1,1))newdf['low']?=?min_max_scaler.fit_transform(df.low.values.reshape(-1,1))newdf['high']?=?min_max_scaler.fit_transform(df.high.values.reshape(-1,1))newdf['volume']?=?min_max_scaler.fit_transform(df.volume.values.reshape(-1,1))newdf['close']?=?min_max_scaler.fit_transform(df.close.values.reshape(-1,1))return?newdffoxconndf_norm=?normalize(foxconndf)然后對(duì)數(shù)據(jù)進(jìn)行訓(xùn)練集與測(cè)試集的切割,另外也定義每一筆數(shù)據(jù)要有多長(zhǎng)的時(shí)間框架:
import?numpy?as?npdef?data_helper(df,?time_frame):#?數(shù)據(jù)維度:?開(kāi)盤(pán)價(jià)、收盤(pán)價(jià)、最高價(jià)、最低價(jià)、成交量,?5維number_features?=?len(df.columns)#?將dataframe?轉(zhuǎn)換為?numpy?arraydatavalue?=?df.as_matrix()result?=?[]#?若想要觀(guān)察的?time_frame?為20天,?需要多加一天作為驗(yàn)證答案for?index?in?range(?len(datavalue)?-?(time_frame+1)?):?#?從?datavalue?的第0個(gè)跑到倒數(shù)第?time_frame+1?個(gè)result.append(datavalue[index:?index?+?(time_frame+1)?])?#?逐筆取出?time_frame+1?個(gè)K棒數(shù)值做為一筆?instanceresult?=?np.array(result)number_train?=?round(0.9?*?result.shape[0])?#?取?result?的前90%?instance?作為訓(xùn)練數(shù)據(jù)x_train?=?result[:int(number_train),?:-1]?#?訓(xùn)練數(shù)據(jù)中,?只取每一個(gè)?time_frame?中除了最后一筆的所有數(shù)據(jù)作為featurey_train?=?result[:int(number_train),?-1][:,-1]?#?訓(xùn)練數(shù)據(jù)中,?取每一個(gè)?time_frame?中最后一筆數(shù)據(jù)的最后一個(gè)數(shù)值(收盤(pán)價(jià))作為答案#?測(cè)試數(shù)據(jù)x_test?=?result[int(number_train):,?:-1]y_test?=?result[int(number_train):,?-1][:,-1]#?將數(shù)據(jù)組成變好看一點(diǎn)x_train?=?np.reshape(x_train,?(x_train.shape[0],?x_train.shape[1],?number_features))x_test?=?np.reshape(x_test,?(x_test.shape[0],?x_test.shape[1],?number_features))??return?[x_train,?y_train,?x_test,?y_test]#?以20天為一區(qū)間進(jìn)行股價(jià)預(yù)測(cè) X_train,?y_train,?X_test,?y_test?=?data_helper(foxconndf_norm,?20)我們以 Keras 框架作為 LSTM 的模型選擇,首先在前面加了兩層 256個(gè)神經(jīng)元的 LSTM layer,并都加上了Dropout層來(lái)防止數(shù)據(jù)過(guò)度擬合(overfitting)。最后再加上兩層有不同數(shù)目神經(jīng)元的全連結(jié)層來(lái)得到只有1維數(shù)值的輸出結(jié)果,也就是預(yù)測(cè)股價(jià):
from?keras.models?import?Sequential from?keras.layers.core?import?Dense,?Dropout,?Activation from?keras.layers.recurrent?import?LSTM import?kerasdef?build_model(input_length,?input_dim):d?=?0.3model?=?Sequential()model.add(LSTM(256,?input_shape=(input_length,?input_dim),?return_sequences=True))model.add(Dropout(d))model.add(LSTM(256,?input_shape=(input_length,?input_dim),?return_sequences=False))model.add(Dropout(d))model.add(Dense(16,kernel_initializer="uniform",activation='relu'))model.add(Dense(1,kernel_initializer="uniform",activation='linear'))model.compile(loss='mse',optimizer='adam',?metrics=['accuracy'])return?model#?20天、5維 model?=?build_model(?20,?5?)建立好 LSTM 模型后,我們就用前面編輯好的訓(xùn)練數(shù)據(jù)集開(kāi)始進(jìn)行模型的訓(xùn)練:LSTM 模型訓(xùn)練
#?一個(gè)batch有128個(gè)instance,總共跑50個(gè)迭代 model.fit(?X_train,?y_train,?batch_size=128,?epochs=50,?validation_split=0.1,?verbose=1)在經(jīng)過(guò)一段時(shí)間的訓(xùn)練過(guò)程后,我們便能得到 LSTM 模型(model)。接著再用這個(gè)模型對(duì)測(cè)試數(shù)據(jù)進(jìn)行預(yù)測(cè),以及將預(yù)測(cè)出來(lái)的數(shù)值(pred)與實(shí)際股價(jià)(y_test)還原回原始股價(jià)的大小區(qū)間:
LSTM 模型預(yù)測(cè)股價(jià)及還原數(shù)值
def?denormalize(df,?norm_value):original_value?=?df['close'].values.reshape(-1,1)norm_value?=?norm_value.reshape(-1,1)min_max_scaler?=?preprocessing.MinMaxScaler()min_max_scaler.fit_transform(original_value)denorm_value?=?min_max_scaler.inverse_transform(norm_value)return?denorm_value#?用訓(xùn)練好的?LSTM?模型對(duì)測(cè)試數(shù)據(jù)集進(jìn)行預(yù)測(cè) pred?=?model.predict(X_test)#?將預(yù)測(cè)值與實(shí)際股價(jià)還原回原來(lái)的區(qū)間值 denorm_pred?=?denormalize(foxconndf,?pred) denorm_ytest?=?denormalize(foxconndf,?y_test)LSTM 預(yù)測(cè)股價(jià)結(jié)果
讓我們把還原后的數(shù)值與實(shí)際股價(jià)畫(huà)出來(lái),看看效果如何:
LSTM 預(yù)測(cè)股價(jià)結(jié)果
import?matplotlib.pyplot?as?plt %matplotlib?inline??plt.plot(denorm_pred,color='red',?label='Prediction') plt.plot(denorm_ytest,color='blue',?label='Answer') plt.legend(loc='best') plt.show()如下圖,藍(lán)線(xiàn)是實(shí)際股價(jià)、紅線(xiàn)是預(yù)測(cè)股價(jià)。雖然整體看起來(lái)預(yù)測(cè)股價(jià)與實(shí)際股價(jià)有類(lèi)似的走勢(shì),但仔細(xì)一看預(yù)測(cè)股價(jià)都比實(shí)際股價(jià)落后了幾天。
所以我們來(lái)調(diào)整一些設(shè)定:
時(shí)間框架長(zhǎng)度的調(diào)整
Keras 模型里全連結(jié)層的 activation 與 optimizaer 的調(diào)整
Keras 模型用不同的神經(jīng)網(wǎng)路(種類(lèi)、順序、數(shù)量)來(lái)組合batch_size?的調(diào)整、epochs?的調(diào)整 …
經(jīng)過(guò)我們對(duì)上述的幾個(gè)參數(shù)稍微調(diào)整過(guò)后,我們就得到一個(gè)更貼近實(shí)際股價(jià)的預(yù)測(cè)結(jié)果啦。
E?N?D
總結(jié)
以上是生活随笔為你收集整理的利用 LSTM 神经网络预测股价走势的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 7极限精简版64位_DNF:国服更新64
- 下一篇: Chrome插件hoxx