• 深度学习100例 —— 循环神经网络(RNN)实现股票预测


    活动地址:CSDN21天学习挑战赛

    深度学习100例——循环神经网络(RNN)实现股票预测

    我的环境

    在这里插入图片描述

    1 RNN

    1.1 RNN简介

    传统神经网络结构:

    • 输入层
    • 隐藏层
    • 输出层

    在这里插入图片描述

    RNN和传统神经网络ANN的最大的区别在于每次会将前一次的输出结果,带到下一次迭代的隐藏层中,一起进行训练。

    在这里插入图片描述

    一般以序列数据作为输入,通过网络的内部结构设计有效捕捉序列之间的关系特征,一般也以序列形式进行输出。

    1.2 RNN模型作用
    • 很好地利用序列之间的关系 → 针对自然界具有连续性的输入序列,能进行很好地处理。
    • 适用场景
      • 文本分类
      • 情感分析
      • 意图识别
      • 机器翻译

    2 准备工作

    2.1 设置GPU
    import tensorflow as tf
    
    gpus = tf.config.list_physical_devices("GPU")
    
    if gpus:
        tf.config.experimental.set_memory_growth(gpus[0], True)  #设置GPU显存用量按需使用
        tf.config.set_visible_devices([gpus[0]],"GPU")	
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    在这里插入图片描述

    2.2 加载数据
    import os,math
    from tensorflow.keras.layers import Dropout, Dense, SimpleRNN
    from sklearn.preprocessing import MinMaxScaler
    from sklearn import metrics
    import numpy             as np
    import pandas            as pd
    import tensorflow        as tf
    import matplotlib.pyplot as plt
    # 支持中文
    plt.rcParams['font.sans-serif'] = ['SimHei']  # 用来正常显示中文标签
    plt.rcParams['axes.unicode_minus'] = False  # 用来正常显示负号
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    在这里插入图片描述

    读入股票文件

    data = pd.read_csv('SH600519.csv')  # 读取股票文件
    data
    
    • 1
    • 2

    在这里插入图片描述

    划分数据集合

    前(2426-300=2126)天的开盘价作为训练集,表格从0开始计数,2:3 是提取[2:3)列,前闭后开,故提取出C列开盘价后300天的开盘价作为测试集

    training_set = data.iloc[0:2426 - 300, 2:3].values  
    test_set = data.iloc[2426 - 300:, 2:3].values  
    
    • 1
    • 2

    在这里插入图片描述

    3 数据预处理

    3.1 归一化
    sc = MinMaxScaler(feature_range=(0, 1))
    training_set = sc.fit_transform(training_set)
    test_set = sc.transform(test_set) 
    
    • 1
    • 2
    • 3
    3.2 设置测试集、训练集
    x_train = []
    y_train = []
    
    x_test = []
    y_test = []
    
    """
    使用前60天的开盘价作为输入特征x_train
        第61天的开盘价作为输入标签y_train
        
    for循环共构建2426-300-60=2066组训练数据。
           共构建300-60=260组测试数据
    """
    for i in range(60, len(training_set)):
        x_train.append(training_set[i - 60:i, 0])
        y_train.append(training_set[i, 0])
        
    for i in range(60, len(test_set)):
        x_test.append(test_set[i - 60:i, 0])
        y_test.append(test_set[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)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    """
    将训练数据调整为数组(array)
    
    调整后的形状:
    x_train:(2066, 60, 1)
    y_train:(2066,)
    x_test :(240, 60, 1)
    y_test :(240,)
    """
    x_train, y_train = np.array(x_train), np.array(y_train) # x_train形状为:(2066, 60, 1)
    x_test,  y_test  = np.array(x_test),  np.array(y_test)
    
    """
    输入要求:[送入样本数, 循环核时间展开步数, 每个时间步输入特征个数]
    """
    x_train = np.reshape(x_train, (x_train.shape[0], 60, 1))
    x_test  = np.reshape(x_test,  (x_test.shape[0], 60, 1))
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    在这里插入图片描述

    4 构建模型

    model = tf.keras.Sequential([
        SimpleRNN(100, return_sequences=True), #布尔值。是返回输出序列中的最后一个输出,还是全部序列。
        Dropout(0.1),                         #防止过拟合
        SimpleRNN(100),
        Dropout(0.1),
        Dense(1)
    ])
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    5 激活模型

    # 该应用只观测loss数值,不观测准确率,所以删去metrics选项,一会在每个epoch迭代显示时只显示loss值
    model.compile(optimizer=tf.keras.optimizers.Adam(0.001),loss='mean_squared_error')  # 损失函数用均方误差
    
    • 1
    • 2

    6 训练模型

    history = model.fit(x_train, y_train, 
                        batch_size=64, 
                        epochs=20, 
                        validation_data=(x_test, y_test), 
                        validation_freq=1)                  #测试的epoch间隔数
    
    model.summary()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    在这里插入图片描述

    7 结果可视化

    7.1 绘制loss
    plt.plot(history.history['loss']    , label='Training Loss')
    plt.plot(history.history['val_loss'], label='Validation Loss')
    plt.title('Training and Validation Loss by DingJiaxiong')
    plt.legend()
    plt.show()
    
    • 1
    • 2
    • 3
    • 4
    • 5

    在这里插入图片描述

    7.2 预测
    predicted_stock_price = model.predict(x_test)                       # 测试集输入模型进行预测
    predicted_stock_price = sc.inverse_transform(predicted_stock_price) # 对预测数据还原---从(0,1)反归一化到原始范围
    real_stock_price = sc.inverse_transform(test_set[60:])              # 对真实数据还原---从(0,1)反归一化到原始范围
    
    # 画出真实数据和预测数据的对比曲线
    plt.plot(real_stock_price, color='red', label='Stock Price')
    plt.plot(predicted_stock_price, color='blue', label='Predicted Stock Price')
    plt.title('Stock Price Prediction by DingJiaxiong')
    plt.xlabel('Time')
    plt.ylabel('Stock Price')
    plt.legend()
    plt.show()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    在这里插入图片描述

    7.3 评估
    """
    MSE  :均方误差    ----->  预测值减真实值求平方后求均值
    RMSE :均方根误差  ----->  对均方误差开方
    MAE  :平均绝对误差----->  预测值减真实值求绝对值后求均值
    R2   :决定系数,可以简单理解为反映模型拟合优度的重要的统计量
    """
    MSE   = metrics.mean_squared_error(predicted_stock_price, real_stock_price)
    RMSE  = metrics.mean_squared_error(predicted_stock_price, real_stock_price)**0.5
    MAE   = metrics.mean_absolute_error(predicted_stock_price, real_stock_price)
    R2    = metrics.r2_score(predicted_stock_price, real_stock_price)
    
    print('均方误差: %.5f' % MSE)
    print('均方根误差: %.5f' % RMSE)
    print('平均绝对误差: %.5f' % MAE)
    print('R2: %.5f' % R2)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    在这里插入图片描述

  • 相关阅读:
    c语言一维数组和二维指针
    HOJ排队打水F601题解
    oracle从入门到精通第五篇(视图|表空间|索引|存储过程|触发器|复制表)
    压缩感知常用的重建算法
    Java中如何遍历Map中的value呢?
    P6183 [USACO10MAR] The Rock Game S
    Ps:明度直方图
    [附源码]Python计算机毕业设计Django病房管理系统
    L3-005 垃圾箱分布
    Linux下C/C++链接mysql流程
  • 原文地址:https://blog.csdn.net/weixin_44226181/article/details/126241587