private void CreateRecommender() { BiasedMatrixFactorization recommender = new BiasedMatrixFactorization(); Console.Error.Write("Reading in ratings ... "); TimeSpan time = Wrap.MeasureTime(delegate() { recommender.Ratings = RatingData.Read(ratings_file, user_mapping, item_mapping); }); Console.Error.WriteLine("done ({0,0:0.##}).", time.TotalSeconds.ToString(CultureInfo.InvariantCulture)); //Console.Error.Write("Reading in additional ratings ... "); //string[] rating_files = Directory.GetFiles("../../saved_data/", "user-ratings-*"); //Console.Error.WriteLine("done."); foreach (var indices_for_item in recommender.Ratings.ByItem) { if (indices_for_item.Count > 0) { movies_by_frequency.Add(new Tuple <int, float>(recommender.Ratings.Items[indices_for_item[0]], indices_for_item.Count)); } } movies_by_frequency = movies_by_frequency.OrderByDescending(x => x.Item2).ToList(); for (int i = 0; i < n_movies; i++) { top_n_movies.Add(movies_by_frequency[i].Item1); } Console.Error.Write("Loading prediction model ... "); recommender.UpdateUsers = true; recommender.UpdateItems = false; recommender.BiasReg = 0.001f; recommender.Regularization = 0.045f; recommender.NumIter = 60; time = Wrap.MeasureTime(delegate() { recommender.LoadModel(model_file); }); Console.Error.WriteLine("done ({0,0:0.##}).", time.TotalSeconds.ToString(CultureInfo.InvariantCulture)); rating_predictor = recommender; current_user_id = user_mapping.ToInternalID(current_user_external_id.ToString()); //rating_predictor.AddUser(current_user_id); // add movies that were not in the training set //rating_predictor.AddItem( item_mapping.InternalIDs.Count - 1 ); PredictAllRatings(); }
/// <summary>Performs user-wise fold-in evaluation, but instead of folding in perform incremental training with the new data</summary> /// <remarks> /// </remarks> /// <returns>the evaluation results</returns> /// <param name='recommender'>a rating predictor capable of performing a user fold-in</param> /// <param name='update_data'>the rating data used to represent the users</param> /// <param name='eval_data'>the evaluation data</param> static public RatingPredictionEvaluationResults EvaluateFoldInIncrementalTraining(this IncrementalRatingPredictor recommender, IRatings update_data, IRatings eval_data) { double rmse = 0; double mae = 0; double cbd = 0; int rating_count = 0; foreach (int user_id in update_data.AllUsers) { if (eval_data.AllUsers.Contains(user_id)) { var local_recommender = (IncrementalRatingPredictor)recommender.Clone(); // add ratings and perform incremental training var user_ratings = new RatingsProxy(update_data, update_data.ByUser[user_id]); local_recommender.AddRatings(user_ratings); var items_to_rate = (from index in eval_data.ByUser[user_id] select eval_data.Items[index]).ToArray(); var predicted_ratings = recommender.Recommend(user_id, candidate_items: items_to_rate); foreach (var pred in predicted_ratings) { float prediction = pred.Item2; float actual_rating = eval_data.Get(user_id, pred.Item1, eval_data.ByUser[user_id]); float error = prediction - actual_rating; rmse += error * error; mae += Math.Abs(error); cbd += Eval.Ratings.ComputeCBD(actual_rating, prediction, recommender.MinRating, recommender.MaxRating); rating_count++; } // remove ratings again local_recommender.RemoveRatings(user_ratings); Console.Error.Write("."); } } mae = mae / rating_count; rmse = Math.Sqrt(rmse / rating_count); cbd = cbd / rating_count; var result = new RatingPredictionEvaluationResults(); result["RMSE"] = (float)rmse; result["MAE"] = (float)mae; result["NMAE"] = (float)mae / (recommender.MaxRating - recommender.MinRating); result["CBD"] = (float)cbd; return(result); }