天天看點

神經網絡用于股市分析從神經網絡到循環神經網絡再到LSTM股市預測

從神經網絡到循環神經網絡再到LSTM股市預測

 一、 前言

         本篇文章是用來做大作業的,會講到神經網絡基礎、逆回報算法推導、循環神經網絡和LSTM基礎(這裡關于LSTM是參考【1】)以及它們的用于股市預測的執行個體。神經網絡(NeuralNetworks)是一種用訓練資料拟合目标函數的黑箱模型,隻要資料量足夠大,它可以拟合出輸入到輸出之間的任意函數關系,這在原理上是比較難解釋的,但已經有許多工作從神經網絡中抽取易于了解的符号規則用于改善神經網絡的可解釋性。傳統的神經網絡模型的輸入是沒有時間關聯性的,一個輸入對應一個輸出,上一個輸入不影響下一個輸入,而循環神經網絡(Recurrent neural Network)就是一種可以處理這種序列資料輸入問題的神經網絡結構模型,比如我們需要判斷句子情感類型或者為電影每一幀畫面貼标簽都可以用RNN。

二、神經網絡(Neural Network)

1.初識神經網絡

        神經網絡是幹什麼的?它最重要的作用就是用于端到端的分類,圖檔的分類、文字的文類都是将需要将分類的内容以數值向量的形式輸入給模型,然後通過我們上文說的黑箱操作進行分類得到一個數值或者向量的分類結果。舉一個簡單的例子,在識别手寫數字的時候,輸入層是28×28的圖像像素點矩陣,輸出層是[ 1.,  0.,  0., ..., 0.,  0.,  0.]這樣的單行矩陣,第一列是1表示分類的結果是1,中間的隐層(hidden layer)就是我們的黑箱。

2.神經元模型

        神經網絡中的最基本的組成成分就是神經元(neuron),輸入、輸出的激活層中每一個最小的機關就是神經元,下圖是神經元模型的過程分析,神經元收到外部m個輸入信号(可能是一個,也有可能是多個由其他神經元傳輸過來的),首先對所有信号進行權重疊加然後判斷是否大于神經元阙值,如果大于則送入激活函數進行輸出,如下圖就是一個神經元模型的網絡結構。

神經網絡用于股市分析從神經網絡到循環神經網絡再到LSTM股市預測

3.單層網絡

        神經網絡的學習規則就是通過調整權重和阙值去拟合函數,這種調整依賴于上一個神經元激勵值的大小,如圖就是一個單層神經網絡(感覺機),通過調整三個權重它可以去拟合一些簡單的線性分類函數。

神經網絡用于股市分析從神經網絡到循環神經網絡再到LSTM股市預測

4.多層網絡

         如果感覺機隻有一層,它的學習能力是非常有限的,在學習非線性問題時由于模型找不到合适的權重,會發生權重震蕩的現象,如果考慮到非線性問題就需要用到多層網絡,即在輸入層和輸出層之間加上若幹隐層,換句話說多層網絡就是通過激活函數不斷地增加拟合函數的緯度,而用非線性函數分類明顯更加容易,如圖是一個含有四個隐層的多層網絡(圖引用于【2】)和一個線性不可分問題示例。

神經網絡用于股市分析從神經網絡到循環神經網絡再到LSTM股市預測

5.誤差逆傳播算法(BackPropagation)

        多層網絡的學習能力較單層網絡相比強得多,但是它的訓練是非常麻煩的,常用的方法是誤差逆傳播算法也稱反向傳播算法,本節以下圖含有一層隐層的網絡為例介紹BP的原理。

神經網絡用于股市分析從神經網絡到循環神經網絡再到LSTM股市預測
神經網絡用于股市分析從神經網絡到循環神經網絡再到LSTM股市預測

5.存在問題

       神經網絡的隐層數量足夠就可以拟合任何複雜的函數,但是經常會出現過拟合的現象,解決這樣的問題一般由兩種政策:一是通過設定訓練集和驗證集,當訓練集誤差降低但驗證集誤差升高則停止訓練;第二種則是正則化,可以在損失函數上加L1或者L2正則化項,用于描述算法複雜度,具體可以參考李航老師的《統計學習方法》。

