我能够从string[]
列名中动态地训练和创建我的回归模型。但是,当我尝试传递与字典关键字对属性具有相同参数名称的动态对象时,会引发错误:
System.ArgumentOutOfRangeException: 'Could not find input column '<MyColumn>''
其中<MyColumn>
是模型要查找的第一个参数。
private static void TestSinglePrediction(MLContext mlContext, dynamic ratingDataSample, int actual)
{
ITransformer loadedModel;
using (var stream = new FileStream(_modelPath, FileMode.Open, FileAccess.Read, FileShare.Read))
{
loadedModel = mlContext.Model.Load(stream);
}
var predictionFunction = loadedModel.MakePredictionFunction<dynamic, RatingPrediction>(mlContext);
var prediction = predictionFunction.Predict(ratingDataSample);
Console.WriteLine($"**********************************************************************");
Console.WriteLine($"Predicted rating: {prediction.Rating:0.####}, actual rating: {actual}");
Console.WriteLine($"**********************************************************************");
}
我怀疑这是因为动态对象不包含我通常会传递的标准类对象具有的[Column]
属性。
但是,我最终将有数百个通过转置SQL查询自动生成的列,因此,将来手动键入每一列都不是可行的方法。
我是否可以在运行时应用属性?还是我可以采用其他方法一般地处理这种情况?谢谢!
答案 0 :(得分:1)
这是一个很好的问题。 dynamic
对象在运行时无法正常工作,因为ML.NET
需要对传入的对象使用称为SchemaDefinition
的对象,这样它才能知道从何处获取期望的列。
解决问题的最简单方法是定义一个对象,该对象仅在计分时保存需要的列,并用Column
属性进行注释,然后在运行时手动转换动态对象。这样做的主要优点是,由于您自己进行了对评分对象的强制转换,因此您可以自己处理丢失的数据案例,而不会抛出ML.NET
运行时。尽管您的SQL查询可能会为您提供各种各样的列,但是您不需要为模型评分而需要使用大多数这些列,因此无需在评分对象中进行说明;您只需要考虑模型期望的列即可。
有关如何对单个行进行评分的示例,请参见this sample中的ML.NET Cookbook。在幕后,ML.NET
正在使用您定义的类,并使用诸如Column
之类的属性来构造SchemaDefinition
。