Simple matrix factorization class, learning is performed by stochastic gradient descent (SGD)

Factorizing the observed rating values using a factor matrix for users and one for items.

NaN values in the model occur if values become too large or too small to be represented by the type float. If you encounter such problems, there are three ways to fix them: (1) (preferred) Use BiasedMatrixFactorization, which is more stable. (2) Change the range of rating values (1 to 5 works generally well with the default settings). (3) Decrease the learn_rate.

This recommender supports incremental updates.

Inheritance: MyMediaLite.RatingPrediction.IncrementalRatingPredictor, IIterativeModel, IFoldInRatingPredictor
 public void TestMatrixInit()
 {
     var mf = new MatrixFactorization() { Ratings = TestUtils.CreateRatings() };
     mf.InitModel();
     Assert.IsNotNull(mf.user_factors);
     Assert.IsNotNull(mf.item_factors);
 }
        public void TestCurrentLearnRate()
        {
            var mf = new MatrixFactorization() { LearnRate = 1.1f, Ratings = TestUtils.CreateRatings() };

            mf.InitModel();
            Assert.AreEqual(1.1f, mf.LearnRate);
            Assert.AreEqual(1.1f, mf.current_learnrate);
        }
        IFoldInRatingPredictor CreateRecommender()
        {
            var training_data = RatingData.Read("../../../../data/ml-100k/u.data");
            var recommender = new MatrixFactorization();
            recommender.Ratings = training_data;
            recommender.NumFactors = 4;
            recommender.NumIter = 5;
            recommender.Train();

            return recommender;
        }
        public void TestDecay()
        {
            var mf = new MatrixFactorization()
            {
                LearnRate = 1.0f, Decay = 0.5f,
                NumIter = 1, Ratings = TestUtils.CreateRatings()
            };

            mf.Train();
            Assert.AreEqual(0.5f, mf.current_learnrate);

            mf.Iterate();
            Assert.AreEqual(0.25f, mf.current_learnrate);
        }
 public void TestDefaultBehaviorIsNoDecay()
 {
     var mf = new MatrixFactorization() { LearnRate = 1.1f, NumIter = 10, Ratings = TestUtils.CreateRatings() };
     mf.Train();
     Assert.AreEqual(1.1f, mf.current_learnrate);
 }
        public void TestMovieLensSingleDomain()
        {
            int numDomains = 1;

            // load data
            var movieLensReader = new MovieLensCrossDomainReader(Paths.MovieLens1MMovies, Paths.MovieLens1M);
            var container = new MovieLensCrossDomainContainer(numDomains);
            movieLensReader.LoadData(container);

            // set taget and active domains
            var targetDomain = container.SpecifyTargetDomain("ml0");
            container.PrintStatistics();

            var startTime = DateTime.Now;

            var splitter = new CrossDomainSimpleSplitter(container, 0.25f);

            // recommender with non-CrossDomain feature builder
            var model = new MatrixFactorization();
            model.NumIter = 50;
            model.NumFactors = 8;
            model.Regularization = 0.1f;
            //var recommender = new MediaLiteRatingPredictor(model);
            var recommender = new LibFmTrainTester();

            // evaluation
            var ctx = new EvalutationContext<ItemRating>(recommender, splitter);
            var ep = new EvaluationPipeline<ItemRating>(ctx);
            ep.Evaluators.Add(new RMSE());
            ep.Evaluators.Add(new MAE());
            ep.Run();
            var duration = (int)DateTime.Now.Subtract(startTime).TotalMilliseconds;

            Console.WriteLine("RMSE\tDuration\n{0}\t{1}", ctx["RMSE"], duration);

            //container.CreateClusterFiles(Paths.MovieLens1M.GetDirectoryPath() + "\\movies.clust.raw", Paths.MovieLens1M.GetDirectoryPath() + "\\movies.clust.feat");
            //container.WriteClusters(Paths.MovieLens1M.GetDirectoryPath() + "\\movies.clust");
        }