2

TensorFlow深度学习!构建神经网络预测股票价格!⛵ - ShowMeAI

 1 year ago
source link: https://www.cnblogs.com/showmeai/p/16883882.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

TensorFlow深度学习!构建神经网络预测股票价格!⛵

a6660fb917d385b447a50402ceac5781.png

💡 作者:韩信子@ShowMeAI
📘 深度学习实战系列https://www.showmeai.tech/tutorials/42
📘 TensorFlow 实战系列https://www.showmeai.tech/tutorials/43
📘 本文地址https://www.showmeai.tech/article-detail/327
📢 声明:版权所有,转载请联系平台与作者并注明出处
📢 收藏ShowMeAI查看更多精彩内容

cf8c06ea187570c1b5331af6b7ca09aa.png

股票价格数据是一个时间序列形态的数据,诚然,股市的涨落和各种利好利空消息更相关,更多体现的是人们的信心状况,但是它的形态下,时序前后是有一定的相关性的,我们可以使用一种特殊类型的神经网络『循环神经网络 (RNN)』来对这种时序相关的数据进行建模和学习。

dde22f5191dc34a1b2371f097344d1cc.png

在本篇内容中,ShowMeAI将给大家演示,如何构建训练神经网络并将其应用在股票数据上进行预测。

4dfe016166b19ead4a98a79050603825.png

对于循环神经网络的详细信息讲解,大家可以阅读ShowMeAI整理的系列教程和文章详细了解:

💡 数据获取

在实际建模与训练之前,我们需要先获取股票数据。下面的代码使用 Ameritrade API 获取并生成数据,也可以使用其他来源。

import matplotlib.pyplot as pltimport mplfinance as mpl import pandas as pd td_consumer_key = 'YOUR-KEY-HERE'# 美国航空股票ticker = 'AAL'##periodType - day, month, year, ytd##period - number of periods to show##frequencyTYpe - type of frequency for each candle - day, month, year, ytd##frequency - the number of the frequency type in each candle - minute, daily, weeklyendpoint = 'https://api.tdameritrade.com/v1/marketdata/{stock_ticker}/pricehistory?periodType={periodType}&period={period}&frequencyType={frequencyType}&frequency={frequency}' # 获取数据full_url = endpoint.format(stock_ticker=ticker,periodType='year',period=10,frequencyType='daily',frequency=1)page = requests.get(url=full_url,params={'apikey' : td_consumer_key})content = json.loads(page.content) # 转成pandas可处理格式df = pd.json_normalize(content['candles']) # 设置时间戳为索引df['timestamp'] = pd.to_datetime(df.datetime, unit='ms')df = df.set_index("timestamp") # 绘制数据plt.figure(figsize=(15, 6), dpi=80)plt.plot(df['close'])plt.legend(['Closing Price'])plt.show() # 存储前一天的数据df["previous_close"] = df["close"].shift(1)df = df.dropna() # 删除缺失值 # 存储df.to_csv('../data/stock_'+ticker+'.csv', mode='w', index=True, header=True)
dbf0f23753da8cac83207cd5d4d57f2a.png

上面的代码查询 Ameritrade API 并返回 10 年的股价数据,例子中的股票为『美国航空公司』。 数据绘图结果如下所示:

90c7bdd38a916626149253d1048a71fb.png

💡 数据处理

我们加载刚才下载的数据文件,并开始处理预测。

# 读取数据ticker = 'AAL'df = pd.read_csv("../data/stock_"+ticker+".csv") # 设置索引df['DateIndex'] = pd.to_datetime(df['timestamp'], format="%Y/%m/%d")df = df.set_index('DateIndex')

下面我们对数据进幅度缩放,以便更好地送入神经网络和训练。(神经网络是一种对于输入数据幅度敏感的模型,不同字段较大的幅度差异,会影响网络的训练收敛速度和精度。)

# 幅度缩放df2 = dfcols = ['close', 'volume', 'previous_close']features = df2[cols]scaler = MinMaxScaler(feature_range=(0, 1)).fit(features.values)features = scaler.transform(features.values)df2[cols] = features

在这里,我们重点处理了收盘价成交量前几天收盘价列

💡 数据切分

接下来我们将数据拆分为训练和测试数据集。

# 收盘价设为目标字段X = df2.drop(['close','timestamp'], axis =1)y = df2['close'] import math# 计算切分点(以80%的训练数据为例)train_percentage = 0.8split_point = math.floor(len(X) * train_percentage) # 时序切分train_x, train_y = X[:split_point], y[:split_point]test_x, test_y = X[split_point:], y[split_point:]