三、循環神經網絡(RecurrentNeural Network)

1.循環神經網絡結構

         循環神經網絡是用于預測序列資料的(比如文本、語音、視訊、圖像、氣象和股票資料等),傳統的神經網絡隐層到輸出層之間是全連接配接,但是當我們的資料是一組有關聯的時間序列資訊時我們需要在隐層實作内部神經元間的互相作用,即系統隐層的輸出會保留在網絡裡,和系統下一刻的輸入一起共同決定下一刻的輸出,而每一個輸入神經元就是一個時刻的資訊。如下圖中,每個時間點輸入資訊包含了上一層隐層和資訊和此時間點的資訊。

神經網絡用于股市分析從神經網絡到循環神經網絡再到LSTM股市預測

         對每個隐層神經元内部進行分析,每神經元都會對原始輸入和上一個時間點(神經元)的輸入進行加工(tanh激活函數),如下圖:

神經網絡用于股市分析從神經網絡到循環神經網絡再到LSTM股市預測

2. 基于時間的反向傳播算法BPTT(Back Propagation Trough Time)

        在講RNN的訓練之前首先需要講一下RNN用到的activation function tanh,其實很簡單就是雙曲正切函數,它和sigmoid的差別在于它在(-1,1)區間函數值變化沒有前者那麼敏感,用于梯度求解更不容易發生梯度彌散的現象。對于RNN的訓練和傳統的神經網絡相似,前向傳播隻需要依次按照時間的順序計算每個時間點的輸出值就行,反向傳播需要在BP算法上加時序變化, 從最後一個時間将累積的殘差傳遞回來。

神經網絡用于股市分析從神經網絡到循環神經網絡再到LSTM股市預測

3.存在問題

       上文也說了,為了解決梯度彌散或者梯度爆炸的現象我們選擇用tanh而不用sigmoid,但隻能在網絡層次較低的時候降低發生機率,一般解決這個問題有兩種政策:1.換用如今神經網絡常用的激活函數relu;2.改進網絡結構,如:LSTM,GRU.同時LSTM也有利于解決長期依賴問題,就是說當相關資訊和目前預測位置之間的間隔變大了之後RNN的感覺能力就會下降。

四、LSTM(Long Short-Term Memory)

1.LSTM網絡結構總叙述

         LSTM是一種時間遞歸神經網絡,适合于處理和預測時間序列中間隔和延遲相對較長的事件, 基于 LSTM 的系統可以學習翻譯語言、控制機器人、圖像分析、文檔摘要、語音識别圖像識别、手寫識别、控制聊天機器人、預測疾病、點選率和股票、合成音樂等等任務。LSTM之是以可以解決延遲相對較長的輸入資訊是因為它加入了一種用于資訊選擇的Cell,每個Cell中含有三種門控結構和一個狀态參數Cell State(細胞狀态),門控結構來去除或者增加資訊到細胞狀态的能力,它包含一個 sigmoid 神經網絡層和一個pointwise 乘法操作。接下來就結合下圖講解一下三種門控結構和細胞狀态以及詳細的網絡結構(本小結主要參考【1】,這是原論文的譯文,講解的十厘清楚):

神經網絡用于股市分析從神經網絡到循環神經網絡再到LSTM股市預測

2.細胞狀态

        細胞狀态就是 Ct,類似于細胞狀态類似于傳送帶,資訊直接在整個鍊上運作,隻有一些少量的線性互動。

神經網絡用于股市分析從神經網絡到循環神經網絡再到LSTM股市預測

3.遺忘門

神經網絡用于股市分析從神經網絡到循環神經網絡再到LSTM股市預測
神經網絡用于股市分析從神經網絡到循環神經網絡再到LSTM股市預測

4.輸入門

         輸入門決定什麼資訊應該被存入細胞狀态,輸入門由兩部分組成,第一部分使用了sigmoid激活函數,輸出為 it,第二部分使用了tanh激活函數,輸出為Ct' , 兩者的結果後面會相乘再去更新細胞狀态。

神經網絡用于股市分析從神經網絡到循環神經網絡再到LSTM股市預測

