@@ -9,25 +9,32 @@ namespace Samples.Dynamic.Trainers.Recommendation
99 public static class MatrixFactorization
1010 {
1111
12- // This example requires installation of additional nuget package <a href="https://www.nuget.org/packages/Microsoft.ML.Recommender/">Microsoft.ML.Recommender</a>.
13- // In this example we will create in-memory data and then use it to train
14- // a matrix factorization model with default parameters. Afterward, quality metrics are reported.
12+ // This example requires installation of additional nuget package at
13+ // for Microsoft.ML.Recommender at
14+ // https://www.nuget.org/packages/Microsoft.ML.Recommender/
15+ // In this example we will create in-memory data and then use it to train
16+ // a matrix factorization model with default parameters. Afterward, quality
17+ // metrics are reported.
1518 public static void Example ( )
1619 {
17- // Create a new context for ML.NET operations. It can be used for exception tracking and logging,
18- // as a catalog of available operations and as the source of randomness.
19- // Setting the seed to a fixed number in this example to make outputs deterministic.
20+ // Create a new context for ML.NET operations. It can be used for
21+ // exception tracking and logging, as a catalog of available operations
22+ // and as the source of randomness. Setting the seed to a fixed number
23+ // in this example to make outputs deterministic.
2024 var mlContext = new MLContext ( seed : 0 ) ;
2125
2226 // Create a list of training data points.
2327 var dataPoints = GenerateMatrix ( ) ;
2428
25- // Convert the list of data points to an IDataView object, which is consumable by ML.NET API.
29+ // Convert the list of data points to an IDataView object, which is
30+ // consumable by ML.NET API.
2631 var trainingData = mlContext . Data . LoadFromEnumerable ( dataPoints ) ;
2732
2833 // Define the trainer.
29- var pipeline = mlContext . Recommendation ( ) . Trainers . MatrixFactorization ( nameof ( MatrixElement . Value ) , nameof ( MatrixElement . MatrixColumnIndex ) ,
30- nameof ( MatrixElement . MatrixRowIndex ) , 10 , 0.2 , 1 ) ;
34+ var pipeline = mlContext . Recommendation ( ) . Trainers .
35+ MatrixFactorization ( nameof ( MatrixElement . Value ) ,
36+ nameof ( MatrixElement . MatrixColumnIndex ) ,
37+ nameof ( MatrixElement . MatrixRowIndex ) , 10 , 0.2 , 1 ) ;
3138
3239 // Train the model.
3340 var model = pipeline . Fit ( trainingData ) ;
@@ -36,11 +43,15 @@ public static void Example()
3643 var transformedData = model . Transform ( trainingData ) ;
3744
3845 // Convert IDataView object to a list.
39- var predictions = mlContext . Data . CreateEnumerable < MatrixElement > ( transformedData , reuseRowObject : false ) . Take ( 5 ) . ToList ( ) ;
46+ var predictions = mlContext . Data
47+ . CreateEnumerable < MatrixElement > ( transformedData ,
48+ reuseRowObject : false ) . Take ( 5 ) . ToList ( ) ;
4049
41- // Look at 5 predictions for the Label, side by side with the actual Label for comparison.
50+ // Look at 5 predictions for the Label, side by side with the actual
51+ // Label for comparison.
4252 foreach ( var p in predictions )
43- Console . WriteLine ( $ "Actual value: { p . Value : F3} , Predicted score: { p . Score : F3} ") ;
53+ Console . WriteLine ( $ "Actual value: { p . Value : F3} ," +
54+ $ "Predicted score: { p . Score : F3} ") ;
4455
4556 // Expected output:
4657 // Actual value: 0.000, Predicted score: 1.234
@@ -50,7 +61,10 @@ public static void Example()
5061 // Actual value: 4.000, Predicted score: 2.362
5162
5263 // Evaluate the overall metrics
53- var metrics = mlContext . Regression . Evaluate ( transformedData , labelColumnName : nameof ( MatrixElement . Value ) , scoreColumnName : nameof ( MatrixElement . Score ) ) ;
64+ var metrics = mlContext . Regression . Evaluate ( transformedData ,
65+ labelColumnName : nameof ( MatrixElement . Value ) ,
66+ scoreColumnName : nameof ( MatrixElement . Score ) ) ;
67+
5468 PrintMetrics ( metrics ) ;
5569
5670 // Expected output:
@@ -60,11 +74,15 @@ public static void Example()
6074 // RSquared: 0.61 (closer to 1 is better. The worest case is 0)
6175 }
6276
63- // The following variables are used to define the shape of the example matrix. Its shape is MatrixRowCount-by-MatrixColumnCount.
64- // Because in ML.NET key type's minimal value is zero, the first row index is always zero in C# data structure (e.g., MatrixColumnIndex=0
65- // and MatrixRowIndex=0 in MatrixElement below specifies the value at the upper-left corner in the training matrix). If user's row index
66- // starts with 1, their row index 1 would be mapped to the 2nd row in matrix factorization module and their first row may contain no values.
67- // This behavior is also true to column index.
77+ // The following variables are used to define the shape of the example
78+ // matrix. Its shape is MatrixRowCount-by-MatrixColumnCount. Because in
79+ // ML.NET key type's minimal value is zero, the first row index is always
80+ // zero in C# data structure (e.g., MatrixColumnIndex=0 and MatrixRowIndex=0
81+ // in MatrixElement below specifies the value at the upper-left corner in
82+ // the training matrix). If user's row index starts with 1, their row index
83+ // 1 would be mapped to the 2nd row in matrix factorization module and their
84+ // first row may contain no values. This behavior is also true to column
85+ // index.
6886 private const uint MatrixColumnCount = 60 ;
6987 private const uint MatrixRowCount = 100 ;
7088
@@ -74,32 +92,40 @@ private static List<MatrixElement> GenerateMatrix()
7492 var dataMatrix = new List < MatrixElement > ( ) ;
7593 for ( uint i = 0 ; i < MatrixColumnCount ; ++ i )
7694 for ( uint j = 0 ; j < MatrixRowCount ; ++ j )
77- dataMatrix . Add ( new MatrixElement ( ) { MatrixColumnIndex = i , MatrixRowIndex = j , Value = ( i + j ) % 5 } ) ;
95+ dataMatrix . Add ( new MatrixElement ( ) { MatrixColumnIndex = i ,
96+ MatrixRowIndex = j , Value = ( i + j ) % 5 } ) ;
97+
7898 return dataMatrix ;
7999 }
80100
81- // A class used to define a matrix element and capture its prediction result.
101+ // A class used to define a matrix element and capture its prediction
102+ // result.
82103 private class MatrixElement
83104 {
84- // Matrix column index. Its allowed range is from 0 to MatrixColumnCount - 1.
105+ // Matrix column index. Its allowed range is from 0 to
106+ // MatrixColumnCount - 1.
85107 [ KeyType ( MatrixColumnCount ) ]
86108 public uint MatrixColumnIndex { get ; set ; }
87109 // Matrix row index. Its allowed range is from 0 to MatrixRowCount - 1.
88110 [ KeyType ( MatrixRowCount ) ]
89111 public uint MatrixRowIndex { get ; set ; }
90- // The actual value at the MatrixColumnIndex-th column and the MatrixRowIndex-th row.
112+ // The actual value at the MatrixColumnIndex-th column and the
113+ // MatrixRowIndex-th row.
91114 public float Value { get ; set ; }
92- // The predicted value at the MatrixColumnIndex-th column and the MatrixRowIndex-th row.
115+ // The predicted value at the MatrixColumnIndex-th column and the
116+ // MatrixRowIndex-th row.
93117 public float Score { get ; set ; }
94118 }
95119
96120 // Print some evaluation metrics to regression problems.
97121 private static void PrintMetrics ( RegressionMetrics metrics )
98122 {
99- Console . WriteLine ( $ "Mean Absolute Error: { metrics . MeanAbsoluteError : F2} ") ;
100- Console . WriteLine ( $ "Mean Squared Error: { metrics . MeanSquaredError : F2} ") ;
101- Console . WriteLine ( $ "Root Mean Squared Error: { metrics . RootMeanSquaredError : F2} ") ;
102- Console . WriteLine ( $ "RSquared: { metrics . RSquared : F2} ") ;
123+ Console . WriteLine ( "Mean Absolute Error: " + metrics . MeanAbsoluteError ) ;
124+ Console . WriteLine ( "Mean Squared Error: " + metrics . MeanSquaredError ) ;
125+ Console . WriteLine ( "Root Mean Squared Error: " +
126+ metrics . RootMeanSquaredError ) ;
127+
128+ Console . WriteLine ( "RSquared: " + metrics . RSquared ) ;
103129 }
104130 }
105131}
0 commit comments