在本文中,我将向您展示如何使用称为长短期记忆(LSTM)的机器学习技术编写一个预测股票价格的python程序。这个程序真的很简单,这个程序会带来一些重大收益,总之是比猜测的要好!请记住,股价可能受许多不同因素的影响。这里所做的预测仅仅是预测而已。
长短期记忆(LSTM)是在深度学习领域中使用的循环神经网络(RNN)架构。与标准前馈神经网络不同,LSTM具有反馈连接。它不仅可以处理单个数据点(例如图像),而且可以处理整个数据序列(例如语音或视频)。
LSTM被广泛用于序列预测问题,并被证明是非常有效的。之所以如此有效,是因为LSTM能够存储重要的过去信息,而忘记了不重要的信息。
LSTM的通用体系结构:
Forget Gate
Input Gate
Output Gate
我将首先说明我希望该程序执行的操作。我希望该程序根据当前的收盘价来预测苹果公司股票未来60天的价格。
首先,我将在程序编写的开头中注入对该程序进行描述。
接下来,我将导入将在整个程序中使用的库。
#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日,通过股票行情公司获得“Apple Inc.”的股票报价(AAPL)。
#Get the stock quote df = web.DataReader('AAPL', data_source='yahoo', start='2012-01-01', end='2019-12-20') #Show the data df
苹果股票行情
我们可以在最后一行看见显示了数据集中的行数和列数。我们记录了2006天的股票价格和6列股票的分类。
创建一个图表以可视化数据。
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()
该图显示了苹果公司的收盘价历史。
创建一个仅包含收盘价的新数据框,并将其转换为数组。
然后创建一个变量以存储训练数据集的长度。我希望训练数据集包含大约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)的值,我这样做是因为在将其提供给神经网络之前通常将数据缩放是一种很好的做法。
#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)
创建一个包含过去60天收盘价的训练数据集,我们希望使用它来预测第61个收盘价。
因此,“ x_train ”数据集中的第一列将包含从索引0到索引59(总共60个值)的数据集中的值,第二列将包含从索引1到索引60的数据集的值(60个值)以此类推。
“ y_train ”数据集将包含第一个列在索引60处的第61个值,第二个列在索引61处的第62个值,以此类推。
#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维格式,形式为[ 样本数量、时间步长、特征数量]。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模型,使其具有两个包含50个神经元的LSTM层和两个密集层,一个包含25个神经元,另一个包含1个神经元。
#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优化器编译模型。
#Compile the modelmodel.compile(optimizer='adam', loss='mean_squared_error')
使用训练数据集训练模型。注意,fit是train的另一个名字。Batch_size是单个批处理中存在的训练示例的总数,epoch是整个数据集通过神经网络向前和向后传递时的迭代次数。
#Train the modelmodel.fit(x_train, y_train, batch_size=1, epochs=1)
创建一个测试数据集。
#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维格式,形式为[ 样本数量、时间步长、特征数量]。这需要完成,因为LSTM模型需要一个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),这是衡量模型准确性的一个很好的方法。值为0表示模型预测值与测试数据集中的实际值完全匹配。
值越低,模型执行的越好。但是通常最好也使用其他指标来真正了解模型的执行情况。
#Calculate/Get the value of RMSErmse=np.sqrt(np.mean((predictions- y_test)**2))rmse
6.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()
显示训练(蓝色),实际(红色)和预测(黄色)价格的图表。
显示实际和预测的价格。
#Show the valid and predicted pricesvalid
实际(收盘价)和预测价格的值。
我想进一步测试模型,以获取Apple Inc.在2019年12月23日的预计收盘价。
因此,我将获得报价,将数据转换为仅包含收盘价的数组。然后,我将获得最近60天的收盘价,并将数据缩放为介于0和1之间(含0和1)的值。
之后,我将创建一个空列表并将过去60天的价格附加到该列表中,然后将其转换为numpy数组并重塑形状,以便可以将数据输入到模型中。
最后,我将数据输入模型,得到预测的价格。
#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的预测价格
现在,让我们看看当天的实际价格是多少。
#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日的实际价格
本文我们使用LSTM来预测苹果公司的股票价格,由于我们的均方根误差值过大,影响了我们最后的预测,不过这个并不是很重要,我们不仅需要一个模型来预测,有时我们可能会需要使用很多的模型来预测同一个问题,这样子可以优选出更好的模型,来为我们服务。
联系客服