You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于R语言neuralnet包构建的股价预测神经网络是否过拟合?

分析股价预测模型97-99%准确率的疑虑:是否过拟合?

首先,你的疑虑非常合理——股价预测属于典型的强噪声、非线性时间序列问题,通常很难达到这么高的准确率,大概率是过拟合或者评估方式的误导,咱们一步步拆解问题:

一、先排查准确率计算的合理性

你的准确率计算方式是 1 - abs(mean(deviation)),其中 deviation = abs((actual-predicted)/actual),这个指标很容易因为股价本身的特性产生“虚高”的准确率:

  • 假设股价每天的波动幅度很小(比如单日涨跌不超过2%),哪怕预测值和实际值有小幅偏差,偏差率也会很低,最终准确率就会显得极高,但这种“高准确率”对实际交易毫无意义——你无法通过这种预测判断涨跌方向或者获取收益。
  • 建议替换成更贴合时间序列预测的评估指标,比如:
    # 计算RMSE(均方根误差)
    rmse <- sqrt(mean((actual - predicted)^2))
    # 计算MAE(平均绝对误差)
    mae <- mean(abs(actual - predicted))
    # 计算涨跌方向准确率(更有实际意义)
    actual_dir <- sign(diff(actual))
    pred_dir <- sign(diff(predicted))
    dir_accuracy <- mean(actual_dir == pred_dir, na.rm = TRUE)
    
    方向准确率能直接反映模型对股价涨跌趋势的判断能力,这才是股价预测的核心价值。

二、验证是否真的过拟合

过拟合的核心特征是训练集表现远优于测试集,你可以做以下验证:

  1. 对比训练集和测试集的误差
    用同样的方式计算训练集的准确率/误差:

    # 对训练集做预测
    nn_pred_train <- compute(nn_model, nn_df_train)
    results_train <- data.frame(actual = nn_df_train$GSPC.Close, prediction = nn_pred_train$net.result)
    # 反归一化
    predicted_train = results_train$prediction * abs(diff(range(nn_org$GSPC.Close))) + min(nn_org$GSPC.Close)
    actual_train = results_train$actual * abs(diff(range(nn_org$GSPC.Close))) + min(nn_org$GSPC.Close)
    # 计算训练集偏差率和准确率
    deviation_train= abs((actual_train-predicted_train)/actual_train)
    accuracy_train=1-abs(mean(deviation_train))
    

    如果accuracy_train接近100%,而测试集准确率是97-99%,那可能不是严重过拟合;但如果训练集准确率比测试集高5%以上,那基本可以确定过拟合。

  2. 时间序列交叉验证(更严谨)
    股价是时间序列数据,不能像普通结构化数据那样随机拆分训练测试——你的拆分方式是前1965条训练,后843条测试,可能存在数据泄露(比如未来信息提前被模型学习)。建议用时间序列交叉验证:

    # 示例:滚动窗口交叉验证
    library(forecast)
    train_window <- 1965
    test_window <- 30
    accuracies <- c()
    
    for(i in seq(from = train_window, to = nrow(nn_df)-test_window, by = test_window)){
      train_data <- nn_df[1:i,]
      test_data <- nn_df[(i+1):(i+test_window),]
      # 训练模型
      temp_model <- neuralnet(GSPC.Close ~ GSPC.Open + GSPC.Low + GSPC.High + SentimentGI, 
                              data = train_data, hidden=5, linear.output=TRUE, threshold=0.01)
      # 预测
      temp_pred <- compute(temp_model, test_data)
      # 反归一化并计算准确率
      pred_temp = temp_pred$net.result * abs(diff(range(nn_org$GSPC.Close))) + min(nn_org$GSPC.Close)
      act_temp = test_data$GSPC.Close * abs(diff(range(nn_org$GSPC.Close))) + min(nn_org$GSPC.Close)
      dev_temp = abs((act_temp - pred_temp)/act_temp)
      acc_temp = 1 - mean(dev_temp)
      accuracies <- c(accuracies, acc_temp)
    }
    
    # 查看交叉验证的平均准确率
    mean(accuracies)
    

    如果交叉验证的平均准确率远低于你之前的97-99%,那说明之前的测试集拆分有问题,模型存在过拟合或者数据泄露。

三、解决过拟合的常见方法

如果确认是过拟合,可以尝试以下调整:

  • 简化模型结构:减少隐藏层神经元数量(比如从5降到2-3),避免模型过度学习训练数据的噪声。
  • 调整训练阈值:降低模型训练的阈值(比如从0.01调到0.05),让模型提前停止训练,避免过度拟合。
  • 特征筛选:检查输入特征是否有冗余(比如GSPC.Open和GSPC.Close本身高度相关),用相关性分析筛选核心特征,减少无关信息对模型的干扰。
  • 扩充数据集:如果可能的话,增加数据集的时间跨度,让模型学习到更多不同市场环境下的股价规律,提升泛化能力。

最后总结

先从评估指标合理性和训练测试集表现对比入手,确认是真的高准确率还是指标误导;再通过时间序列交叉验证验证模型的泛化能力;如果确实是过拟合,再通过简化模型、调整训练参数等方式优化。

内容的提问来源于stack exchange,提问作者james_ricky

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.13 09:19:41