5.更新細胞狀态

       舊細胞狀态與舍棄資訊 ft相乘,再加上輸入門中兩種資訊的乘積,得到下一個時間的細胞資訊Ct。

神經網絡用于股市分析從神經網絡到循環神經網絡再到LSTM股市預測

6.輸出門

       輸出門确定輸出什麼值,這個輸出将會基于我們的細胞狀态,但是也是一個過濾後的版本。首先,我們運作一個 sigmoid 層來确定細胞狀态的哪個部分将輸出出去。接着,我們把細胞狀态通過 tanh 進行處理(得到一個在 -1 到 1 之間的值)并将它和sigmoid 門的輸出相乘,最終我們僅僅會輸出我們确定輸出的那部分。

神經網絡用于股市分析從神經網絡到循環神經網絡再到LSTM股市預測

四、LSTM執行個體:股票分析

1.介紹

 此實驗是基于五百支股票的每分鐘報價得到的标準普爾500指數(SP500)對下一分鐘的SP500進行預測,标準普爾500指數具有采樣面廣、代表性強、精确度高、連續性好等特點,被普遍認為是一種理想的股票指數期貨合約的标的。本次實驗資料來自【3】團隊在STATWORX上進行協作,Google Finance API抓取了每分鐘的标準普爾500指數。

2.代碼分析

#——————————————————資料分析——————————————————————
data = pd.read_csv('data_stock.csv')
sp500=data['SP500']
stock_value=data.iloc[1]
stock_value_example=stock_value.values[2:] 
           
plt.figure(figsize=(12,4),dpi=80)
plt.title('Examples of stock price volatility') 
plt.plot(stock_value_example, 'y.')
plt.show()
plt.figure(figsize=(12,4),dpi=80)
plt.title('Examples of stock sp500 value') 
plt.plot(sp500, 'r-')
plt.show()
           

神經網絡用于股市分析從神經網絡到循環神經網絡再到LSTM股市預測

神經網絡用于股市分析從神經網絡到循環神經網絡再到LSTM股市預測

#——————————————————資料讀入——————————————————————
data = data.drop(['DATE'], 1)  
row = data.shape[0]
col = data.shape[1]
data_value = data.values
print(row,col,'\n',data_value,'\n')
train_start = 0
train_end = int(np.floor(0.8*row))
test_start = train_end 
test_end = row
data_train = data_value[np.arange(train_start, train_end), :]
data_test = data_value[np.arange(test_start, test_end), :]
print(data_train.shape,data_test.shape)
           

神經網絡用于股市分析從神經網絡到循環神經網絡再到LSTM股市預測

#———————————————資料歸一處理———————————————————
from sklearn.preprocessing import MinMaxScaler
scaler = MinMaxScaler()
scaler.fit(data_train)
data_train = scaler.transform(data_train)
data_test = scaler.transform(data_test)
print(data_train)
           

神經網絡用于股市分析從神經網絡到循環神經網絡再到LSTM股市預測

#—————————————————設定超參數—————————————————————
lr = 1e-3
lr_decay = 0.5 # 學習速率衰減
batch_size = 100
input_size = 500
time_step = 100#時間步
hidden_size = 20
layer_num = 2
class_num = 1
#用于dropout.每批資料輸入時神經網絡中的每個單元會以1-keep_prob的機率不工作
keep_prob = 0.8
cell_type="lstm"
           
#———————————————資料劃分————————————————   
X_train,y_train,batch_index=[],[],[]
for i in range(len(data_train)-time_step):
    if i % batch_size==0:
        batch_index.append(i)  
    x=data_train[i:i+time_step,1:]
    y=data_train[i:i+time_step,0]
    X_train.append(x.tolist())
    y_train.append(y.tolist())
batch_index.append((len(data_train)-time_step))
X_test,y_test=[],[]
for i in range(len(data_test)-time_step): 
    x=data_test[i:i+time_step,1:]
    y=data_test[i:i+time_step,0]
    X_test.append(x.tolist())
    y_test.append(y.tolist())
