@@ -89,8 +89,19 @@ namespace Microsoft.ML.Trainers
89
89
public sealed class MatrixFactorizationTrainer : TrainerBase < MatrixFactorizationPredictor > ,
90
90
IEstimator < MatrixFactorizationPredictionTransformer >
91
91
{
92
+ public enum LossFunctionType { SquareLossRegression = 0 , SquareLossOneClass = 12 } ;
93
+
92
94
public sealed class Arguments
93
95
{
96
+ /// <summary>
97
+ /// Loss function minimized for finding factor matrices. Two values are allowed, 0 or 12. The values 0 means traditional collaborative filtering
98
+ /// problem with squared loss. The value 12 triggers one-class matrix factorization for implicit-feedback recommendation problem.
99
+ /// </summary>
100
+ [ Argument ( ArgumentType . AtMostOnce , HelpText = "Loss function minimized for finding factor matrices." ) ]
101
+ [ TGUI ( SuggestedSweeps = "0,12" ) ]
102
+ [ TlcModule . SweepableDiscreteParam ( "LossFunction" , new object [ ] { LossFunctionType . SquareLossRegression , LossFunctionType . SquareLossOneClass } ) ]
103
+ public LossFunctionType LossFunction = LossFunctionType . SquareLossRegression ;
104
+
94
105
[ Argument ( ArgumentType . AtMostOnce , HelpText = "Regularization parameter. " +
95
106
"It's the weight of factor matrices' norms in the objective function minimized by matrix factorization's algorithm. " +
96
107
"A small value could cause over-fitting." ) ]
@@ -116,6 +127,33 @@ public sealed class Arguments
116
127
[ TlcModule . SweepableDiscreteParam ( "Eta" , new object [ ] { 0.001f , 0.01f , 0.1f } ) ]
117
128
public double Eta = 0.1 ;
118
129
130
+ /// <summary>
131
+ /// Importance of unobserved (i.e., negative) entries' loss in one-class matrix factorization.
132
+ /// In general, only a few of matrix entries (e.g., less than 1%) in the training are observed (i.e., positive).
133
+ /// To balance the contributions from unobserved and obverved in the overall loss function, this parameter is
134
+ /// usually a small value so that the solver is able to find a factorization equally good to unobserved and observed
135
+ /// entries. If only 10000 observed entries present in a 200000-by-300000 training matrix, one can try Alpha = 10000 / (200000*300000 - 10000).
136
+ /// When most entries in the training matrix are observed, one can use Alpha >> 1; for example, if only 10000 in previous
137
+ /// matrix is not observed, one can try Alpha = (200000 * 300000 - 10000) / 10000. Consequently,
138
+ /// Alpha = (# of observed entries) / (# of unobserved entries) can make observed and unobserved entries equally important
139
+ /// in the minimized loss function. However, the best setting in machine learning is alwasy data-depedent so user still needs to
140
+ /// try multiple values.
141
+ /// </summary>
142
+ [ Argument ( ArgumentType . AtMostOnce , HelpText = "Importance of unobserved entries' loss in one-class matrix factorization." ) ]
143
+ [ TGUI ( SuggestedSweeps = "1,0.01,0.0001,0.000001" ) ]
144
+ [ TlcModule . SweepableDiscreteParam ( "Alpha" , new object [ ] { 1f , 0.01f , 0.0001f , 0.000001f } ) ]
145
+ public double Alpha = 0.0001 ;
146
+
147
+ /// <summary>
148
+ /// Desired negative entries value in one-class matrix factorization. In one-class matrix factorization, all matrix values observed are one
149
+ /// (which can be viewed as positive cases in binary classification) while unobserved values (which can be viewed as negative cases in binary
150
+ /// classification) need to be specified manually using this option.
151
+ /// </summary>
152
+ [ Argument ( ArgumentType . AtMostOnce , HelpText = "Desired negative entries' value in one-class matrix factorization" ) ]
153
+ [ TGUI ( SuggestedSweeps = "0.000001,0,0001,0.01" ) ]
154
+ [ TlcModule . SweepableDiscreteParam ( "C" , new object [ ] { 0.000001f , 0.0001f , 0.01f } ) ]
155
+ public double C = 0.000001f ;
156
+
119
157
[ Argument ( ArgumentType . AtMostOnce , HelpText = "Number of threads can be used in the training procedure." , ShortName = "t" ) ]
120
158
public int ? NumThreads ;
121
159
@@ -131,10 +169,13 @@ public sealed class Arguments
131
169
+ "and the values of the matrix are ratings. " ;
132
170
133
171
// LIBMF's parameter
172
+ private readonly int _fun ;
134
173
private readonly double _lambda ;
135
174
private readonly int _k ;
136
175
private readonly int _iter ;
137
176
private readonly double _eta ;
177
+ private readonly double _alpha ;
178
+ private readonly double _c ;
138
179
private readonly int _threads ;
139
180
private readonly bool _quiet ;
140
181
private readonly bool _doNmf ;
@@ -192,11 +233,15 @@ public MatrixFactorizationTrainer(IHostEnvironment env, Arguments args) : base(e
192
233
Host . CheckUserArg ( args . NumIterations > 0 , nameof ( args . NumIterations ) , posError ) ;
193
234
Host . CheckUserArg ( args . Lambda > 0 , nameof ( args . Lambda ) , posError ) ;
194
235
Host . CheckUserArg ( args . Eta > 0 , nameof ( args . Eta ) , posError ) ;
236
+ Host . CheckUserArg ( args . Alpha > 0 , nameof ( args . Alpha ) , posError ) ;
195
237
238
+ _fun = ( int ) args . LossFunction ;
196
239
_lambda = args . Lambda ;
197
240
_k = args . K ;
198
241
_iter = args . NumIterations ;
199
242
_eta = args . Eta ;
243
+ _alpha = args . Alpha ;
244
+ _c = args . C ;
200
245
_threads = args . NumThreads ?? Environment . ProcessorCount ;
201
246
_quiet = args . Quiet ;
202
247
_doNmf = args . NonNegative ;
@@ -224,10 +269,13 @@ public MatrixFactorizationTrainer(IHostEnvironment env,
224
269
var args = new Arguments ( ) ;
225
270
advancedSettings ? . Invoke ( args ) ;
226
271
272
+ _fun = ( int ) args . LossFunction ;
227
273
_lambda = args . Lambda ;
228
274
_k = args . K ;
229
275
_iter = args . NumIterations ;
230
276
_eta = args . Eta ;
277
+ _alpha = args . Alpha ;
278
+ _c = args . C ;
231
279
_threads = args . NumThreads ?? Environment . ProcessorCount ;
232
280
_quiet = args . Quiet ;
233
281
_doNmf = args . NonNegative ;
@@ -338,8 +386,8 @@ private MatrixFactorizationPredictor TrainCore(IChannel ch, RoleMappedData data,
338
386
339
387
private SafeTrainingAndModelBuffer PrepareBuffer ( )
340
388
{
341
- return new SafeTrainingAndModelBuffer ( Host , _k , Math . Max ( 20 , 2 * _threads ) ,
342
- _threads , _iter , _lambda , _eta , _doNmf , _quiet , copyData : false ) ;
389
+ return new SafeTrainingAndModelBuffer ( Host , _fun , _k , _threads , Math . Max ( 20 , 2 * _threads ) ,
390
+ _iter , _lambda , _eta , _alpha , _c , _doNmf , _quiet , copyData : false ) ;
343
391
}
344
392
345
393
/// <summary>
0 commit comments