接下来,我们对数据进行处理,构建滑窗数据,沿时间序列创建数据样本。(因为我们需要基于历史信息对未来的数值进行预测)

07cb4b5902b203331d4cbc3d194eb904.png
# 构建滑窗数据import numpy.libfrom numpy.lib.stride_tricks import sliding_window_view def genWindows(X_in, y_in, window_size): X_out = [] y_out = [] length = X_in.shape[0] for i in range(window_size, length): X_out.append(X_in[i-window_size:i, 0:4]) y_out.append(y_in[i-1]) return np.array(X_out), np.array(y_out) # 窗口大小为5window_size = 5X_train_win, y_train_win = genWindows(np.array(train_x), np.array(train_y), window_size)X_test_win, y_test_win = genWindows(np.array(test_x), np.array(test_y), window_size)

💡 模型构建&训练

构建完数据之后,我们就要构建 RNN 模型了,具体的代码如下所示。注意到下面使用了1个回调函数,模型会在验证集性能没有改善的情况下提前停止训练,防止模型过拟合影响泛化能力。

from tensorflow.keras import callbacks # 早停止 回调函数callback_early_stopping = callbacks.EarlyStopping( monitor="loss", patience=10,#look at last 10 epochs min_delta=0.0001,#loss must improve by this amount restore_best_weights=True,) from tensorflow import kerasfrom tensorflow.keras import layersfrom keras.models import Sequential # 构建RNN模型,结构为 输入-RNN-RNN-连续值输出input_shape=(X_train_win.shape[1],X_train_win.shape[2])print(input_shape)model = Sequential( [ layers.Input(shape=input_shape), layers.SimpleRNN(units=128, return_sequences=True), layers.SimpleRNN(64, return_sequences=False), layers.Dense(1, activation="linear"), ]) # 优化器optimizer = keras.optimizers.Nadam(learning_rate=0.0001)model.compile(optimizer=optimizer, loss="mse") # 模型结构总结model.summary() # 模型训练batch_size = 20epochs = 50history = model.fit(X_train_win, y_train_win, batch_size=batch_size, epochs=epochs, callbacks=[ callback_early_stopping ])

模型训练过程的损失函数(训练集上)的变化如下图所示。随着训练过程推进,模型损失不断优化,初期的优化和loss减小速度很快,后逐渐趋于平稳。

0bc8dadf088914cb908a8d4dcd63f48e.png

大约 10 个 epoch 后达到了最佳结果,训练好的模型就可以用于后续预测了,我们可以先对训练集进行预测,验证一下在训练集上学习的效果。

# 训练集预测pred_train_y = model.predict(X_train_win) # 绘图plt.figure(figsize=(15, 6), dpi=80)plt.plot(np.array(train_y))plt.plot(pred_train_y)plt.legend(['Actual', 'Predictions'])plt.show()

模型在训练集上学习的效果还不错,大家可以看到预测结果和真实值对比绘图如下:

275f7854502d82228a3f71b3e3b2a47d.png

💡 模型预测&应用

我们要评估模型的真实表现,需要在它没有见过的测试数据上评估,大家记得我们在数据切分的时候预留了 20% 的数据,下面我们用模型在这部分数据上预测并评估。

# 测试集预测pred_test_y = model.predict(X_test_win) # 预测结果绘制plt.figure(figsize=(15, 6), dpi=80)plt.plot(np.array(test_y))plt.plot(pred_test_y)plt.legend(['Actual', 'Predictions'])plt.show()
7f44199240534842e68e9cc9c4538bca.png

相对训练集来说,大家看到测试集上的效果稍有偏差,但是总体趋势还是预测得不错。

我们要考察这个模型对于时间序列预测的泛化能力,可以进行更严格一点的建模预测,比如将训练得到的模型应用与另一支完全没见过的股票上进行预测。如下为我们训练得到的模型对 Microsoft/微软股票价格的预测:

55e2996be3efa7328a0d66330567f45d.png
afb40e26ea71aafd8eeb9c04fc371c89.png

我们从图上可以看到,模型表现良好(预测存在一定程度的噪音,但它对总体趋势的预测比较准确)。

e9190f41b8de4af38c8a1a0c96f0513b~tplv-k3u1fbpfcp-zoom-1.image

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK