Branch: master
Find file History
CESARDELATORRE Migration to v0.10 of all C# samples (#242)
* BikeSharing sample migrated to 0.10

* Added cultureInfo.InvariantCulture to resolve issue #227

* added Build props file into other samples which are not migrated yet. so that build will not file on remote.

* Did the following changes.
1.Changed the version to 0.10 for global build.props file.
2.Changed the Credit card sample with the following to fix breaking changes.
a. Replace BinaryClassificationContext with BinaryClassificationCatalog
b. Added parameter names to input parameter of ML.Net API calls.
c. Added AppendCacheCheckpoint(mlContext) in the pipeLine.
Resolved some compilation errors according to ML.Net version changes

* Migrated sample Clustering_CustomerSegmentation with the following changes
1.Replaced CreateTextReader with ReadFromTextFile.
2.Changed the order of columns while creating the estimator
3.Added parameter names in API calls.
4.Accessed Fetures and score variables with DefaultColumnNames static class

* Minor changes in Customer Segmentation project
1.Updated Readme File
2.Removed AppendCacheCheckPoint() method as the program is running fine with F5 option in visual studio.

* Minor changes to Credit card Fraud Detection.
1.Changed readme file with version to 0.10 and code changes.
2.Removed AppendCahceCheckPoint(mlContext) as the program runs fine with out delay becuase of F5 option.

* Minor changes to Bike Sharing Demand Sample.
Replaced version with 0.10 in Readme file

* Migrated GitHubLabeler sample to v0.10 with the following changes.
1.Added parameter names in ML.Net API calls
2.strong typed label,features,Predicted label strings with DefaultColumnNames class

* Migrated MultiClassClassification_Iris to v0.10.
-Changed the readme file by updating version information to 0.10
-Deleted local build.props file which has 0.9 version
-Repalced Setosa name with Virginica in  the console.writeLine as we are testing for 'Virginica'

* Migrated Clustering_Iris to v0.10 with the following changes.
1. Replaced string values with nameof(classnme.variableName).
2.Replaced string values with DefaultColumnNames calss for "Features"
3.Changed Readme file.
4.Removed Build.props file.

* Migrated MovieRecommendationE2E sample.
1.updated Readme file with version inforamtion 0.10
2.Replaced the fields with data class while defining the schema and reading training data.
3.Specifiedparameter names in API calls.
4.Specified "Feature" strings with DefaultColumnNames class.

* Migrated Sentiment Analysis sample
1.Used DefaultColumnNames Class to specify/access features, score,label
2.Used parameter names in API calls.
3.Removed the Build.props file which has version 0.9
4. Changed Readme file.

* Migrated ProductRecommendation Sample to v0.10 with the following changes.
1.Added folder with name Common and linked ConsoleHelper file.
2.Removed Build.Props file which ahs version 0.9
3.Changed the code according to ML.Net 0.10 API changes.
4.Specified parameter names in the ML.Net API calls, etc.
5.Changed Reacme file.

* Migrated SalesForecast to v0.10 by fixing the below breaking changes and some refactoring.
1. Removed Build.Props file which ahs version 0.9
3.Changed the code according to ML.Net 0.10 API changes.
4.Specified parameter names in the ML.Net API calls, used DefaultColumnNames class to access constant names like Feature,Label, score etc.
5.Changed Readme file.

* Migrated TaxiFarePedication Sample to 0.10 with the follwoing changes:
1.Changed the order of input and output columns in Ml.Net API calls.
2.Specified parameternames in API calls.
3.Refactored code using DefaultColumnNames class and nameof().
4.Changed Readme file.
5.Removed Build.Props file which has version 0.9

* Migrated MovieRecommendation Sample to v0.10. with the below changes.
1.Changed code according Ml.Net API calls.
2.Used DefaultColumnNames class to specify common ouput types like Features, score,label etc.
3.Removed Build.props file which has version 0.9
4. Changed Readme file
5. seperated DataProcessingPipeLine and TrainingPipeLine.
6. Changed the Nuget package name from MatrixFactorization to Recommender.

