參考鏈接: 從Python獲取輸入
文章目錄
?一、背景二、主要技術介紹1、RNN模型2、LSTM模型3、控制門工作原理四、代碼實現五、案例分析六、參數設置七、結論完整程序下載
?
?
一、背景?
近年來,股票預測還處于一個很熱門的階段,因為股票市場的波動十分巨大,隨時可能因為一些新的政策或者其他原因,進行大幅度的波動,導致自然人股民很難對股票進行投資盈利。因此本文想利用現有的模型與算法,對股票價格進行預測,從而使自然人股民可以自己對股票進行預測。 理論上,股票價格是可以預測的,但是影響股票價格的因素有很多,而且目前為止,它們對股票的影響還不能清晰定義。這是因為股票預測是高度非線性的,這就要預測模型要能夠處理非線性問題,并且,股票具有時間序列的特性,因此適合用循環神經網絡,對股票進行預測。 雖然循環神經網絡(RNN),允許信息的持久化,然而,一般的RNN模型對具備長記憶性的時間序列數據刻畫能力較弱,在時間序列過長的時候,因為存在梯度消散和梯度爆炸現象RNN訓練變得非常困難。Hochreiter 和 Schmidhuber 提出的長短期記憶( Long Short-Term Memory,LSTM)模型在RNN結構的基礎上進行了改造,從而解決了RNN模型無法刻畫時間序列長記憶性的問題。 綜上所述,深度學習中的LSTM模型能夠很好地刻畫時間序列的長記憶性。?
二、主要技術介紹?
1、RNN模型?
在傳統的RNN(循環神經網絡)中,所有的w都是同一個w,經過同一個cell的時候,都會保留輸入的記憶,再加上另外一個要預測的輸入,所以預測包含了之前所有的記憶加上此次的輸入。所有RNN都具有一種重復神經網絡模塊的鏈式的形式。在標準的RNN中,這個重復的模塊只有一個非常簡單的結構,例如一個tanh層。 當權中大于1時,反向傳播誤差時,誤差將會一直放大,導致梯度爆炸;當權中小于1時,誤差將會一直縮小,導致梯度消失,進而導致網絡權重更新緩慢,無法體現出RNN的長期記憶的效果,使得RNN太過健忘。RNN模型的結構如圖:??
2、LSTM模型?
長短期記憶模型(long-short term memory)是一種特殊的RNN模型,是為了解決反向傳播過程中存在梯度消失和梯度爆炸現象,通過引入門(gate)機制,解決了RNN模型不具備的長記憶性問題,LSTM模型的結構如圖:?
?具體來說,LSTM模型的1個神經元包含了1個細胞狀態(cell)和3個門(gate)機制。細胞狀態(cell)是LSTM模型的關鍵所在,類似于存儲器,是模型的記憶空間。細胞狀態隨著時間而變化,記錄的信息由門機制決定和更新。門機制是讓信息選擇式通過的方法,通過sigmoid函數和點乘操作實現。sigmoid取值介于0~1之間,乘即點乘則決定了傳送的信息量(每個部分有多少量可以通過),當sigmoid取0時表示舍棄信息,取1時表示完全傳輸(即完全記住)[2]。 LSTM 擁有三個門,來保護和控制細胞狀態:遺忘門(forget gate)、更新門(update gate)和輸出門(output gate)。 細胞狀態類似于傳送帶。直接在整個鏈上運行,只有一些少量的線性交互。信息在上面流傳保持不變會很容易。 如圖:??
3、控制門工作原理?
遺忘門? 更新門? ?
輸出門??
四、代碼實現?
UI?
demo.py
import tensorflow as tf
import numpy as np
import tkinter as tk
from tkinter import filedialog
import time
import pandas as pd
?
import stock_predict as pred
?
?
def creat_windows():
? ? win = tk.Tk()? # 創建窗口
? ? sw = win.winfo_screenwidth()
? ? sh = win.winfo_screenheight()
? ? ww, wh = 800, 450
? ? x, y = (sw - ww) / 2, (sh - wh) / 2
? ? win.geometry("%dx%d+%d+%d" % (ww, wh, x, y - 40))? # 居中放置窗口
?
? ? win.title('LSTM股票預測')? # 窗口命名
?
? ? f_open =open('dataset_2.csv')
? ? canvas = tk.Label(win)
? ? canvas.pack()
?
? ? var = tk.StringVar()? # 創建變量文字
? ? var.set('選擇數據集')
? ? tk.Label(win, textvariable=var, bg='#C1FFC1', font=('宋體', 21), width=20, height=2).pack()
?
? ? tk.Button(win, text='選擇數據集', width=20, height=2, bg='#FF8C00', command=lambda: getdata(var, canvas),
? ? ? ? ? ? ? font=('圓體', 10)).pack()
?
? ? canvas = tk.Label(win)
? ? L1 = tk.Label(win, text="選擇你需要的 列(請用空格隔開,從0開始)")
? ? L1.pack()
? ? E1 = tk.Entry(win, bd=5)
? ? E1.pack()
? ? button1 = tk.Button(win, text="提交", command=lambda: getLable(E1))
? ? button1.pack()
? ? canvas.pack()
? ? win.mainloop()
?
def getLable(E1):
? ? string = E1.get()
? ? print(string)
? ? gettraindata(string)
?
def getdata(var, canvas):
? ? global file_path
? ? file_path = filedialog.askopenfilename()
? ? var.set("注,最后一個為label")
? ? # 讀取文件第一行標簽
? ? with open(file_path, 'r', encoding='gb2312') as f:
? ? # with open(file_path, 'r', encoding='utf-8') as f:
? ? ? ? lines = f.readlines()? # 讀取所有行
? ? ? ? data2 = lines[0]
? ? print()
?
? ? canvas.configure(text=data2)
? ? canvas.text = data2
?
def gettraindata(string):
? ? f_open = open(file_path)
? ? df = pd.read_csv(f_open)? # 讀入股票數據
? ? list = string.split()
? ? print(list)
? ? x = len(list)
? ? index=[]
? ? # data = df.iloc[:, [1,2,3]].values? # 取第3-10列 (2:10從2開始到9)
? ? for i in range(x):
? ? ? ? q = int(list[i])
? ? ? ? index.append(q)
? ? global data
? ? data = df.iloc[:, index].values
? ? print(data)
? ? main(data)
?
def main(data):
? ? pred.LSTMtest(data)
? ? var.set("預測的結果是:" + answer)
?
if __name__ == "__main__":
? ? creat_windows()
?
stock_predict.py?
import numpy as np
import matplotlib.pyplot as plt
import tensorflow as tf
import pandas as pd
import math
?
def LSTMtest(data):
?
? ? n1 = len(data[0]) - 1 #因為最后一位為label
? ? n2 = len(data)
? ? print(n1, n2)
?
? ? # 設置常量
? ? input_size = n1? # 輸入神經元個數
? ? rnn_unit = 10? ? # LSTM單元(一層神經網絡)中的中神經元的個數
? ? lstm_layers = 7? # LSTM單元個數
? ? output_size = 1? # 輸出神經元個數(預測值)
? ? lr = 0.0006? ? ? # 學習率
?
? ? train_end_index = math.floor(n2*0.9)? # 向下取整
? ? print('train_end_index', train_end_index)
? ? # 前90%數據作為訓練集,后10%作為測試集
? ? # 獲取訓練集
? ? # time_step 時間步,batch_size 每一批次訓練多少個樣例
? ? def get_train_data(batch_size=60, time_step=20, train_begin=0, train_end=train_end_index):
? ? ? ? batch_index = []
? ? ? ? data_train = data[train_begin:train_end]
? ? ? ? normalized_train_data = (data_train - np.mean(data_train, axis=0)) / np.std(data_train, axis=0)? # 標準化
? ? ? ? train_x, train_y = [], []? # 訓練集
? ? ? ? for i in range(len(normalized_train_data) - time_step):
? ? ? ? ? ? if i % batch_size == 0:
? ? ? ? ? ? ? ? # 開始位置
? ? ? ? ? ? ? ? batch_index.append(i)
? ? ? ? ? ? ? ? # 一次取time_step行數據
? ? ? ? ? ? # x存儲輸入維度(不包括label) :X(最后一個不取)
? ? ? ? ? ? # 標準化(歸一化)
? ? ? ? ? ? x = normalized_train_data[i:i + time_step, :n1]
? ? ? ? ? ? # y存儲label
? ? ? ? ? ? y = normalized_train_data[i:i + time_step, n1, np.newaxis]
? ? ? ? ? ? # np.newaxis分別是在行或列上增加維度
? ? ? ? ? ? train_x.append(x.tolist())
? ? ? ? ? ? train_y.append(y.tolist())
? ? ? ? # 結束位置
? ? ? ? batch_index.append((len(normalized_train_data) - time_step))
? ? ? ? print('batch_index', batch_index)
? ? ? ? # print('train_x', train_x)
? ? ? ? # print('train_y', train_y)
? ? ? ? return batch_index, train_x, train_y
?
? ? # 獲取測試集
? ? def get_test_data(time_step=20, test_begin=train_end_index+1):
? ? ? ? data_test = data[test_begin:]
? ? ? ? mean = np.mean(data_test, axis=0)
? ? ? ? std = np.std(data_test, axis=0)? # 矩陣標準差
? ? ? ? # 標準化(歸一化)
? ? ? ? normalized_test_data = (data_test - np.mean(data_test, axis=0)) / np.std(data_test, axis=0)
? ? ? ? # " // "表示整數除法。有size個sample
? ? ? ? test_size = (len(normalized_test_data) + time_step - 1) // time_step
? ? ? ? print('test_size$$$$$$$$$$$$$$', test_size)
? ? ? ? test_x, test_y = [], []
? ? ? ? for i in range(test_size - 1):
? ? ? ? ? ? x = normalized_test_data[i * time_step:(i + 1) * time_step, :n1]
? ? ? ? ? ? y = normalized_test_data[i * time_step:(i + 1) * time_step, n1]
? ? ? ? ? ? test_x.append(x.tolist())
? ? ? ? ? ? test_y.extend(y)
? ? ? ? test_x.append((normalized_test_data[(i + 1) * time_step:, :n1]).tolist())
? ? ? ? test_y.extend((normalized_test_data[(i + 1) * time_step:, n1]).tolist())
? ? ? ? return mean, std, test_x, test_y
?
? ? # ——————————————————定義神經網絡變量——————————————————
? ? # 輸入層、輸出層權重、偏置、dropout參數
? ? # 隨機產生 w,b
? ? weights = {
? ? ? ? 'in': tf.Variable(tf.random_normal([input_size, rnn_unit])),
? ? ? ? 'out': tf.Variable(tf.random_normal([rnn_unit, 1]))
? ? }
? ? biases = {
? ? ? ? 'in': tf.Variable(tf.constant(0.1, shape=[rnn_unit, ])),
? ? ? ? 'out': tf.Variable(tf.constant(0.1, shape=[1, ]))
? ? }
? ? keep_prob = tf.placeholder(tf.float32, name='keep_prob')? # dropout 防止過擬合
?
? ? # ——————————————————定義神經網絡——————————————————
? ? def lstmCell():
? ? ? ? # basicLstm單元
? ? ? ? # tf.nn.rnn_cell.BasicLSTMCell(self, num_units, forget_bias=1.0,
? ? ? ? # tate_is_tuple=True, activation=None, reuse=None, name=None)?
? ? ? ? # num_units:int類型,LSTM單元(一層神經網絡)中的中神經元的個數,和前饋神經網絡中隱含層神經元個數意思相同
? ? ? ? # forget_bias:float類型,偏置增加了忘記門。從CudnnLSTM訓練的檢查點(checkpoin)恢復時,必須手動設置為0.0。
? ? ? ? # state_is_tuple:如果為True,則接受和返回的狀態是c_state和m_state的2-tuple;如果為False,則他們沿著列軸連接。后一種即將被棄用。
? ? ? ? # (LSTM會保留兩個state,也就是主線的state(c_state),和分線的state(m_state),會包含在元組(tuple)里邊
? ? ? ? # state_is_tuple=True就是判定生成的是否為一個元組)
? ? ? ? #? ?初始化的 c 和 a 都是zero_state 也就是都為list[]的zero,這是參數state_is_tuple的情況下
? ? ? ? #? ?初始state,全部為0,慢慢的累加記憶
? ? ? ? # activation:內部狀態的激活函數。默認為tanh
? ? ? ? # reuse:布爾類型,描述是否在現有范圍中重用變量。如果不為True,并且現有范圍已經具有給定變量,則會引發錯誤。
? ? ? ? # name:String類型,層的名稱。具有相同名稱的層將共享權重,但為了避免錯誤,在這種情況下需要reuse=True.
? ? ? ? #
?
? ? ? ? basicLstm = tf.nn.rnn_cell.BasicLSTMCell(rnn_unit, forget_bias=1.0, state_is_tuple=True)
? ? ? ? # dropout 未使用
? ? ? ? drop = tf.nn.rnn_cell.DropoutWrapper(basicLstm, output_keep_prob=keep_prob)
? ? ? ? return basicLstm
?
? ?
?
? ? def lstm(X):? # 參數:輸入網絡批次數目
? ? ? ? batch_size = tf.shape(X)[0]
? ? ? ? time_step = tf.shape(X)[1]
? ? ? ? w_in = weights['in']
? ? ? ? b_in = biases['in']
?
? ? ? ? # 忘記門(輸入門)
? ? ? ? # 因為要進行矩陣乘法,所以reshape
? ? ? ? # 需要將tensor轉成2維進行計算
? ? ? ? input = tf.reshape(X, [-1, input_size])
? ? ? ? input_rnn = tf.matmul(input, w_in) + b_in
? ? ? ? # 將tensor轉成3維,計算后的結果作為忘記門的輸入
? ? ? ? input_rnn = tf.reshape(input_rnn, [-1, time_step, rnn_unit])
? ? ? ? print('input_rnn', input_rnn)
? ? ? ? # 更新門
? ? ? ? # 構建多層的lstm
? ? ? ? cell = tf.nn.rnn_cell.MultiRNNCell([lstmCell() for i in range(lstm_layers)])
? ? ? ? init_state = cell.zero_state(batch_size, dtype=tf.float32)
?
? ? ? ? # 輸出門
? ? ? ? w_out = weights['out']
? ? ? ? b_out = biases['out']
? ? ? ? # output_rnn是最后一層每個step的輸出,final_states是每一層的最后那個step的輸出
? ? ? ? output_rnn, final_states = tf.nn.dynamic_rnn(cell, input_rnn, initial_state=init_state, dtype=tf.float32)
? ? ? ? output = tf.reshape(output_rnn, [-1, rnn_unit])
? ? ? ? # 輸出值,同時作為下一層輸入門的輸入
? ? ? ? pred = tf.matmul(output, w_out) + b_out
? ? ? ? return pred, final_states
?
? ? # ————————————————訓練模型————————————————————
?
? ? def train_lstm(batch_size=60, time_step=20, train_begin=0, train_end=train_end_index):
? ? ? ? # 于是就有了tf.placeholder,
? ? ? ? # 我們每次可以將 一個minibatch傳入到x = tf.placeholder(tf.float32,[None,32])上,
? ? ? ? # 下一次傳入的x都替換掉上一次傳入的x,
? ? ? ? # 這樣就對于所有傳入的minibatch x就只會產生一個op,
? ? ? ? # 不會產生其他多余的op,進而減少了graph的開銷。
?
? ? ? ? X = tf.placeholder(tf.float32, shape=[None, time_step, input_size])
? ? ? ? Y = tf.placeholder(tf.float32, shape=[None, time_step, output_size])
? ? ? ? batch_index, train_x, train_y = get_train_data(batch_size, time_step, train_begin, train_end)
? ? ? ? # 用tf.variable_scope來定義重復利用,LSTM會經常用到
? ? ? ? with tf.variable_scope("sec_lstm"):
? ? ? ? ? ? pred, state_ = lstm(X) # pred輸出值,state_是每一層的最后那個step的輸出
? ? ? ? print('pred,state_', pred, state_)
?
? ? ? ? # 損失函數
? ? ? ? # [-1]——列表從后往前數第一列,即pred為預測值,Y為真實值(Label)
? ? ? ? #tf.reduce_mean 函數用于計算張量tensor沿著指定的數軸(tensor的某一維度)上的的平均值
? ? ? ? loss = tf.reduce_mean(tf.square(tf.reshape(pred, [-1]) - tf.reshape(Y, [-1])))
? ? ? ? # 誤差loss反向傳播——均方誤差損失
? ? ? ? # 本質上是帶有動量項的RMSprop,它利用梯度的一階矩估計和二階矩估計動態調整每個參數的學習率。
? ? ? ? # Adam的優點主要在于經過偏置校正后,每一次迭代學習率都有個確定范圍,使得參數比較平穩.
? ? ? ? train_op = tf.train.AdamOptimizer(lr).minimize(loss)
? ? ? ? saver = tf.train.Saver(tf.global_variables(), max_to_keep=15)
?
? ? ? ? with tf.Session() as sess:
? ? ? ? ? ? # 初始化
? ? ? ? ? ? sess.run(tf.global_variables_initializer())
? ? ? ? ? ? theloss = []
? ? ? ? ? ? # 迭代次數
? ? ? ? ? ? for i in range(200):
? ? ? ? ? ? ? ? for step in range(len(batch_index) - 1):
? ? ? ? ? ? ? ? ? ? # sess.run(b, feed_dict = replace_dict)
? ? ? ? ? ? ? ? ? ? state_, loss_ = sess.run([train_op, loss],
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? feed_dict={X: train_x[batch_index[step]:batch_index[step + 1]],
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?Y: train_y[batch_index[step]:batch_index[step + 1]],
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?keep_prob: 0.5})
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? #? 使用feed_dict完成矩陣乘法 處理多輸入
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? #? feed_dict的作用是給使用placeholder創建出來的tensor賦值
?
?
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? #? [batch_index[step]: batch_index[step + 1]]這個區間的X與Y
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? #? keep_prob的意思是:留下的神經元的概率,如果keep_prob為0的話, 就是讓所有的神經元都失活。
? ? ? ? ? ? ? ? print("Number of iterations:", i, " loss:", loss_)
? ? ? ? ? ? ? ? theloss.append(loss_)
? ? ? ? ? ? print("model_save: ", saver.save(sess, 'model_save2\\modle.ckpt'))
? ? ? ? ? ? print("The train has finished")
? ? ? ? return theloss
?
? ? theloss = train_lstm()
?
? ? # ————————————————預測模型————————————————————
? ? def prediction(time_step=20):
?
? ? ? ? X = tf.placeholder(tf.float32, shape=[None, time_step, input_size])
? ? ? ? mean, std, test_x, test_y = get_test_data(time_step)
? ? ? ? # 用tf.variable_scope來定義重復利用,LSTM會經常用到
? ? ? ? with tf.variable_scope("sec_lstm", reuse=tf.AUTO_REUSE):
? ? ? ? ? ? pred, state_ = lstm(X)
? ? ? ? saver = tf.train.Saver(tf.global_variables())
? ? ? ? with tf.Session() as sess:
? ? ? ? ? ? # 參數恢復(讀取已存在模型)
? ? ? ? ? ? module_file = tf.train.latest_checkpoint('model_save2')
? ? ? ? ? ? saver.restore(sess, module_file)
? ? ? ? ? ? test_predict = []
? ? ? ? ? ? for step in range(len(test_x) - 1):
? ? ? ? ? ? ? ? predict = sess.run(pred, feed_dict={X: [test_x[step]], keep_prob: 1})
? ? ? ? ? ? ? ? predict = predict.reshape((-1))
? ? ? ? ? ? ? ? test_predict.extend(predict)? # 把predict的內容添加到列表
?
? ? ? ? ? ? # 相對誤差=(測量值-計算值)/計算值×100%
? ? ? ? ? ? test_y = np.array(test_y) * std[n1] + mean[n1]
? ? ? ? ? ? test_predict = np.array(test_predict) * std[n1] + mean[n1]
? ? ? ? ? ? acc = np.average(np.abs(test_predict - test_y[:len(test_predict)]) / test_y[:len(test_predict)])
? ? ? ? ? ? print("預測的相對誤差:", acc)
?
? ? ? ? ? ? print(theloss)
? ? ? ? ? ? plt.figure()
? ? ? ? ? ? plt.plot(list(range(len(theloss))), theloss, color='b', )
? ? ? ? ? ? plt.xlabel('times', fontsize=14)
? ? ? ? ? ? plt.ylabel('loss valuet', fontsize=14)
? ? ? ? ? ? plt.title('loss-----blue', fontsize=10)
? ? ? ? ? ? plt.show()
? ? ? ? ? ? # 以折線圖表示預測結果
? ? ? ? ? ? plt.figure()
? ? ? ? ? ? plt.plot(list(range(len(test_predict))), test_predict, color='b', )
? ? ? ? ? ? plt.plot(list(range(len(test_y))), test_y, color='r')
? ? ? ? ? ? plt.xlabel('time value/day', fontsize=14)
? ? ? ? ? ? plt.ylabel('close value/point', fontsize=14)
? ? ? ? ? ? plt.title('predict-----blue,real-----red', fontsize=10)
? ? ? ? ? ? plt.show()
?
?
?
? ? prediction()
?
五、案例分析?
1、數據說明 本實驗分析了兩種股票種類,為某單支股票(6109個連續時間點)數據data2上證綜合指數前復權日線(6230個連續時間點,1991年到2016年)數據作為data2,分別保存在兩個文件中,將兩個數據集的最后一列設定為label。前90%數據作為訓練集,后10%作為測試集。 Data1:? Data2:? 本次實驗所采用的為LSTM模型: 輸入神經元個數 input_size = 選取列數 輸出神經元個數 output_size = 1 (預測值個數) 學習率 lr = 0.0006 隨機初始化初始化網絡權重?
2、數據預處理 零-均值規范化(z-score標準化): 標準化值,是講集合中單個數與集合的均值相減的結果除以集合的標準差得到的標準化的結果,該方法類似與正態分布標準化轉換,轉換函數公式為:? 公式中x為需要被標準化的原始值,μ為均值,σ為標準差,σ不等于0。 Z分數標準化處理后的值代表原始值和集合均值之間的舉例,以標準差為單位計算。該值存在正負值,低于均值均為輔助,反之則為證書,其范圍為[-∞,+∞],數據均值為0,方差為1。 3、損失函數 損失函數(Loss function)是用來估量網絡模型的預測值X與真實值Y的不一致程度,它是一個非負實值函數,通常用 L(Y,f(x))來表示。損失函數越小,模型的魯棒性就越好。損失函數是經驗風險函數的核心部分,也是結構風險函數的重要組成部分。 本實驗采取十分常用的均方誤差損失: 平方損失也可以理解為是最小二乘法,一般在回歸問題中比較常見,最小二乘法的基本原理是:最優擬合直線是使各點到回歸直線的距離和最小的直線,即平方和最。同時在實際應用中,均方誤差也經常被用為衡量模型的標準:??
4、誤差標準 相對偏差是指某一次測量的絕對偏差占平均值的百分比。? 5、可視化UI? ?
六、參數設置?
1、輸入維度及迭代次數? 由表一可見,輸入維度越多,網絡訓練效果越好;迭代次數在100次時,網絡已經比較穩定。 2、忘記偏置? 由表二可見,在data1(單支股票)forget_bias適當減小,即忘記部分信息,網絡訓練效果有些許提高,但在data2(大盤)中,網絡訓練效果卻有所下滑。個人認為,可能是因為對于單支股票來說,近2天的數據相關程度比較小,而在大盤中,因為近2天的數據相關程度比較大,畢竟有多方面因素影響股價。 3、LSTM單元數??
由表三可見,兩個數據集中,LSTM單元數增加的情況下時,網絡訓練效果反而下降,可以看出,其實股票行情在7天內的的相關聯程度比在14天內的情況高,但是有可能是因為forget_bias過大。因此,在進行一組實驗,調整forget_bias值進行比較。? 由表四可以看出,在相同LSTM單元數的情況下,forget_bias較小時,預測效果較好,我們可以看出,在LSTM單元數較大的情況下,forget_bias應選取比較小的,以免記憶太多無效信息。? 由表五可以看出,在data1和data2兩個數據集中,LSTM單元數較小的情況下,forget_bias比較大時,預測效果較好,記憶更多相關信息。因此LSTM單元數較小的情況下,forget_bias應選取比較大的,記憶更多相關信息。?
4、可視化結果 選取數據集data1,迭代次數為200次?
(1)、忘記偏置=1.0 , LSTM單元數 = 2??
(2)、忘記偏置=0.7 , LSTM單元數 = 2(表現最好)? (3)、忘記偏置=1.0 , LSTM單元數 = 7? (4)、忘記偏置=1.0 , LSTM單元數 = 14??
(5)、忘記偏置=0.7, LSTM單元數 = 7? (6)、忘記偏置=0.4 , LSTM單元數 = 7? (7)、忘記偏置=0.4 , LSTM單元數 = 14??
七、結論?
針對以上實驗,可以得知,在LSTM模型下的對股票收盤價預測值較為準確和穩定。對LSTM模型進行參數調整,發現迭代次數在100次后,網絡模型趨于穩定,說明其是一個較輕量級的網絡;在LSTM單元數較大的情況下,forget_bias應選取比較小的,以免記憶太多無效信息;LSTM單元數較小的情況下,forget_bias應選取比較大的,記憶更多相關信息。當然,這和本身的數據集有關。就股票數據集來說,本實驗中表現的最優秀的是,忘記偏置為0.7,LSTM神經單元數取2時,網絡預測效果最好,說明,在2天內股票序列是比較有價值的,與最后預測值有一定程度的聯系。?
完整程序下載?
https://download.csdn.net/download/zxm_jimin/12126063 自行調試運行噢~?
參考文獻 [1] 陳衛華. 基于深度學習的上證綜指波動率預測效果比較研究[D].統計與信息論壇,2018. [2] Hochreiter & Schmidhuber. Long short-term memory[ J]. Neural Computation, 1997, 9( 8).?
參考博客 https://blog.csdn.net/jiaoyangwm/article/details/79725445 https://blog.csdn.net/mylove0414/article/details/56969181?
本文為原創。 轉載請注明出處。