ML.NET AutoML saved model schema issue

Viewed 117

I am able to use ML.NET to manually train a model, save it, load it to create a PredictionEngine and make predictions. But when I try to use the AutoML feature, I run into problems loading the model due to schema binding issue below.

Does anyone know what the issue is? I can get my model to load fine and make predictions if I train and save it without using AutoML so this really puzzles me.

System.InvalidOperationException
  Message=Can't bind the IDataView column 'CategoricalFeature1' of type 'Vector<Single, 42>' to field or property 'CategoricalFeature1' of type 'System.String'.
  Source=Microsoft.ML.Data

Here is how I load the model and use the modelSchema to create PredictionEngine

var trainedModel = mlContext.Model.Load(@"D:\Best_Model.zip", out var modelSchema);

var predictionEngine = mlContext.Model.CreatePredictionEngine<MyData, MyDataPrediction>(trainedModel, modelSchema);

Here is how I train my model using AutoML and save the best model.

var experimentSettings = new BinaryExperimentSettings
{
    MaxExperimentTimeInSeconds = 60 * 1,
    CancellationToken = cancellationTokenSource.Token,
    OptimizingMetric = BinaryClassificationMetric.AreaUnderRocCurve,
    CacheDirectoryName = CACHE_DIRECTORY_NAME
};

var dataView = mlContext.Data.LoadFromTextFile<MyData>(@"D:\MyDataset.csv", separatorChar: ',', hasHeader: true);

var experiment = mlContext.Auto().CreateBinaryClassificationExperiment(experimentSettings);

var crossValidationExperimentResult = experiment.Execute(dataView, numberOfCVFolds: 10);

var bestCrossValidationResult = crossValidationExperimentResult.BestRun.Results
    .OrderByDescending(result => result.ValidationMetrics.AreaUnderRocCurve)
    .First();

mlContext.Model.Save(bestCrossValidationResult.Model, dataView.Schema, @$"D:\Best_Model.zip");

Here is MyData class

public class MyData
{
    [LoadColumn(0)]
    public string CategoricalFeature1 { get; set; } = string.Empty;

    [LoadColumn(1)]
    public Boolean Label { get; set; }
}

Here is MyPrediction class

public class MyPrediction : MyData
{

    [ColumnName("PredictedLabel")]
    public bool Prediction { get; set; }

    public float Probability { get; set; }

    public float Score { get; set; }
}
2 Answers

I think you need to specify that your CategoricalFeature1 column is both an string and categorical with a EstimatorChain. This is because under the hood all ML models only use a vector of float.

Try adding an IEstimater like this:

var dataProcessPipeline = mlContext.Transforms.Conversion.OneHotEncoding(new[] { new InputOutputColumnPair("CategoricalFeature1","CategoricalFeature1")})

var crossValidationExperimentResult = experiment.Execute(dataView, numberOfCVFolds: 10, prefeaturizer: dataProcessPipeline);

This will encode your data as categorical and turn it into a vector of floats.

Related