【问题标题】:ML.NET - how to reverse mlContext.Transforms.Conversion.MapValueToKey using stored modelML.NET - 如何使用存储模型反转 mlContext.Transforms.Conversion.MapValueToKey
【发布时间】:2021-12-09 05:06:18
【问题描述】:

我正在使用 ML.Net 模型,该模型在管道中使用 MapValueToKey 转换。训练模型后,我将其保存。

在运行时,我加载保存的模型并进行预测。这工作正常,但我只得到值(整数)。如何使用从存储文件加载的模型提取与预测值匹配的键(字符串值)(我知道映射包含在存储模型中,因为如果我打印混淆矩阵,我可以看到它)。

示例代码如下,显示了我的问题的主要元素:

//Note: this.AllData is preloaded:  IDataView AllData

        //Create the PipeLine - Mapping Treatment Name to a Label as needed by the Multiclass Classification model
        var pipeline = mlContext.Transforms.Conversion.MapValueToKey(outputColumnName: "Label", nameof(TreatmentObservation.NextTreatmentName))
                        .Append(mlContext.Transforms.Categorical.OneHotEncoding(outputColumnName: "roadclass", inputColumnName: nameof(TreatmentObservation.RoadClass)))
                        .Append(mlContext.Transforms.Categorical.OneHotEncoding(outputColumnName: "surf_mat", inputColumnName: nameof(TreatmentObservation.SurfMaterial)))                                                       
                        .Append(mlContext.Transforms.Concatenate("Features", "roadclass", nameof(TreatmentObservation.Rut85th), nameof(TreatmentObservation.Naasra85th)));

        //Create a LightGBM Trainer
        IEstimator<ITransformer> trainer = mlContext.MulticlassClassification.Trainers.LightGbm();
        var trainingPipeline = pipeline.Append(trainer);
        var trainedModelWithPreproc = trainingPipeline.Fit(this.AllData); //Fit the pipleline on all the preloaded data

        //Save the model            
        string modelSaveFilePath = "modelPipeline.zip";            
        mlContext.Model.Save(trainedModelWithPreproc, dataSplit.TrainSet.Schema, modelSaveFilePath);

        //Now Load back the model and test it
        // Define trained model schemas
        DataViewSchema modelSchema;
        ITransformer allInOneModel = mlContext.Model.Load(modelSaveFilePath, out modelSchema);

        List<TreatmentObservation> testingData = null;
        //Load testing data here...(code not included)

        var observations = mlContext.Data.LoadFromEnumerable(testingData);
                               
        var engine = this.mlContext.Model.CreatePredictionEngine<TreatmentObservation, Prediction_MultiLabel>(allInOneModel);  //Create the prediction engine

        foreach (TreatmentObservation observation in testingData)
        {
            var predicted = engine.Predict(observation);
            uint label_value = predicted.PredictedLabel;

            string label_key;
            //How to get back the Key from the predicted value?

        }

这是上面示例中用于进行预测的类:

// Class used to capture predictions.
public class Prediction_MultiLabel
{
    // Original label.
    public uint Label { get; set; }

    // Predicted label from the trainer.
    public uint PredictedLabel { get; set; }

}

所以我的问题是:如何在使用存储和加载的模型进行预测时反转映射?

我看过像这样的例子:ML.NET example 但这些例子不使用存储模型。他们构建然后直接使用管道。我需要知道如何从存储的模型中反转映射。我不是 ML.NET 的专家,所以如果我的问题有一些无知,请原谅!

【问题讨论】:

    标签: c# ml.net


    【解决方案1】:

    令人担忧的是,两天后我没有收到来自 ML.NET 社区的建议解决方案。但我设法使用这个ML.NET 帮助帖子组合了一个解决方案。上面的问题陈述中显示的代码需要使用以下模式进行修改:

    //First create an explicit map for mapping keys to values. The values will be the index of the items in the array. 
            var lookupData = new[] {
                new LookupMap { Key = "Banana" },
                new LookupMap { Key = "Apple" },
                new LookupMap { Key = "Orange"  },
                new LookupMap { Key = "Melon" },
            };
    
            //Convert to IDataView
            var lookupIdvMap = mlContext.Data.LoadFromEnumerable(lookupData);
            
            //Now create the pipeline, with an explicit keyData Map using the above mapping
            var pipeline = mlContext.Transforms.Conversion.MapValueToKey(outputColumnName: "Label", nameof(Fruit.Name), keyData: lookupIdvMap)                                                        
                            .Append(mlContext.Transforms.Concatenate("Features", nameof(Fruit.Color), nameof(Fruit.Diameter), nameof(Fruit.Weight)));
    

    现在使用这个管道训练模型,然后保存它(示例代码在上面的问题语句中)。

    接下来,加载存储的模型进行测试,并创建一个预测引擎。同样,示例代码在上面的问题陈述中。完成后,您可以进行预测并获取名称而不是值,如下所示:

    //Here is an example of how you make a prediction:
            //In this case 'observation' is an instance of the type 'Fruit'
            var predicted = engine.Predict(observation);
            
            //Compare the observed and predicted name of the fruit
            string obs_Name = observation.Name;  //this is the observed value
            string pred_Name = lookupData[predicted.PredictedLabel - 1].Key;  //this is the predicted value. 
    

    LookupMap 类型是一个简单的类,定义如下:

    // Type for the IDataView that will be serving as the map
    public class LookupMap
    {
        public string Key { get; set; }
    }
    
        
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-05-12
      • 2022-07-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多