作者 | Scatterday
来源 | Medium
编辑 | 代码医生团队
人工智能(AI)无处不在。机器学习和人工智能正在彻底改变现代问题的解决方式。应用机器学习的一种很酷的方法是使用财务数据。财务数据是机器学习的一个游乐场。
在这个项目中,使用带有sci-kit-learn的支持向量回归和使用Keras的LSTM来分析特斯拉的股票价格。
在使用LSTM和其他算法等技术分析财务数据时,请务必记住这些不是保证结果。股票市场令人难以置信的不可预测且迅速变化。这只是一个有趣的项目,可以学习使用神经网络进行库存分析的一些基本技术。
目录:
1.获取我们的数据:
2.可视化我们的数据:
3.支持向量回归:
4.深度学习:
5.结果:
进口:
import keras
from keras.layers import Dense
from keras.layers import LSTM
from keras.layers import Dropout
import pandas as pd
import pandas_datareader.data as web
import datetime
import numpy as np
from matplotlib import style
# ignore warnings
import warnings
warnings.filterwarnings('ignore')
在这里导入:
获取库存数据:
# Get the stock data using yahoo API:
style.use('ggplot')
# get 2014-2018 data to train our model
start = datetime.datetime(2014,1,1)
end = datetime.datetime(2018,12,30)
df = web.DataReader("TSLA", 'yahoo', start, end)
# get 2019 data to test our model on
start = datetime.datetime(2019,1,1)
end = datetime.date.today()
test_df = web.DataReader("TSLA", 'yahoo', start, end)
https://matplotlib.org/3.1.1/gallery/style_sheets/ggplot.html
修复数据:
# sort by date
df = df.sort_values('Date')
test_df = test_df.sort_values('Date')
# fix the date
df.reset_index(inplace=True)
df.set_index("Date", inplace=True)
test_df.reset_index(inplace=True)
test_df.set_index("Date", inplace=True)
df.tail()
绘制数据和滚动意味着:
# Visualize the training stock data:
import matplotlib.pyplot as plt
%matplotlib inline
plt.figure(figsize = (12,6))
plt.plot(df["Adj Close"])
plt.xlabel('Date',fontsize=15)
plt.ylabel('Adjusted Close Price',fontsize=15)
plt.show()
# Rolling mean
close_px = df['Adj Close']
mavg = close_px.rolling(window=100).mean()
plt.figure(figsize = (12,6))
close_px.plot(label='TSLA')
mavg.plot(label='mavg')
plt.xlabel('Date')
plt.ylabel('Price')
plt.legend()
2014-2018特斯拉关闭股票价格
滚动平均值绘制在数据上
数学:
转换日期:
import matplotlib.dates as mdates
# change the dates into ints for training
dates_df = df.copy()
dates_df = dates_df.reset_index()
# Store the original dates for plotting the predicitons
org_dates = dates_df['Date']
# convert to ints
dates_df['Date'] = dates_df['Date'].map(mdates.date2num)
dates_df.tail()
线性回归
支持向量机:
支持向量回归演练:
使用sklearn和可视化内核的SVR代码:
# Use sklearn support vector regression to predicit our data:
from sklearn.svm import SVR
dates = dates_df['Date'].as_matrix()
prices = df['Adj Close'].as_matrix()
#Convert to 1d Vector
dates = np.reshape(dates, (len(dates), 1))
prices = np.reshape(prices, (len(prices), 1))
svr_rbf = SVR(kernel= 'rbf', C= 1e3, gamma= 0.1)
svr_rbf.fit(dates, prices)
plt.figure(figsize = (12,6))
plt.plot(dates, prices, color= 'black', label= 'Data')
plt.plot(org_dates, svr_rbf.predict(dates), color= 'red', label= 'RBF model')
plt.xlabel('Date')
plt.ylabel('Price')
plt.legend()
plt.show()
SVR适合数据
内核函数的Gif
规范数据:
# Create train set of adj close prices data:
train_data = df.loc[:,'Adj Close'].as_matrix()
print(train_data.shape) # 1258
# Apply normalization before feeding to LSTM using sklearn:
from sklearn.preprocessing import MinMaxScaler
scaler = MinMaxScaler()
train_data = train_data.reshape(-1,1)
scaler.fit(train_data)
train_data = scaler.transform(train_data)
为神经网络准备数据:
'''Function to create a dataset to feed into an LSTM'''
def create_dataset(dataset, look_back):
dataX, dataY = [], []
for i in range(len(dataset)-look_back):
a = dataset[i:(i + look_back), 0]
dataX.append(a)
dataY.append(dataset[i + look_back, 0])
return np.array(dataX), np.array(dataY)
# Create the data to train our model on:
time_steps = 36
X_train, y_train = create_dataset(train_data, time_steps)
# reshape it [samples, time steps, features]
X_train = np.reshape(X_train, (X_train.shape[0], 36, 1))
print(X_train.shape)
# Visualizing our data with prints:
print('X_train:')
print(str(scaler.inverse_transform(X_train[0])))
print("\n")
print('y_train: ' + str(scaler.inverse_transform(y_train[0].reshape(-1,1)))+'\n')
X_train:
[[150.1000061 ]
[149.55999756]
[147. ]
[149.36000061]
[151.27999878]
[147.52999878]
[145.72000122]
[139.33999634]
[161.27000427]
[164.13000488]
[170.97000122]
[170.00999451]
[176.67999268]
[178.55999756]
[181.5 ]
[174.6000061 ]
[169.61999512]
[178.38000488]
[175.22999573]
[182.83999634]
[181.41000366]
[177.11000061]
[178.72999573]
[174.41999817]
[178.38000488]
[186.52999878]
[196.55999756]
[196.61999512]
[195.32000732]
[199.63000488]
[198.22999573]
[203.69999695]
[193.63999939]
[209.97000122]
[209.6000061 ]
[217.6499939 ]]
y_train: [[248.]]
递归神经网络:
LSTM演练:
LSTM是一种在每个LSTM小区内部具有门的RNN。喜欢将LSTM细胞视为一个细胞,每个细胞内部都有自己的微小神经网络。LSTM单元内的这些门有助于LSTM决定记住哪些数据是重要的,甚至在长序列数据中也可以忘记哪些数据。门的类型是遗忘门,输入门和输出门。下面是这个视频中这些LSTM细胞外观的惊人可视化。这部分受到本视频和本文的严重影响,因为这些解释非常棒:
https://colah.github.io/posts/2015-08-Understanding-LSTMs/
所以LSTM就像RNN一样顺序。先前的单元输出作为输入传递给下一个单元。让分解一下LSTM单元内的每个门正在做什么:
盖茨包含sigmoid激活函数。S形激活函数可以被认为是“挤压”函数。它接受数字输入并将数字调整到0到1的范围内。这很重要,因为它允许我们避免网络中的数字变得庞大并导致学习错误。
遗忘门:
遗忘门从先前的LSTM单元和当前输入获取先前的隐藏状态并将它们相乘。接近0的值意味着忘记数据,而接近1的值意味着保留此数据。
遗忘门是遗忘门权重矩阵乘以先前的隐藏状态,然后输入状态+一些偏差全部传递到sigmoid激活函数。计算完成后,将其传递给单元状态。
输入门:
此门使用要在单元状态中存储的新数据更新单元状态。输入门将先前的隐藏状态乘以输入并将其传递给sigmoid。接近0的值并不重要,接近1的值很重要。然后将前一个隐藏状态乘以输入并传递给tan激活函数,该函数将值调整到-1到1的范围内。然后,将sigmoid输出乘以tan输出。sigmoid输出决定哪些信息对于保持tan输出很重要。
细胞状态:
网络记忆。这可以被认为是一种“信息高速公路”,它将来自先前细胞的记忆带到未来的细胞上。门进入单元状态,然后将该信息传递给下一个单元。一旦计算了遗忘门和输入门,我们就可以计算出单元状态的值。
单元状态是遗忘门输出*前一个单元状态+输入门输出*从前一个单元传递的单元状态值。这是为了丢弃想要忘记的接近零的某些值。然后将输入门的值添加到我们想要传递给下一个单元的单元状态值。
输出门:
输出门决定下一个隐藏状态应该是什么。将先前的隐藏状态乘以输入并传递到sigmoid激活函数。然后将单元状态值传递给tan激活函数。然后,将tan输出乘以sigmoid输出,以确定隐藏状态应该携带到下一个LSTM单元的数据。
退出:
模型的代码:
# Build the model
model = keras.Sequential()
model.add(LSTM(units = 100, return_sequences = True, input_shape = (X_train.shape[1], 1)))
model.add(Dropout(0.2))
model.add(LSTM(units = 100))
model.add(Dropout(0.2))
# Output layer
model.add(Dense(units = 1))
# Compiling the model
model.compile(optimizer = 'adam', loss = 'mean_squared_error')
# Fitting the model to the Training set
history = model.fit(X_train, y_train, epochs = 20, batch_size = 10, validation_split=.30)
绘制模型损失:
# Plot training & validation loss values
plt.plot(history.history['loss'])
plt.plot(history.history['val_loss'])
plt.title('Model loss')
plt.ylabel('Loss')
plt.xlabel('Epoch')
plt.legend(['Train', 'Test'], loc='upper left')
plt.show()
在这里,使用keras api中的代码来绘制模型损失。当到达第20个时代时,测试损失和火车损失非常接近并且它们被最小化。
做出预测:
# Get the stock prices for 2019 to have our model make the predictions
test_data = test_df['Adj Close'].values
test_data = test_data.reshape(-1,1)
test_data = scaler.transform(test_data)
# Create the data to test our model on:
time_steps = 36
X_test, y_test = create_dataset(test_data, time_steps)
# store the original vals for plotting the predictions
y_test = y_test.reshape(-1,1)
org_y = scaler.inverse_transform(y_test)
# reshape it [samples, time steps, features]
X_test = np.reshape(X_test, (X_test.shape[0], 36, 1))
# Predict the prices with the model
predicted_y = model.predict(X_test)
predicted_y = scaler.inverse_transform(predicted_y)
# plot the results
plt.plot(org_y, color = 'red', label = 'Real Tesla Stock Price')
plt.plot(predicted_y, color = 'blue', label = 'Predicted Tesla Stock Price')
plt.title('Tesla Stock Price Prediction')
plt.xlabel('Time')
plt.ylabel('Tesla Stock Price')
plt.legend()
plt.show()
LSTM预测结果
结论:
https://github.com/DrewScatterday
资源:
推荐阅读