ML.NET MakePredictionFunction动态类型?

时间:2018-12-18 16:50:04

标签: c# machine-learning ml.net

我能够从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查询自动生成的列,因此,将来手动键入每一列都不是可行的方法。

我是否可以在运行时应用属性?还是我可以采用其他方法一般地处理这种情况?谢谢!

1 个答案:

答案 0 :(得分:1)

这是一个很好的问题。 dynamic对象在运行时无法正常工作,因为ML.NET需要对传入的对象使用称为SchemaDefinition的对象,这样它才能知道从何处获取期望的列。

解决问题的最简单方法是定义一个对象,该对象仅在计分时保存需要的列,并用Column属性进行注释,然后在运行时手动转换动态对象。这样做的主要优点是,由于您自己进行了对评分对象的强制转换,因此您可以自己处理丢失的数据案例,而不会抛出ML.NET运行时。尽管您的SQL查询可能会为您提供各种各样的列,但是您不需要为模型评分而需要使用大多数这些列,因此无需在评分对象中进行说明;您只需要考虑模型期望的列即可。

有关如何对单个行进行评分的示例,请参见this sample中的ML.NET Cookbook。在幕后,ML.NET正在使用您定义的类,并使用诸如Column之类的属性来构造SchemaDefinition