使用ML.NET回归模型预测值不符问题排查
为什么ML.NET回归模型预测结果和预期不符?
我来帮你捋捋问题所在——你的代码目标是训练一个输入Column1和输出Result完全线性对应的模型,但预测178时结果偏差很大,主要有这几个核心原因:
训练数据的范围和规模不够
你只生成了0到99的100条训练数据,而要预测的178已经超出了训练数据的取值范围。对于FastTree这类树模型来说,它本质是基于训练数据的区间做划分,完全没有外推能力,所以会返回接近训练数据上限的94;而Sdca作为线性模型虽然支持外推,但数据量太小、覆盖范围太窄,模型很难学习到准确的线性系数。默认训练器参数导致拟合不足
Sdca训练器默认带有正则化项,用来防止过拟合,但你的数据集是完全线性、没有任何噪声的简单场景,正则化反而会限制模型的拟合能力,导致预测值和真实值出现偏差。(小细节)预测时的
Result字段完全没用
你预测时传入的new Input { Column1 = 178, Result = 0}里,Result字段对预测没有任何影响,模型只用到Column1作为特征,这个只是无关紧要的小问题。
修正后的代码示例
我们可以通过扩大训练数据范围、调整训练器参数来解决问题:
class Program { static Input[] trainData; static void CreateData(int count = 200) { trainData = new Input[count]; // 生成0到199的训练数据,覆盖要预测的178 for (int i = 0; i < count; i++) { trainData[i] = new Input { Column1 = i, Result = i }; } } static void Main(string[] args) { CreateData(); var mlContext = new MLContext(); var dataView = mlContext.Data.LoadFromEnumerable(trainData); // 调整Sdca的正则化参数,几乎关闭正则化,让模型完美拟合线性关系 var pipeline = mlContext.Transforms.CopyColumns("Label", "Result") .Append(mlContext.Transforms.Concatenate("Features", "Column1")) .Append(mlContext.Regression.Trainers.Sdca( labelColumnName: "Label", featureColumnName: "Features", l2Regularization: 0.0001f, l1Regularization: 0f)); var model = pipeline.Fit(dataView); var predictor = mlContext.Model.CreatePredictionEngine<Input, Output>(model); // 预测时不需要传Result字段,因为模型用不到 var prediction = predictor.Predict(new Input { Column1 = 178}); Console.WriteLine(prediction.Result); // 现在会输出非常接近178的值 Console.Beep(500, 100); Console.Read(); } } class Input { public float Column1; public float Result; } class Output { [ColumnName("Score")] public float Result; }
额外小贴士
- 如果用
FastTree的话,哪怕扩大训练数据范围,它的外推能力依然很差。如果你的场景需要处理超出训练范围的预测,优先选择线性回归类训练器(比如Sdca、Ols)。 - 对于这种完全线性的无噪声数据,你也可以直接用
mlContext.Regression.Trainers.Ols()(普通最小二乘法),它能完美拟合这种线性关系,不需要调整任何正则化参数。
内容的提问来源于stack exchange,提问作者Vya4eslav5213
相关产品推荐
相关产品推荐

