苹果神经网络是什么意思
Stock price prediction is definitely not an easy task as there are many factors that need to be taken into consideration. Overall market conditions, competitors’ performance, new product releases, temper of global relations are just some key factors that have potential to increase or decrease stock prices. In addition to these, unexpected events may occur such as the corona virus situation we are currently experiencing.
股票价格预测绝对不是一件容易的事,因为有许多因素需要考虑。 总体市场状况,竞争对手的业绩,新产品发布,全球关系的缓和只是可能增加或降低股价的一些关键因素。 除此之外,还可能发生意外事件,例如我们目前正在经历的日冕病毒情况。
The factors we have listed up to now are hard to predict. Thus, we will put them aside throughout this post. One key factor that can be used to make prediction on stock prices is the historical prices. For instance, if a stock has been increasing steadily for two years, we might assume that it will keep going up for another month. However, stocks are not usually follow a simple continuous upward or downward trend. Thus, we need more complicated tools to make observations that are hard for us to catch.
我们到目前为止列出的因素很难预测。 因此,我们将在整个这篇文章中将它们放在一旁。 可以用来预测股票价格的一个关键因素是历史价格。 例如,如果股票连续两年稳定增长,我们可能会假设它会再持续一个月。 但是,库存通常不遵循简单的连续上升或下降趋势。 因此,我们需要更复杂的工具来进行难以捕捉的观察。
LSTM (Long Short Term Memory), which is a type of RNN (Recurrent Neural Network), can be used to predict stock prices using historical data. LSTM is suitable to model sequence data because it maintains an internal state to keep track of the data it has already seen. Common applications of LSTMs include time series analysis and natural language processing.
LSTM(长期短期记忆)是RNN(递归神经网络)的一种,可用于使用历史数据预测股票价格。 LSTM适用于对序列数据建模,因为它保持内部状态以跟踪已经看到的数据。 LSTM的常见应用包括时间序列分析和自然语言处理。
Let’s first obtain the data using pandas datareader module. It makes it very simple to get stock price data with a few lines of code.
我们首先使用pandas datareader模块获取数据。 使用几行代码,即可轻松获取股票价格数据。
import numpy as np
import pandas as pd
from pandas_datareader import dataaapl = data.DataReader("AAPL",
start='2015-1-1',
end='2019-12-31',
data_source='yahoo')
That’s all! We now have apple stock price data between 2015 and 2020 saved in a pandas dataframe.
就这样! 现在,我们已将2015年至2020年之间的苹果股票价格数据保存在熊猫数据框中。
![Image for post](https://miro.medium.com/max/9999/1*cm1T_edlsNJU1GUCrtIwSQ.png)
We will use the adjusted close (Adj Close) price. Let’s take a look at the general trend from 2015 to 2020.
我们将使用调整后的收盘价。 让我们看一下2015年至2020年的总体趋势。
#import dataviz libraries
import matplotlib.pyplot as plt
import seaborn as sns
sns.set(style='darkgrid')
%matplotlib inline#Plot "Adj Close"
plt.figure(figsize=(12,8))
plt.title("APPLE Stock Prices", fontsize=15)
sns.lineplot(x=aapl.index, y='Adj Close', data=aapl)
![Image for post](https://miro.medium.com/max/9999/1*t3XjrzEw8yOAJ0gmpz2RYw.png)
2015 does not seem to be a profitable year which followed by a stable upward trend for almost 3 years. We observe a sharp decrease at the end of 2019 which followed by a steady increase for about a year.
2015年似乎并不是一个有利可图的年份,紧随其后的是近3年的稳定增长趋势。 我们观察到2019年底急剧下降,随后稳定增长了大约一年。
What we will try to do with LSTM layers is to predict the price at time t using the historical prices of past 90 days (i.e. from t-90 to t-1). Please keep in mind that we will try to capture the trend, not exact prices.
我们将尝试对LSTM图层进行的操作是使用过去90天(即从t-90到t-1)的历史价格来预测时间t处的价格。 请记住,我们将尝试捕捉趋势,而不是确切的价格。
LSTM requires the input to be a 3D tensor with shape (batch_size, timesteps, input_dim).
LSTM要求输入为具有形状(batch_size,timesteps,input_dim)的3D张量。
Since we are using historical data of 90 days (t-90 to t-1) to make prediction at time t, the number of timesteps is 90. We only use “Adj Close” price to make the prediction so the input_dim is 1. Input_dim can be increase by adding additional features. For example, the value of a competitors stock price may have an effect on Apple stock price. If we also use a second variable to make the prediction, than the input_dim will be 2. The batch_size is the number of observations to be feed into LSTM layers before updating the weights.
由于我们使用90天的历史数据(t-90到t-1)在时间t进行预测,因此时间步数为90。我们仅使用“ 平仓价 ”进行预测,因此input_dim为1。可以通过添加其他功能来增加Input_dim。 例如,竞争对手股票价格的价值可能会影响苹果股票价格。 如果我们还使用了第二可变以使预测,比input_dim将2. 的batch_size是更新权重之前被送入LSTM层观测值的数目。
数据预处理 (Data Preprocessing)
We need to format the data in a way that each input contains stock prices of a 90-day period (t-90 to t-1) and the target is the price at time t. We can use a basic for loop as follows:
我们需要格式化数据,以便每个输入都包含90天时间段(t-90到t-1)的股票价格,目标是时间t的价格。 我们可以使用以下基本的for循环:
hist = []
target = []
length = 90adj_close = aapl['Adj Close']for i in range(len(adj_close) - length):
x = adj_close[i:i+length]
y = adj_close[i+length]
hist.append(x)
target.append(y)
Each element of “hist” is a list of 90 items. Since we increment by one, the last item of the second element of “hist” must be equal to the first element of “target”. Let’s confirm:
“历史”的每个元素都是90个项目的列表。 由于我们增加一个,因此“ hist”的第二个元素的最后一项必须等于“ target”的第一个元素。 让我们确认一下:
hist[1][89] == target[0]
True
“Hist” and “target” are lists. We need to convert them to numpy arrays and reshape the target variable to a 2-dimensional array.
“历史”和“目标”是列表。 我们需要将它们转换为numpy数组,并将目标变量重塑为二维数组。
hist = np.array(hist)
target = np.array(target)
target = target.reshape(-1,1)print(hist.shape)
print(target.shape)(1168, 90)
(1168, 1)
It is also better to normalize the values due to excessive computations done in a neural network. Normalization can be done with a few simple mathematical operations or pre-defined functions of libraries can be used. I will use MinMaxScaler of scikit-learn. By default, it normalizes values into a range of [0,1].
由于在神经网络中进行了过多的计算,因此最好对这些值进行归一化。 可以通过一些简单的数学运算来完成标准化,也可以使用库的预定义函数。 我将使用scikit-learn的MinMaxScaler 。 默认情况下,它将值标准化为[0,1]。
We are working on a supervised learning task. We will train the model with some data and test its performance using previously unseen data. Thus, we need to split the data into training and test sets. To get accurate performance results, the model should not have any clue about the data in test set. We should keep that in mind when normalizing the data as well. We need to split the data first. Then apply normalization separately.
我们正在监督学习任务。 我们将使用一些数据训练模型,并使用以前看不见的数据测试其性能。 因此,我们需要将数据分为训练集和测试集。 为了获得准确的性能结果,模型不应包含有关测试集中数据的任何线索。 在对数据进行规范化时,我们也应牢记这一点。 我们需要先拆分数据。 然后分别应用归一化。
#train/test splitX_train = hist[:1138]
X_test = hist[1138:]y_train = target[:1138]
y_test = target[1138:]
We split the data in a way that the model is trained with the data of 1138 days and tested on the data of the following 30 days.
我们以一种方式对数据进行拆分,即使用1138天的数据训练模型并在接下来的30天的数据上进行测试。
We can now do the normalization. We will first create a MinMaxScaler object and apply fit_transform method on training set. Then, we will only apply transform method on test set. It is very important to make this separation. Otherwise, we would be leaking information to the model from test set.
我们现在可以进行归一化。 我们将首先创建一个MinMaxScaler对象,并将fit_transform方法应用于训练集。 然后,我们将仅对测试集应用变换方法。 进行此分离非常重要。 否则,我们会将信息从测试集中泄漏到模型中。
from sklearn.preprocessing import MinMaxScaler
sc = MinMaxScaler()#train set, fit_transform
X_train_scaled = sc.fit_transform(X_train)
y_train_scaled = sc.fit_transform(y_train)#test set, only transform
X_test_scaled = sc.transform(X_test)
y_test_scaled = sc.transform(y_test)
Last step of data preprocessing is to convert inputs to 3-D arrays because LSTM accepts 3-D arrays as input.
数据预处理的最后一步是将输入转换为3-D数组,因为LSTM接受3-D数组作为输入。
X_train_scaled = X_train_scaled.reshape((len(X_train_scaled), length, 1))X_test_scaled = X_test_scaled.reshape((len(X_test_scaled), length, 1))
模型 (Model)
We will implement the neural network using LSTM layes of Keras which is a high-level API of TensorFlow.
我们将使用Keras的LSTM布局来实现神经网络,这是TensorFlow的高级API。
import tensorflow as tf
from tensorflow.keras import layers
We will create a sequential model with 4 LSTM layers and a dense layer.
我们将创建一个具有4个LSTM层和一个密集层的顺序模型。
model = tf.keras.Sequential()model.add(layers.LSTM(units=64, return_sequences=True, input_shape=(90,1), dropout=0.2))model.add(layers.LSTM(units=32, return_sequences=True, dropout=0.2))model.add(layers.LSTM(units=32, return_sequences=True, dropout=0.2))model.add(layers.LSTM(units=16, dropout=0.2))model.add(layers.Dense(units=1))model.summary()
![Image for post](https://miro.medium.com/max/9999/1*gEfcMk8TVu_PTDjSmYvWqg.png)
There are some important points to keep in mind:
有几点要牢记:
If an LSTM layer is followed by another LSTM layer, return_sequences parameter must be set as True.
如果一个LSTM层后面是另一个LSTM层,则必须将return_sequences参数设置为True。
Input_shape parameter needs to specified only for first LSTM layer. For other layers, model figure out the input from the output of the previous layer.
仅需要为第一个LSTM层指定Input_shape参数。 对于其他层,模型会从上一层的输出中找出输入。
Input_shape parameter is a tuple that contains timesteps and input_dim. Batch_size is specified during training.
Input_shape参数是一个包含时间步长和input_dim的元组。 在训练期间指定Batch_size。
Units parameter is the number of nodes used in a layer. There is not a strict rule to define optimum number of nodes.
单位参数是一个图层中使用的节点数。 没有定义最佳节点数的严格规则。
Dropout is used to prevent the model from overfitting.
辍学用于防止模型过度拟合。
- Units of dense layer should be 1 since it is used as the output layer. 密集层的单位应为1,因为它用作输出层。
We can now compile the model by specifying an optimizer and a loss function.
现在,我们可以通过指定优化器和损失函数来编译模型。
model.compile(optimizer='adam', loss='mean_squared_error')
Then, we train the model.
然后,我们训练模型。
history = model.fit(X_train_scaled, y_train_scaled,
epochs=30, batch_size=16)
We already discussed the batch_size. Epochs indicates how many times the entire dataset is fed into the neural network.
我们已经讨论了batch_size。 历元表示将整个数据集馈入神经网络的次数。
![Image for post](https://miro.medium.com/max/9999/1*KqPQL8r7vBQ6ZU3JzIXlbg.png)
You see the number 72 at each epoch. It comes from number of training points divided by the batch size. X_train_scaled has 1138 data points. The batch size is 16. 1138/15=71.125 so it is completed in 72 cycles.
您将在每个时期看到数字72。 它来自训练点数除以批次大小。 X_train_scaled具有1138个数据点。 批处理大小为16。1138/15 = 71.125,因此在72个周期内完成。
The model achieved a MSE of 0.0017. Let’s see how it has changed through 30 epochs.
该模型的MSE为0.0017。 让我们看看它在30个纪元内是如何变化的。
loss = history.history['loss']
epoch_count = range(1, len(loss) + 1)plt.figure(figsize=(12,8))
plt.plot(epoch_count, loss, 'r--')
plt.legend(['Training Loss'])
plt.xlabel('Epoch')
plt.ylabel('Loss')
plt.show();
![Image for post](https://miro.medium.com/max/9999/1*OCMXsbe5cYbxEiqwJuhWMg.png)
The loss has followed a downward trend and reached below 0.002 after epoch 25. However, the model has not converged yet. It seems like loss will keep decreasing if we do more epochs. Let’s try to 50 epochs.
损失遵循下降趋势,在第25个时期后达到0.002以下。但是,该模型尚未收敛。 如果我们进行更多的尝试,损失似乎将继续减少。 让我们尝试50个纪元。
![Image for post](https://i-blog.csdnimg.cn/blog_migrate/acf616dbfd76002390bb5cdabc460b50.png)
Now the loss is below 0.001. Please note that it is not always best practice to keep reducing the loss. After some point, we may end up having an overfit model which focus on training set too much rather than generalizing well.
现在损失低于0.001。 请注意,减少损失并非总是最佳实践。 在某一点之后,我们可能最终会得到一个过拟合模型,该模型过于关注训练集而不是很好地概括。
It is time to make predictions. We will try to predict the trend of stock price on the following 30 day period. Remember our goal is to predict the trend, not the actual prices.
现在该做出预测了。 我们将尝试预测接下来30天的股价趋势。 请记住,我们的目标是预测趋势,而不是实际价格。
pred = model.predict(X_test_scaled)
pred_transformed = sc.inverse_transform(pred)y_test_transformed = sc.inverse_transform(y_test_scaled)plt.figure(figsize=(12,8))
plt.plot(y_test_transformed, color='blue', label='Real')
plt.plot(pred_transformed, color='red', label='Prediction')
plt.title('Apple Stock Price Prediction')
plt.legend()
plt.show()
![Image for post](https://miro.medium.com/max/9999/1*xHP06okBDD-pvKLT_Xc14w.png)
Although the values do not precisely match, we are able to predict the general trend in a 30-day period. The model responded to decrease between days 7 and 10 a few days late. Then it catched up the upward trend.
尽管这些值不完全匹配,但我们可以预测30天的总体趋势。 该模型在几天后的第7天到第10天之间响应减少。 然后,它赶上了上升趋势。
There are many ways to try to improve the performance of this model. You can achieve a better result by adjusting:
有很多方法可以尝试改善此模型的性能。 您可以通过调整以下内容来获得更好的结果:
- Number of layers 层数
- Number of nodes in a layer 层中的节点数
- Number of timesteps 时间步数
- Dropout ratio 辍学率
- Number of epochs 纪元数
- Batch size 批量大小
Thank you for reading. Please let me know if you have any feedback.
感谢您的阅读。 如果您有任何反馈意见,请告诉我。
翻译自: https://towardsdatascience.com/predicting-apple-stock-prices-with-neural-networks-4aefdf10afd0
苹果神经网络是什么意思