• 基于RNN的短期股票预测


    1.数据集来源

    本文数据集是通过python中tushare模块下载的股票日k线数据,本次数据只用来了其中的开盘价格

     tushare模块简介

    导入tushare

    import tushare as ts

    这里注意, tushare版本需大于1.2.10

    设置token

    ts.set_token('your token here')

    以上方法只需要在第一次或者token失效后调用,完成调取tushare数据凭证的设置,正常情况下不需要重复设置。也可以忽略此步骤,直接用pro_api('your token')完成初始化,但这里的token需要自己去官网申请(注册即可得到)

    初始化pro接口

    pro = ts.pro_api()

     调取数据

    ts.get_k_data()

    get_k_data含义是获取k线数据,所以起了这么一个简单的名称。虽然一贯的不标准,不规范,但主要看气质,主要看数据。 新接口融合了get_hist_data和get_h_data两个接口的功能,即能方便获取日周月的低频数据,也可以获取5、15、30和60分钟相对高频的数据。同时,上市以来的前后复权数据也能在一行代码中轻松获得,当然,您也可以选择不复权。

    主要参数说明 

    • code 证券代码:支持沪深A、B股支持全部指数支持ETF基金 
    • ktype 数据类型:默认为D日线数据D=日k线 W=周 M=月 5=5分钟 15=15分钟 30=30分钟 60=60分钟
    • autype 复权类型:qfq-前复权 hfq-后复权 None-不复权,默认为qfq 
    • index 是否为指数:默认为False设定为True时认为code为指数代码
    •  start 开始日期 format:YYYY-MM-DD 为空时取当前日期
    • end 结束日期 :format:YYYY-MM-DD

    数据属性说明

    • date 日期和时间低频数据时为:YYYY-MM-DD高频数为:YYYY-MM-DD HH:MM
    • open开盘价 close收盘价
    • high最高价
    • low最低价
    • volume成交量
    • code证券代码

    2.代码

    模型内部参数大家可自己调试,我的参数不一定是最优的

    1. # -*- coding: utf-8 -*-
    2. # @Time : 2022/9/13 16:05
    3. # @Author : 中意灬
    4. # @QQ NUM : 978593353
    5. # @FileName: 基于RNN的股票预测.py
    6. # @Software: PyCharm
    7. '''第一步:导入相关的库'''
    8. import os.path
    9. import tushare as ts
    10. import numpy as np
    11. import tensorflow as tf
    12. from tensorflow.keras.layers import Dense,SimpleRNN,Dropout
    13. import matplotlib.pyplot as plt
    14. import pandas as pd
    15. from tensorflow.keras import Model
    16. from sklearn.preprocessing import MinMaxScaler
    17. from sklearn.metrics import mean_squared_error,mean_absolute_error
    18. import math
    19. '''第二步:准备数据'''
    20. datapath='./data.csv'
    21. if os.path.exists(datapath):
    22. print('==========load data==========')
    23. data = pd.read_csv('./data.csv')
    24. training_set = data.iloc[0:2427 - 300, 2:3].values #前(2427-300=2127)天的开盘价作为训练集,表格从0开始计数,2:3 是提取[2:3)列,前闭后开,故提取出C列开盘价
    25. test_set = data.iloc[2427 - 300:, 2:3].values #后三百天作为测试集
    26. else:
    27. ts.set_token('f9e62b42d9f31fbf0267d9ba52204d37c5fef60f3d6091e9820c40a1') #这儿的token需要自己去turshare注册申请
    28. df=ts.get_k_data('600519',ktype='D',start='2012-01-01',end='2022-01-01')
    29. df.to_csv(datapath)
    30. data = pd.read_csv('./data.csv')
    31. training_set = data.iloc[0:2427 - 300, 2:3].values
    32. test_set = data.iloc[2427 - 300:, 2:3].values
    33. #归一化
    34. sc=MinMaxScaler(feature_range=(0,1))#定义归一化:归一化到(0-1)之间
    35. training_set_scaler=sc.fit_transform(training_set)# 求得训练集的最大值,最小值这些训练集固有的属性,并在训练集上进行归一化
    36. test_set=sc.transform(test_set)# 利用训练集的属性对测试集归一化
    37. x_train=[]
    38. x_test=[]
    39. y_train=[]
    40. y_test=[]
    41. #利用for循环,遍历整个训练集,将训练集中连续60天的数据作为训练特征x_train,第61天的数据作为训练标签y_train
    42. for i in range(60,len(training_set_scaler)):
    43. x_train.append(training_set_scaler[i-60:i,0])
    44. y_train.append(training_set_scaler[i,0])
    45. #将训练特征和标签转换神经网络的输入格式,使x_train符合RNN输入要求:[送入样本数, 循环核时间展开步数, 每个时间步输入特征个数]。
    46. x_train,y_train=np.array(x_train),np.array(y_train)
    47. x_train=np.reshape(x_train,(len(x_train),60,1))
    48. #利用for循环,遍历整个训练集,将测试集中连续60天的数据作为测试特征x_train,第61天的数据作为测试标签y_train
    49. for i in range(60,len(test_set)):
    50. x_test.append(test_set[i-60:i,0])
    51. y_test.append(test_set[i,0])
    52. #将测试特征和标签转换神经网络的输入格式,使x_test符合RNN输入要求:[送入样本数, 循环核时间展开步数, 每个时间步输入特征个数]。
    53. x_test,y_test=np.array(x_test),np.array(y_test)
    54. x_test=np.reshape(x_test,(len(x_test),60,1))
    55. #对训练集进行打乱
    56. np.random.seed(3)
    57. np.random.shuffle(x_train)
    58. np.random.seed(3)
    59. np.random.shuffle(y_train)
    60. """第三步:使用class类搭建神经网络结构"""
    61. class StockRNN(Model):
    62. def __init__(self):
    63. super(StockRNN, self).__init__()
    64. self.r1=SimpleRNN(256,activation='tanh',return_sequences=True)#因为下一层依然是RNN,所以选择True,将每个时间步的ht都送入下一层
    65. self.d1=Dropout(0.2)
    66. self.r2=SimpleRNN(100,activation='tanh',return_sequences=False)
    67. self.d2=Dropout(0.2)
    68. self.f1=Dense(1)
    69. def call(self,x):
    70. x=self.r1(x)
    71. x=self.d1(x)
    72. x=self.r2(x)
    73. x=self.d2(x)
    74. x=self.f1(x)
    75. return x
    76. model=StockRNN()
    77. '''第四步:使用model.compile配置网络参数'''
    78. model.compile(optimizer=tf.keras.optimizers.Adam(0.001),#自己设定adam的学习率,尽量先设置小,大了会收敛过快
    79. loss='mean_squared_error')#不必观察metrics值,没必要,只用观察loss值就可以
    80. checkpoint_save_path='./checkpoint/StockRNN.ckpt'
    81. if os.path.exists(checkpoint_save_path+'.index'):
    82. print('==========load the model==========')
    83. model.load_weights(checkpoint_save_path)
    84. cp_callback=tf.keras.callbacks.ModelCheckpoint(filepath=checkpoint_save_path,
    85. save_weights_only=True,
    86. save_best_only=True,
    87. monitor='val_loss')
    88. """第五步:使用model.fit训练模型"""
    89. history=model.fit(x_train,y_train,batch_size=32,epochs=50,validation_data=(x_test,y_test),validation_freq=1,callbacks=[cp_callback])
    90. #参数提取
    91. file=open('./weights.txt','w')
    92. for v in model.trainable_variables:
    93. file.write(str(v.name)+'\n')
    94. file.write(str(v.shape)+'\n')
    95. file.write(str(v.numpy())+'\n')
    96. '''第六步:使用model.summary打印网络结构'''
    97. model.summary()
    98. #绘制loss图像
    99. plt.figure()
    100. plt.plot(history.history['loss'],label='loss')
    101. plt.plot(history.history['val_loss'],label='val_loss')
    102. plt.title('Train and Validation loss')
    103. plt.legend()
    104. plt.show()
    105. #模型预测
    106. predict_stock_openprice=model.predict(x_test)
    107. #对预测数据反归一化
    108. predict_stock_openprice=sc.inverse_transform(predict_stock_openprice)
    109. #对真实数据反归一化
    110. real_stock_openprice=sc.inverse_transform(test_set[60:])
    111. #可视化
    112. plt.figure()
    113. plt.plot(real_stock_openprice,color='r',label='real')
    114. plt.plot(predict_stock_openprice,color='b',label='predict')
    115. plt.legend()
    116. plt.show()
    117. ##模型预测效果量化,数值越小,效果越好
    118. #MSE 均方误差-->E[(预测值-真实值)^2]
    119. mse=mean_squared_error(predict_stock_openprice,real_stock_openprice)
    120. #RMSE 均方误差根-->sqrt(mse)
    121. rmse=math.sqrt(mean_squared_error(predict_stock_openprice,real_stock_openprice))
    122. #MAE 平均绝对误差-->E(|预测值-真实值|)
    123. mae=mean_absolute_error(predict_stock_openprice,real_stock_openprice)
    124. print('均方误差:',mse)
    125. print('均方误差根:',rmse)
    126. print('平局绝对误差:',mae)
    127. #对未知数据预测
    128. preNum=int(input('输入你要预测后多少个数据:'))
    129. a = test_set[len(test_set) - 60:, 0]
    130. c=[]#存储预测后的数据
    131. for i in range(preNum):
    132. b=np.reshape(a,(1,60,1))
    133. pre=model.predict(b)
    134. a=a.tolist()
    135. del a[0]
    136. a.extend(pre[0])
    137. c.extend(pre)
    138. a=np.array(a)
    139. test_set=np.array(test_set)
    140. c=sc.inverse_transform(c)
    141. plt.figure()
    142. plt.plot(sc.inverse_transform(test_set[60:]),color='b',label='real')
    143. x=np.arange(len(test_set[60:]),len(test_set[60:])+preNum)
    144. plt.plot(x,c,color='r')
    145. plt.plot(predict_stock_openprice,color='r',label='predict')
    146. plt.show()

     

     但其实从对未知数据进行预测的结果便能看出,rnn存在一共缺点,就是无法长期预测,我们将预测得到的数据带入模型,对跟后面数据进行预测,会发现时间跨度一大,其预测结果就会变得离谱。

    预测后20个数据

     预测后50个数据

     

     

     

  • 相关阅读:
    Redis命令和Redisson对象匹配列表
    RationalDMIS2022车削件(轴类)测量:回转体检测
    9.MyBatis-Plus
    AIGC革新,将文字或者LOGO融入AI视频基于PIKA-labs(Python3.10)
    教你面试的时候如何迅速完成90%以上的海量数据处理题
    同构和异构经典图神经网络汇总+pytorch代码
    K8S名称空间和资源配额
    【初始MongoDB】MongoDB的使用(对比MySQL)
    linux开发常用命令
    如何把JavaWeb项目部署到服务器
  • 原文地址:https://blog.csdn.net/qq_55977554/article/details/126849943