预测股市将如何变化历来是最困难的事情之一。这个预测行为中包含着如此之多的因素—包括物理或心理因素、理性或者不理性行为因素等等。所有这些因素结合在一起,使得股价波动剧烈,很难准确预测。
使用机器学习可能改变游戏规则吗?机器学习技术使用最新的组织公告、季度收益等作为特征,有潜力挖掘出我们以前没有见过的模式和见解,并可用于准确无误的预测。
在本文中,我们将研究上市公司股价的历史数据。我们将使用LSTM深度学习算法来预测这家公司的未来股价。
我们将很快深入本文的实现部分,但首先重要的是确定我们要解决的问题。一般来说,股票市场分析分为两个部分——基本面分析和技术分析。
基本面分析是根据公司目前的经营环境和财务状况,对公司未来的盈利能力进行分析。
技术分析包括阅读图表和使用统计数字来确定股票市场的趋势。
您可能已经猜到,我们的重点将放在技术分析部分。我们将使用来自Quandl的数据集(您可以在这里找到各种股票的历史数据),这个项目中,我使用了“塔塔全球饮料”的数据。
首先让我们加载数据集,定义问题的目标变量:
import pandas as pd import numpy as np import matplotlib.pyplot as plt # setting figure size from matplotlib.pylab import rcParams rcParams['figure.figsize'] = 20, 10 # for normalizing data from sklearn.preprocessing import MinMaxScaler scaler = MinMaxScaler(feature_range=(0, 1)) # read the file df = pd.read_csv('NSE-TATAGLOBAL.csv') # print the head df.head() print(df)数据集中有多个变量——日期(date)、开盘价(open)、最高价(high)、最低价(low)、最后交易价(last)、收盘价(close)、总交易额(total_trade_quantity)和营业额(turnover)。
开盘价和收盘价代表股票在某一天交易的起始价和最终价。最高价、最低价和最后交易价表示当天股票的最高价、最低价和最后交易价格。交易总量是指当天买卖的股票数量,而营业额(Lacs)是指某一特定公司在某一特定日期的营业额。要注意的另一点是,市场在周末和公共假期休市。注意上表缺失了一些日期值——2/10/2018、6/10/2018、7/10/2018。其中2号是国庆节,6号和7号是周末。
损益的计算通常由股票当日的收盘价决定,因此我们将收盘价作为目标变量。让我们画出目标变量来理解它在我们的数据集中的分布:
# setting index as date df['Date'] = pd.to_datetime(df.Date, format='%Y-%m-%d') df.index = df['Date'] # plot plt.figure(figsize=(16, 8)) plt.plot(df['Close'], label='Close Price history') plt.show()在接下来的部分中,我们将探索这些变量,并使用不同的技术来预测股票的每日收盘价。
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 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 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) 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]) 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 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 = np.sqrt(np.mean(np.power((valid - closing_price), 2))) print(rms) # for plotting train = new_data[:987] valid = new_data[987:] valid['Predictions'] = closing_price plt.plot(train['Close']) plt.plot(valid[['Close', 'Predictions']]) plt.show()99s - loss: 8.1449e-04 9.401323848367626
哇!LSTM轻松地超越了我们目前看到的任何算法。LSTM模型可以对各种参数进行调优,如改变LSTM层数、增加dropout值或增加训练迭代轮数(epoch)数。但LSTM的预测是否足以确定股票价格将上涨还是下跌?当然不行!
正如我在文章开头提到的,股价受到公司新闻和其他因素的影响,如公司的非货币化或合并/分拆。还有一些无形的因素往往是无法事先预测的。