在上一篇中,我們回顧了先知的方法,但是在這個案例中表現也不是特別突出,今天介紹的是著名的l s t m算法,在時間序列中解決了傳統r n n算法梯度消失問題的的它這一次還會有令人傑出的表現嗎?
長短期記憶(Long Short-Term Memory) 是具有長期記憶能力的一種時間遞歸神經網絡(Recurrent Neural Network)。 其網絡結構含有一個或多個具有可遺忘和記憶功能的單元組成。它在1997年被提出用於解決傳統RNN(Recurrent Neural Network) 的隨時間反向傳播中權重消失的問題(vanishing gradient problem over backpropagation-through-time),重要組成部分包括Forget Gate, Input Gate, 和 Output Gate, 分別負責決定當前輸入是否被采納,是否被長期記憶以及決定在記憶中的輸入是否在當前被輸出。Gated Recurrent Unit 是 LSTM 眾多版本中典型的一個。因為它具有記憶性的功能,LSTM經常被用在具有時間序列特性的數據和場景中。
LSTM 算法廣泛應用於序列預測問題中,並被證明是一種非常有效的方法。它們之所表現如此出色,是因為LSTM能夠存儲重要的既往信息,並忽略不重要的信息。
LSTM有三個門:
-
輸入門:輸入門將信息添加到細胞狀態
-
遺忘門:它移除模型不再需要的信息
-
輸出門:LSTM的輸出門選擇作為輸出的信息
要更詳細地了解LSTM及其體系結構,可以閱讀下面的文章:
-
長短期記憶網絡簡介
現在,讓我們將LSTM實現為一個黑盒,並檢查它在特定數據上的性能。
實現
#importing required libraries 導入必要的庫函數
from sklearn.preprocessing import MinMaxScaler
from keras.models import Sequential
from keras.layers import Dense, Dropout, LSTM
#creating dataframe 搭建p d的數據框架,利用循環填充框架的內容
data = df.sort_index(ascending=True, axis=0)
new_data = pd.DataFrame(index=range(0,len(df)),columns=['Date', 'Close'])
for i in range(0,len(data)):
new_data['Date'][i] = data['Date'][i]
new_data['Close'][i] = data['Close'][i]
#setting index 設定數據的索引,刨除date列
new_data.index = new_data.Date
new_data.drop('Date', axis=1, inplace=True)
#creating train and test sets 划分訓練集測試集
dataset = new_data.values
train = dataset[0:987,:]
valid = dataset[987:,:]
#converting dataset into x_train and y_train 將兩個數據集歸一化處理
scaler = MinMaxScaler(feature_range=(0, 1))
#總數據集歸一化
scaled_data = scaler.fit_transform(dataset)
#確定正式訓練集測試集,大小是在剛剛划分的數據集合中,按60:1的比例划分,這里的划分不能算是k折交叉驗證,知道的朋友麻煩留言解答一下,感謝🙏
x_train, y_train = [], []
for i in range(60,len(train)):
x_train.append(scaled_data[i-60:i,0])
y_train.append(scaled_data[i,0])
#轉為numpy格式
x_train, y_train = np.array(x_train), np.array(y_train)
#重新改變矩陣的大小,這里如果不理解可以參考我的傳送門
x_train = np.reshape(x_train, (x_train.shape[0],x_train.shape[1],1))
# create and fit the LSTM network 建立模型
model = Sequential()
model.add(LSTM(units=50, return_sequences=True, input_shape=(x_train.shape[1],1)))
model.add(LSTM(units=50))
model.add(Dense(1))
#編譯模型,並給模型喂數據
model.compile(loss='mean_squared_error', optimizer='adam')
model.fit(x_train, y_train, epochs=1, batch_size=1, verbose=2)
#predicting 246 values, using past 60 from the train data 用測試集最后的60個數據
inputs = new_data[len(new_data) - len(valid) - 60:].values
inputs = inputs.reshape(-1,1)
inputs = scaler.transform(inputs)
#取最終的測試集
X_test = []
for i in range(60,inputs.shape[0]):
X_test.append(inputs[i-60:i,0])
X_test = np.array(X_test)
#調整矩陣的規模
X_test = np.reshape(X_test, (X_test.shape[0],X_test.shape[1],1))
#模型預測
closing_price = model.predict(X_test)
closing_price = scaler.inverse_transform(closing_price)
#計算rms
rms=np.sqrt(np.mean(np.power((valid-closing_price),2)))
rms
11.772259608962642
#for plotting 繪畫結果
train = new_data[:987]
valid = new_data[987:]
valid['Predictions'] = closing_price
plt.plot(train['Close'])
plt.plot(valid[['Close','Predictions']])
推論
LSTM輕松地超越了我們目前看到的任何算法。
LSTM模型可以對各種參數進行調優,如改變LSTM層數、增加dropout值或增加訓練迭代輪數(epoch)數。
但LSTM的預測是否足以確定股票價格將上漲還是下跌?當然不行!
正如我在文章開頭提到的,股價受到公司新聞和其他因素的影響,如公司的非貨幣化或合並/分拆。還有一些無形的因素往往是無法事先預測的。