* Migrated HeartDisease sample to v0.10 with the following changes.
1.Removed Build.props file which ahs version 0.9
2.Changed Readme file.
3.Used nameof and DefaultColumnNames instead of strings.
4.Specified paramter names in Ml.Net API calls.

* Migrated MNIST sample to v0.10 with the following changes.
1.Refactored code
2.Changed Readme file.
3.Removed Build.Props file.
4.Changed the csproj file to refer version from global file.
5.Changed API calls according to syntax changes Ml.Net API.

* Minor changes to BikaSharinDemand sample.
1.used nameof(Classname.Fieldname) instead of "fieldname"
2.Used DefaultColumnNames class to access Fetaures,label,score etc.

* Migrated TenslorFlow Scorer to v0.10 with the following changes.
1.Specified paramternames, reordered parameters
2. Refactored code to avoid using strings directly in method calls so that we don't get exceptions runtime.
3.Updated ReadMe file.
4.Removed Build.Props file which has version 0.9

* Migrated Changes to TensorFlow Estimator
1. Fixed the breaking changes like changing from "MulticlassClassificationContext" to  "MulticlassClassificationCatalog"
2.Changed the parameter orders in the API calls and specified parameter names.
3.Changed ReadMe file.
4.Removed Build.Props file which has version 0.9

* Pushing v0.10 solution file

* Migrated SpamDetection sample to v0.10 with the fowllowing changes.
1.used ReadformText file to define the schema,train data in a single line instead of reader.
2.Changed Readme File.
3.Removed Build.Props file which had version 0.9
4. Refactored code and specified parameter names in API calls.

* Build file update and remove 0.7,0.9 solutions:
1.Updated Build file to configure Mnist sample
2.V0.10 sample changed when spam detection sample is added
3.Removed 0.7 and 0.9 samples
Latest commit ee509d4 Feb 8, 2019
Type Name Latest commit message Commit time
Failed to load latest commit information.
Data add recommendation sample Nov 22, 2018
MovieRecommendation Migration to v0.10 of all C# samples (#242) Feb 8, 2019
MovieRecommendation.sln add recommendation sample Nov 22, 2018 Migration to v0.10 of all C# samples (#242) Feb 8, 2019

Movie Recommendation - Matrix Factorization problem sample

ML.NET version API type Status App Type Data type Scenario ML Task Algorithms
v0.10 Dynamic API Updated to v0.9 Console app .csv files Recommendation Matrix Factorization MatrixFactorizationTrainer

In this sample, you can see how to use ML.NET to build a movie recommendation engine.


For this tutorial we will use the MovieLens dataset which comes with movie ratings, titles, genres and more. In terms of an approach for building our movie recommendation engine we will use Factorization Machines which uses a collaborative filtering approach.

‘Collaborative filtering’ operates under the underlying assumption that if a person A has the same opinion as a person B on an issue, A is more likely to have B’s opinion on a different issue than that of a randomly chosen person.

With ML.NET we support the following three recommendation scenarios, depending upon your scenario you can pick either of the three from the list below.

Scenario Algorithm Link To Sample
You have UserId, ProductId and Ratings available to you for what users bought and rated. Matrix Factorization This sample
You only have UserId and ProductId's the user bought available to you but not ratings. This is common in datasets from online stores where you might only have access to purchase history for your customers. With this style of recommendation you can build a recommendation engine which recommends frequently bought items. One Class Matrix Factorization Product Recommender
You want to use more attributes (features) beyond UserId, ProductId and Ratings like Product Description, Product Price etc. for your recommendation engine Field Aware Factorization Machines Movie Recommender with Factorization Machines


The original data comes from MovieLens Dataset:

ML task - Matrix Factorization (Recommendation)

The ML Task for this sample is Matrix Factorization, which is a supervised machine learning task performing collaborative filtering.


