在本文中,我將向您展示如何使用稱(chēng)為長(cháng)短期記憶(LSTM)的機器學(xué)習技術(shù)編寫(xiě)一個(gè)預測股票價(jià)格的python程序。這個(gè)程序真的很簡(jiǎn)單,這個(gè)程序會(huì )帶來(lái)一些重大收益,總之是比猜測的要好!請記住,股價(jià)可能受許多不同因素的影響。這里所做的預測僅僅是預測而已。
長(cháng)短期記憶(LSTM)是在深度學(xué)習領(lǐng)域中使用的循環(huán)神經(jīng)網(wǎng)絡(luò )(RNN)架構。與標準前饋神經(jīng)網(wǎng)絡(luò )不同,LSTM具有反饋連接。它不僅可以處理單個(gè)數據點(diǎn)(例如圖像),而且可以處理整個(gè)數據序列(例如語(yǔ)音或視頻)。
LSTM被廣泛用于序列預測問(wèn)題,并被證明是非常有效的。之所以如此有效,是因為L(cháng)STM能夠存儲重要的過(guò)去信息,而忘記了不重要的信息。
LSTM的通用體系結構:
Forget Gate
Input Gate
Output Gate
我將首先說(shuō)明我希望該程序執行的操作。我希望該程序根據當前的收盤(pán)價(jià)來(lái)預測蘋(píng)果公司股票未來(lái)60天的價(jià)格。
首先,我將在程序編寫(xiě)的開(kāi)頭中注入對該程序進(jìn)行描述。
接下來(lái),我將導入將在整個(gè)程序中使用的庫。
#Import the librariesimport mathimport pandas_datareader as webimport numpy as npimport pandas as pdfrom sklearn.preprocessing import MinMaxScalerfrom keras.models import Sequentialfrom keras.layers import Dense, LSTMimport matplotlib.pyplot as pltplt.style.use('fivethirtyeight')我將從2012年1月1日到2019年12月20日,通過(guò)股票行情公司獲得“Apple Inc.”的股票報價(jià)(AAPL)。
#Get the stock quote df = web.DataReader('AAPL', data_source='yahoo', start='2012-01-01', end='2019-12-20') #Show the data df蘋(píng)果股票行情
我們可以在最后一行看見(jiàn)顯示了數據集中的行數和列數。我們記錄了2006天的股票價(jià)格和6列股票的分類(lèi)。
創(chuàng )建一個(gè)圖表以可視化數據。
plt.figure(figsize=(16,8))plt.title('Close Price History')plt.plot(df['Close'])plt.xlabel('Date',fontsize=18)plt.ylabel('Close Price USD ($)',fontsize=18)plt.show()該圖顯示了蘋(píng)果公司的收盤(pán)價(jià)歷史。
創(chuàng )建一個(gè)僅包含收盤(pán)價(jià)的新數據框,并將其轉換為數組。
然后創(chuàng )建一個(gè)變量以存儲訓練數據集的長(cháng)度。我希望訓練數據集包含大約80%的數據。
#Create a new dataframe with only the 'Close' columndata = df.filter(['Close'])#Converting the dataframe to a numpy arraydataset = data.values#Get /Compute the number of rows to train the model ontraining_data_len = math.ceil( len(dataset) *.8) 現在將數據集縮放為0和1之間(含0和1)的值,我這樣做是因為在將其提供給神經(jīng)網(wǎng)絡(luò )之前通常將數據縮放是一種很好的做法。
#Scale the all of the data to be values between 0 and 1 scaler = MinMaxScaler(feature_range=(0, 1)) scaled_data = scaler.fit_transform(dataset)創(chuàng )建一個(gè)包含過(guò)去60天收盤(pán)價(jià)的訓練數據集,我們希望使用它來(lái)預測第61個(gè)收盤(pán)價(jià)。
因此,“ x_train ”數據集中的第一列將包含從索引0到索引59(總共60個(gè)值)的數據集中的值,第二列將包含從索引1到索引60的數據集的值(60個(gè)值)以此類(lèi)推。
“ y_train ”數據集將包含第一個(gè)列在索引60處的第61個(gè)值,第二個(gè)列在索引61處的第62個(gè)值,以此類(lèi)推。
#Create the scaled training data settrain_data = scaled_data[0:training_data_len , : ]#Split the data into x_train and y_train data setsx_train=[]y_train = []for i in range(60,len(train_data)): x_train.append(train_data[i-60:i,0]) y_train.append(train_data[i,0])現在將獨立的訓練數據集“ x_train ”和從屬的訓練數據集“ y_train ”轉換為numpy數組,以便將它們用于訓練LSTM模型。
#Convert x_train and y_train to numpy arraysx_train, y_train = np.array(x_train), np.array(y_train)將數據重構為3維格式,形式為[ 樣本數量、時(shí)間步長(cháng)、特征數量]。LSTM模型期望使用3維數據集。
#Reshape the data into the shape accepted by the LSTMx_train = np.reshape(x_train, (x_train.shape[0],x_train.shape[1],1))建立LSTM模型,使其具有兩個(gè)包含50個(gè)神經(jīng)元的LSTM層和兩個(gè)密集層,一個(gè)包含25個(gè)神經(jīng)元,另一個(gè)包含1個(gè)神經(jīng)元。
#Build the LSTM network modelmodel = Sequential()model.add(LSTM(units=50, return_sequences=True,input_shape=(x_train.shape[1],1)))model.add(LSTM(units=50, return_sequences=False))model.add(Dense(units=25))model.add(Dense(units=1))使用均方誤差(MSE)損失函數和adam優(yōu)化器編譯模型。
#Compile the modelmodel.compile(optimizer='adam', loss='mean_squared_error')使用訓練數據集訓練模型。注意,fit是train的另一個(gè)名字。Batch_size是單個(gè)批處理中存在的訓練示例的總數,epoch是整個(gè)數據集通過(guò)神經(jīng)網(wǎng)絡(luò )向前和向后傳遞時(shí)的迭代次數。
#Train the modelmodel.fit(x_train, y_train, batch_size=1, epochs=1)創(chuàng )建一個(gè)測試數據集。
#Test data settest_data = scaled_data[training_data_len - 60: , : ]#Create the x_test and y_test data setsx_test = []y_test = dataset[training_data_len : , : ] #Get all of the rows from index 1603 to the rest and all of the columns (in this case it's only column 'Close'), so 2003 - 1603 = 400 rows of datafor i in range(60,len(test_data)): x_test.append(test_data[i-60:i,0])然后將獨立的測試數據集“ x_test ”轉換為numpy數組,以便可以將其用于測試LSTM模型。
#Convert x_test to a numpy array x_test = np.array(x_test)將數據重構為3維格式,形式為[ 樣本數量、時(shí)間步長(cháng)、特征數量]。這需要完成,因為L(cháng)STM模型需要一個(gè)3維數據集。
#Reshape the data into the shape accepted by the LSTMx_test = np.reshape(x_test, (x_test.shape[0],x_test.shape[1],1))現在,使用測試數據從模型中獲得預測值。
#Getting the models predicted price valuespredictions = model.predict(x_test) predictions = scaler.inverse_transform(predictions)#Undo scaling獲取均方根誤差(RMSE),這是衡量模型準確性的一個(gè)很好的方法。值為0表示模型預測值與測試數據集中的實(shí)際值完全匹配。
值越低,模型執行的越好。但是通常最好也使用其他指標來(lái)真正了解模型的執行情況。
#Calculate/Get the value of RMSErmse=np.sqrt(np.mean((predictions- y_test)**2))rmse6.70350807645975---RMSE值讓我們繪制和可視化數據。
#Plot/Create the data for the graphtrain = data[:training_data_len]valid = data[training_data_len:]valid['Predictions'] = predictions#Visualize the dataplt.figure(figsize=(16,8))plt.title('Model')plt.xlabel('Date', fontsize=18)plt.ylabel('Close Price USD ($)', fontsize=18)plt.plot(train['Close'])plt.plot(valid[['Close', 'Predictions']])plt.legend(['Train', 'Val', 'Predictions'], loc='lower right')plt.show()顯示訓練(藍色),實(shí)際(紅色)和預測(黃色)價(jià)格的圖表。
顯示實(shí)際和預測的價(jià)格。
#Show the valid and predicted pricesvalid實(shí)際(收盤(pán)價(jià))和預測價(jià)格的值。
我想進(jìn)一步測試模型,以獲取Apple Inc.在2019年12月23日的預計收盤(pán)價(jià)。
因此,我將獲得報價(jià),將數據轉換為僅包含收盤(pán)價(jià)的數組。然后,我將獲得最近60天的收盤(pán)價(jià),并將數據縮放為介于0和1之間(含0和1)的值。
之后,我將創(chuàng )建一個(gè)空列表并將過(guò)去60天的價(jià)格附加到該列表中,然后將其轉換為numpy數組并重塑形狀,以便可以將數據輸入到模型中。
最后,我將數據輸入模型,得到預測的價(jià)格。
#Get the quoteapple_quote = web.DataReader('AAPL', data_source='yahoo', start='2012-01-01', end='2019-12-20')#Create a new dataframenew_df = apple_quote.filter(['Close'])#Get teh last 60 day closing price last_60_days = new_df[-60:].values#Scale the data to be values between 0 and 1last_60_days_scaled = scaler.transform(last_60_days)#Create an empty listX_test = []#Append teh past 60 daysX_test.append(last_60_days_scaled)#Convert the X_test data set to a numpy arrayX_test = np.array(X_test)#Reshape the dataX_test = np.reshape(X_test, (X_test.shape[0], X_test.shape[1], 1))#Get the predicted scaled pricepred_price = model.predict(X_test)#undo the scaling pred_price = scaler.inverse_transform(pred_price)print(pred_price)[[269.60187]]----2019/12/23的預測價(jià)格現在,讓我們看看當天的實(shí)際價(jià)格是多少。
#Get the quoteapple_quote2 = web.DataReader('AAPL', data_source='yahoo', start='2019-12-23', end='2019-12-24')print(apple_quote2['Close'])2019年12月23日的實(shí)際價(jià)格
本文我們使用LSTM來(lái)預測蘋(píng)果公司的股票價(jià)格,由于我們的均方根誤差值過(guò)大,影響了我們最后的預測,不過(guò)這個(gè)并不是很重要,我們不僅需要一個(gè)模型來(lái)預測,有時(shí)我們可能會(huì )需要使用很多的模型來(lái)預測同一個(gè)問(wèn)題,這樣子可以?xún)?yōu)選出更好的模型,來(lái)為我們服務(wù)。
聯(lián)系客服