基于RNN、LSTM神经网络的基金净值预测


都是神经网络惹的祸

        这个月花了将近100G的流量,大半都拿来下学习视频了。上次写了个爬虫把基金数据爬下来了,说是要数据分析一波,头脑热了一个礼拜,每天晚上都在搞神经网络的代码,光是装TensorFlow环境就搞了我3个晚上,到处在网上找代码学习,本来就差最后一步就把要程序跑出来了,结果卡在了反归一化上面,输入输出维度不匹配,又搞了好几天,终于神经网络把我劝退了。我发现这样是行不通的,整得太浮躁了,不懂计算原理直接啃代码,连输入输出是什么都不懂,一些基本的激活函数、归一函数、评价模型都不懂想直接调包也没那么容易,出结果

       后来大概过了大半个月,机缘巧合正好需要用到机器学习,我拾起了之前留下的烂摊子,慢慢(假的)基础知识学习,又搞起了机器学习。

        今天终于能把神经网络跑出来了😁好久没更新博客了,主要是最近没啥时间搞自己的东西,作业都写不完

大家好,我是调包侠

虽然把神经网络跑出来了,中间还有些小问题,预测效果也不是很好,但是能跑出来

我就非常开心了,后面会再把基础打扎实一些。

先看效果图:

预测

两条线基本拟合度不是很好,甚至可以说两条线没什么关系,细节波动预测不到,但是大致走势还比较正确(已经调整过很多种方案了,这是还比较像人样的)

看看他的过去:可以说是毫不相干😡

最开始这是纯RNN模型

RNN

后来我改成了LSTM模型,发现更离谱:(后来我把模型的第一层改成LSTM就得到了图一)

大概可以看出加入LSTM模型,预测值将会变得更趋于平缓,我猜可能是因为LSTM模型对长期记忆性导致的

其中存在的问题是每次Epoch的val_loss值都是不变,而且loss值为什么都是nan,我去看了网上说是每次训练出来的权重不变(或者说没有更新),或者是模型错误造成的,俺不懂怎么办了,百思不得其解,有没有懂得大佬指点一下,感激涕零😭损失值

下面康康学习过程

好多包,我好爱

import numpy as np
import tensorflow as tf
from tensorflow.keras.layers import Dropout, Dense, SimpleRNN, LSTM
import matplotlib.pyplot as plt
import os
import pandas as pd
from sklearn.preprocessing import MinMaxScaler
from sklearn.metrics import mean_squared_error, mean_absolute_error
import math

导入数据和数据预处理:

yiliao = pd.read_csv('./SH600519.csv')
#print(yiliao)
training_set = yiliao.iloc[0:2426 - 300, 2:3].values  #前(1975-300)天的净值作为训练集,表格从0开始计数,2:3是提取[1:2)列,前闭后开,故提取出第二列净值
test_set = yiliao.iloc[2426 - 300:, 2:3].values  #后300天的开盘价作为测试集

#归一化
sc = MinMaxScaler(feature_range=(0, 1))  #定义归一化;缩放到(0,1)之间
training_set_scaled = sc.fit_transform(training_set)  #求得训练集的最大最小值这些训练集固有的属性,并在训练集上进行归一化
test_set = sc.fit_transform(test_set)  #利用训练集的属性对测试集进行归一化

还是数据预处理,将数据训练集和测试集划分

测试集:csv表格中的前1975-300=1675天的数据
#利用for循环,遍历整个训练集,提取训练集中连续60天的开盘价作为输入特征x_train,第61天的数据作为标签,for循环共构建1975-300-60=1615
for i in range(60, len(training_set_scaled)):
    x_train.append(training_set_scaled[i - 60:i, 0])
    y_train.append(training_set_scaled[i: 0])
#打乱训练集顺序
np.random.seed(7)
np.random.shuffle(x_train)
np.random.seed(7)
np.random.shuffle(y_train)
tf.random.set_seed(7)
#将训练集由list格式变为array格式
x_train, y_train = np.array(x_train), np.array(y_train)
#此处整个数据集送入,送入样本数为x_train.shape[0]及1615组数据
x_train = np.reshape(x_train, (x_train.shape[0], 60, 1))#测试集:csv表格中后300天数据
#...省略
for i in range(60, len(test_set)):
    x_test.append(test_set[i - 60:i, 0])
    y_test.append(test_set[i, 0])
#测试集变arry并reshape为符合RNN输入要求:[送入样本数, 循环核时间展开步数, 每个时间步输入的特征个数]
x_test, y_test = np.array(x_test), np.array(y_test)
x_test = np.reshape(x_test, (x_test.shape[0], 60, 1))

设定模型:


model = tf.keras.Sequential([
    SimpleRNN(80, return_sequences=True),
    Dropout(0.2),
    SimpleRNN(100),
    Dropout(0.2),
    Dense(1)
])

model.compile(optimizer=tf.keras.optimizers.Adam(0.001),loss='mean_squared_error')  #损失函数用均方误差

保存训练好的模型:

checkpoint_sava_path = "./checkpoint/jijin.ckpt"

if os.path.exists(checkpoint_sava_path + '.index'):
    print('--------load the model--------')
    model.load_weights(checkpoint_sava_path)

cp_callback = tf.keras.callbacks.ModelCheckpoint(filepath=checkpoint_sava_path,
                                                 save_weights_only=True,
                                                 save_best_only=True,
                                                 monitor='val_loss')
history = model.fit(x_train, y_train, batch_size=128, epochs=5, validation_data=(x_test, y_test), validation_freq=1,
                    callbacks=[cp_callback])
model.summary()
file = open('./weight.txt', 'w')  #参数提取
for v in model.trainable_variables:
    file.write(str(v.name) + '\n')
    file.write(str(v.shape) + '\n')
    file.write(str(v.numpy()) + '\n')
file.close()

loss = history.history['loss']
val_loss = history.history['val_loss']

画出损失函数图:

plt.plot(loss, label='Training Loss')
plt.plot(val_loss, label='Validation Loss')
plt.title('Training and Validation Loss')
plt.legend()
plt.show()

测试集输入模型开始预测:

predicted_stock_price = model.predict(x_test)
# 对预测数据还原--从(0-1)反归一化到原始范围
predicted_stock_price = sc.inverse_transform(predicted_stock_price)
# 对真实数据还原--从0-1)反归一化到原始范围
real_stock_price = sc.inverse_transform(test_set[60:])
# 画出真实数据和预测数据对比曲线
plt.plot(real_stock_price, color='red', label='Jijin Price')
plt.plot(predicted_stock_price, color='blue', label='Predicted Jijin Price')
plt.title('Jijin Price Prediction')
plt.xlabel('Time')
plt.ylabel('Jijin Price')
plt.legend()
plt.show()

评价模型:

mse = mean_squared_error(predicted_stock_price, real_stock_price)
# 均方根误差
rmse = math.sqrt(mean_squared_error(predicted_stock_price, real_stock_price))
# 平均绝对误差
mae = mean_absolute_error(predicted_stock_price, real_stock_price)

以上

完整代码会上传到我的Github,欢迎fock,顺便求助一下俺的问题555


文章作者: Yuukyou
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 Yuukyou !
评论
  目录