Is it possible to store my ML.Net model in my MSSQL database?

Viewed 315

I have a few predictionmodels created with ML.Net and I would like to store them in my database with the rest of my data.

The models are per user.

Here's my current code, saving my model to my local folder:

        //MLNET
        var contextML = new MLContext();

        //Load Data
        var trainData = contextML.Data.LoadFromEnumerable<BankaccountBalanceData>(convertedTransactions);
        
        var testTrainSplit = contextML.Data.TrainTestSplit(trainData, testFraction: 0.2);
        //Build Model
        var pipeline = contextML.Transforms.Text.FeaturizeText("DateF", "Date")
            .Append(contextML.Transforms.Concatenate("Features", "DateF")
            .Append(contextML.Regression.Trainers.LbfgsPoissonRegression()));

        var model = pipeline.Fit(testTrainSplit.TrainSet);

        //Evaluate
        var predictions = model.Transform(testTrainSplit.TestSet);

        var metrics = contextML.Regression.Evaluate(predictions);

        //Predict
        var newData = new BankaccountBalanceData
        {
            Date = "2020-12-25"
        };

        var predictionFunction = contextML.Model.CreatePredictionEngine<BankaccountBalanceData, Prediction>(model);

        var prediction = predictionFunction.Predict(newData);

        contextML.Model.Save(model, trainData.Schema, "Model.zip");

What I have tried was to load the model and save it to a byte array in my SqlServer but I don't know if this is possible and if so, how to read it back to a ITransformer as my original model.

        DataViewSchema modelSchema;
        ITransformer trainedModel = contextML.Model.Load("model.zip", out modelSchema);
        user.Model = System.IO.File.ReadAllBytes(trainedModel.ToString());
1 Answers

You may want to save your model to a MemoryStream, then convert it to a byte array using ToArray() and store it in the database as varbinary.

Saving model to database:

using (var stream = new MemoryStream())
{
    MlContext.Model.Save(trainedModel, trainData.Schema, stream);

    dbContext.Models.Add(new Model
    {
        ModelData = stream.ToArray(),
        // Additonal metadata
    });

    await SaveChangesAsync();
}

Loading model from database:

var dbModel = await dbContext.Models.OrderByDescending(x => x.Id).FirstAsync();

ITransformer mlModel;
using (var stream = new MemoryStream(dbModel.ModelData))
{
    mlModel = MlContext.Model.Load(stream, out var schema);
}
Related