y_train=np.reshape(y_train,[1500,100,1])
y_test=np.reshape(y_test,[300,100,1])
print(np.shape(y_train))
print(np.shape(X_train)
           

神經網絡用于股市分析從神經網絡到循環神經網絡再到LSTM股市預測

#—————————————————網絡結構—————————————————————
from tensorflow.contrib import rnn 
X_input=tf.placeholder(tf.float32, shape=[None,time_step,input_size])
Y_input=tf.placeholder(tf.float32, shape=[None,time_step,1])
W= tf.Variable(tf.truncated_normal([hidden_size, class_num], stddev=0.1), dtype=tf.float32)
bias = tf.Variable(tf.constant(0.1,shape=[class_num]), dtype=tf.float32)
#步驟1:定義輸入層
X=X_input
#步驟2:定義LSTM_cell
def lstm_cell(cell_type, num_nodes, keep_prob):
    if cell_type == "lstm":
        cell = tf.contrib.rnn.BasicLSTMCell(num_nodes)
    else:
        cell = tf.contrib.rnn.LSTMBlockCell(num_nodes)
    cell = tf.contrib.rnn.DropoutWrapper(cell, output_keep_prob=keep_prob)
    return cell
# 步驟3:調用 MultiRNNCell 來實作多層 LSTM
mlstm_cell = tf.contrib.rnn.MultiRNNCell([lstm_cell(cell_type, hidden_size, keep_prob) \
            for _ in range(layer_num)], state_is_tuple = True)
# 步驟4:初始化state
init_state = mlstm_cell.zero_state(batch_size, dtype=tf.float32)
           
#—————————————————隐層輸出—————————————————————
outputs=[]
state = init_state 
with tf.variable_scope('RNN'):
    for timestep in range(time_step):
        if timestep > 0: 
            tf.get_variable_scope().reuse_variables()
        (cell_output, state) = mlstm_cell(X[:, timestep, :], state) 
        outputs.append(cell_output)
h_state =outputs
           
#——————————————————訓練模型——————————————————   
#預測值
y_pre=[]
for i in range(100):
    pre = tf.matmul(h_state[i], W) + bias
    y_pre.append(pre)
#損失函數  
loss_function=tf.reduce_mean(abs(Y_input-y_pre))
train_op=tf.train.AdamOptimizer(lr).minimize(loss_function)
correct_prediction = tf.equal(y_pre,Y_input)
accuracy = tf.reduce_mean(tf.cast(correct_prediction, "float"))
saver = tf.train.Saver() 
with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    for  i in range(500):
        for step in range(len(batch_index)-1):
            cost,acc,_= sess.run([loss_function, accuracy, train_op], feed_dict={\
                X_input:X_train[batch_index[step]:batch_index[step+1]],\
                Y_input: y_train[batch_index[step]:batch_index[step+1]]})
        if (i % 50) == 0:
            print('The current step is',i,'the loss function value is' ,cost,'\n')
            save_path = saver.save(sess,"LSTM_model/lstm_mode.ckpt")    
           

3.訓練結果    

    通過500次疊代,每次疊代選擇100分鐘的時間序列,輸入是一個[100,500,100]的三維矩陣,輸出是一個[100,100,1]的三位矩陣,損失函數選擇兩個矩陣之差的均值,可以看到損失函數的總體呈下降趨勢,同時沒有陷入局部最優點。

神經網絡用于股市分析從神經網絡到循環神經網絡再到LSTM股市預測
神經網絡用于股市分析從神經網絡到循環神經網絡再到LSTM股市預測

4.結果分析

    以1600到1650分鐘的SP500指數為例,分析預測結果,發現實際結果和預測結果大緻趨勢相同:

神經網絡用于股市分析從神經網絡到循環神經網絡再到LSTM股市預測

    同時分析1到1600分鐘的500支股票價格的變化浮動得到漲跌幅排行榜:

神經網絡用于股市分析從神經網絡到循環神經網絡再到LSTM股市預測

參考文獻:【1】https://www.jianshu.com/p/9dc9f41f0b29

                 【2】https://www.cnblogs.com/maybe2030/p/5597716.html

                 【3】https://cloud.tencent.com/developer/article/1042820

繼續閱讀