如何用C#与ML.NET基于JSON数据实现股票价格预测?
基于ML.NET的股票价格预测实现(无需CSV依赖)
1. 定义数据实体类
先对应你的JSON字段创建两个核心类:一个存储历史股票数据,一个接收预测结果:
// 历史股票数据模型(匹配JSON字段) public class StockHistory { public DateTime Date { get; set; } public float Open { get; set; } public float Close { get; set; } public float High { get; set; } public float Low { get; set; } public float Volume { get; set; } [ColumnName("AdjustedClose")] // 规避字段名空格,适配ML.NET列名规则 public float AdjustedClose { get; set; } } // 时间序列预测结果模型(输出多日预测值) public class StockPriceForecast { [ColumnName("Score")] public float[] PredictedAdjustedClose { get; set; } } // 回归预测结果模型(单条数据预测) public class StockPricePrediction { [ColumnName("Score")] public float PredictedPrice { get; set; } }
2. 加载JSON数据到ML.NET
直接将JSON反序列化为List<StockHistory>,再转换为ML.NET的IDataView(完全无需依赖CSV文件):
// 反序列化JSON数据(替换为你的JSON字符串或读取逻辑) var jsonData = File.ReadAllText("stock_data.json"); var stockHistoryList = JsonSerializer.Deserialize<List<StockHistory>>(jsonData); // 初始化ML上下文 var mlContext = new MLContext(seed: 42); // 固定种子保证实验可复现 // 转换为ML.NET可处理的IDataView var trainingData = mlContext.Data.LoadFromEnumerable(stockHistoryList);
3. 构建时间序列预测模型(推荐用于走势预测)
用ML.NET的SsaForecasting算法,适合基于历史序列预测未来N天价格:
// 构建训练管道 var forecastingPipeline = mlContext.Forecasting.ForecastBySsa( outputColumnName: "Score", inputColumnName: "AdjustedClose", // 选择调整后收盘价作为预测目标 windowSize: 7, // 用过去7天的数据作为窗口 seriesLength: 30, // 参考过去30天的序列规律 trainSize: stockHistoryList.Count, // 全部历史数据用于训练 horizon: 7); // 预测未来7天的价格 // 训练模型 var forecastingModel = forecastingPipeline.Fit(trainingData);
4. 生成未来日期的预测结果
创建预测引擎,生成预测后对应到未来日期:
// 创建时间序列预测引擎 var forecastEngine = forecastingModel.CreateTimeSeriesEngine<StockHistory, StockPriceForecast>(mlContext); // 执行预测 var forecastResult = forecastEngine.Predict(); // 匹配未来日期(从最后一条历史数据的次日开始) var lastDate = stockHistoryList.Last().Date; var finalForecast = new List<(DateTime ForecastDate, float PredictedPrice)>(); for (int i = 0; i < forecastResult.PredictedAdjustedClose.Length; i++) { finalForecast.Add((lastDate.AddDays(i + 1), forecastResult.PredictedAdjustedClose[i])); } // 输出结果示例 foreach (var item in finalForecast) { Console.WriteLine($"日期: {item.ForecastDate:yyyy-MM-dd} | 预测调整后收盘价: {item.PredictedPrice:F2}"); }
5. 扩展:用回归模型预测高低/平均价格
如果需要预测最高/最低/平均价格,可使用FastTree回归模型,结合多特征训练:
// 构建回归管道(用Open/High/Low/Volume作为特征,预测AdjustedClose) var regressionPipeline = mlContext.Transforms.Concatenate("Features", "Open", "High", "Low", "Volume") .Append(mlContext.Regression.Trainers.FastTree( labelColumnName: "AdjustedClose", featureColumnName: "Features")); // 训练回归模型 var regressionModel = regressionPipeline.Fit(trainingData); // 构造未来日期的输入特征(实验用:用历史均值填充未知字段) var avgOpen = stockHistoryList.Average(s => s.Open); var avgHigh = stockHistoryList.Average(s => s.High); var avgLow = stockHistoryList.Average(s => s.Low); var avgVolume = stockHistoryList.Average(s => s.Volume); var futureInputs = new List<StockHistory>(); for (int i = 0; i < 7; i++) { futureInputs.Add(new StockHistory { Date = lastDate.AddDays(i + 1), Open = avgOpen, High = avgHigh, Low = avgLow, Volume = avgVolume, AdjustedClose = 0 // 目标字段留空,由模型预测 }); } // 转换为IDataView并执行预测 var futureData = mlContext.Data.LoadFromEnumerable(futureInputs); var regressionPredictions = regressionModel.Transform(futureData); // 提取预测结果 var predictedPrices = mlContext.Data.CreateEnumerable<StockPricePrediction>(regressionPredictions, reuseRowObject: false);
关键注意事项
- 时间序列预测中,
windowSize和seriesLength需根据你的数据周期调整(比如日线数据用7/30,周线用4/12)。 - 回归模型的预测精度依赖特征的合理性,实验阶段可先用历史均值填充未来特征,后续可优化特征逻辑。
- 若要预测High/Low,只需将训练管道中的
labelColumnName改为"High"或"Low"即可。
内容的提问来源于stack exchange,提问作者Cameron
相关产品推荐
相关产品推荐