To solve this problem, you build and train an ML model on existing training data, evaluate how good it is (analyzing the obtained metrics), and lastly you can consume/test the model to predict the demand given input data variables.

Build -> Train -> Evaluate -> Consume

1. Build model

Building a model includes:

  • Define the data's schema mapped to the datasets to read (recommendation-ratings-train.csv and recommendation-ratings-test.csv) with a Textloader

  • Matrix Factorization requires the two features userId, movieId to be encoded

  • Matrix Factorization trainer then takes these two encoded features (userId, movieId) as input

Here's the code which will be used to build the model:

 //STEP 1: Create MLContext to be shared across the model creation workflow objects 
  MLContext mlcontext = new MLContext();

 //STEP 2: Read the training data which will be used to train the movie recommendation model    
 //The schema for training data is defined by type 'TInput' in ReadFromTextFile<TInput>() method.
 IDataView trainingDataView = mlcontext.Data.ReadFromTextFile<MovieRating>(TrainingDataLocation, hasHeader: true, ar:',');

//STEP 3: Transform your data by encoding the two features userId and movieID. These encoded features will be provided as 
//        to our MatrixFactorizationTrainer.
 var dataProcessingPipeline = mlcontext.Transforms.Conversion.MapValueToKey(outputColumnName: userIdEncoded, inputColumnName: eRating.userId))
                .Append(mlcontext.Transforms.Conversion.MapValueToKey(outputColumnName: movieIdEncoded, inputColumnName: nameofg.movieId)));
 //Specify the options for MatrixFactorization trainer
 MatrixFactorizationTrainer.Options options = new MatrixFactorizationTrainer.Options();
 options.MatrixColumnIndexColumnName = userIdEncoded;
 options.MatrixRowIndexColumnName = movieIdEncoded;
 options.LabelColumnName = DefaultColumnNames.Label;
 options.NumIterations = 20;
 options.K = 100;

//STEP 4: Create the training pipeline 
 var trainingPipeLine = dataProcessingPipeline.Append(mlcontext.Recommendation().Trainers.MatrixFactorization(options));

2. Train model

Training the model is a process of running the chosen algorithm on a training data (with known movie and user ratings) to tune the parameters of the model. It is implemented in the Fit() method from the Estimator object.

To perform training you need to call the Fit() method while providing the training dataset (recommendation-ratings-train.csv file) in a DataView object.

ITransformer model = trainingPipeLine.Fit(trainingDataView);

Note that ML.NET works with data with a lazy-load approach, so in reality no data is really loaded in memory until you actually call the method .Fit().

3. Evaluate model

We need this step to conclude how accurate our model operates on new data. To do so, the model from the previous step is run against another dataset that was not used in training (recommendation-ratings-test.csv).

Evaluate() compares the predicted values for the test dataset and produces various metrics, such as accuracy, you can explore.

Console.WriteLine("=============== Evaluating the model ===============");
IDataView testDataView = mlcontext.Data.ReadFromTextFile<MovieRating>(TestDataLocation, hasHeader: true); 
var prediction = model.Transform(testDataView);
var metrics = mlcontext.Regression.Evaluate(prediction, label: DefaultColumnNames.Label, score: DefaultColumnNames.Score);

4. Consume model

After the model is trained, you can use the Predict() API to predict the rating for a particular movie/user combination.

var predictionengine = model.MakePredictionFunction<MovieRating, MovieRatingPrediction>(mlcontext);
var movieratingprediction = predictionengine.Predict(
                new MovieRating()
                    //Example rating prediction for userId = 6, movieId = 10 (GoldenEye)
                    userId = predictionuserId,
                    movieId = predictionmovieId
 Console.WriteLine("For userId:" + predictionuserId + " movie rating prediction (1 - 5 stars) for movie:" +  
                   movieService.Get(predictionmovieId).movieTitle + " is:" + Math.Round(movieratingprediction.Score,1));

Please note this is one approach for performing movie recommendations with Matrix Factorization. There are other scenarios for recommendation as well which we will build samples for as well.