/// <summary>Computes the squared error sum</summary> /// <returns>the squared error sum</returns> /// <param name='recommender'>the recommender to make predictions with</param> /// <param name='ratings'>the actual ratings</param> public static double ComputeSquaredErrorSum(this IRatingPredictor recommender, IRatings ratings) { double sum = 0; for (int i = 0; i < ratings.Count; i++) sum += Math.Pow(recommender.Predict(ratings.Users[i], ratings.Items[i]) - ratings[i], 2); return sum; }
/// <summary>Evaluates a rating predictor for RMSE, MAE, and NMAE</summary> /// <remarks> /// For NMAE, see "Eigentaste: A Constant Time Collaborative Filtering Algorithm" by Goldberg et al. /// </remarks> /// <param name="recommender">rating predictor</param> /// <param name="ratings">Test cases</param> /// <returns>a Dictionary containing the evaluation results</returns> public static Dictionary<string, double> Evaluate(IRatingPredictor recommender, IRatings ratings) { double rmse = 0; double mae = 0; if (recommender == null) throw new ArgumentNullException("recommender"); if (ratings == null) throw new ArgumentNullException("ratings"); for (int index = 0; index < ratings.Count; index++) { double error = (recommender.Predict(ratings.Users[index], ratings.Items[index]) - ratings[index]); rmse += error * error; mae += Math.Abs(error); } mae = mae / ratings.Count; rmse = Math.Sqrt(rmse / ratings.Count); var result = new Dictionary<string, double>(); result["RMSE"] = rmse; result["MAE"] = mae; result["NMAE"] = mae / (recommender.MaxRating - recommender.MinRating); return result; }
/// <summary>Create a AdjustedCosine matrix from given data</summary> /// <param name="ratings">the ratings data</param> /// <param name="entity_type">the entity type, either USER or ITEM</param> /// <param name="shrinkage">a shrinkage parameter</param> /// <returns>the complete AdjustedCosine matrix</returns> static public CorrelationMatrix Create(IRatings ratings, EntityType entity_type, float shrinkage) { AdjustedCosine cm; int num_entities = 0; if (entity_type.Equals(EntityType.USER)) { num_entities = ratings.MaxUserID + 1; } else if (entity_type.Equals(EntityType.ITEM)) { num_entities = ratings.MaxItemID + 1; } else { throw new ArgumentException("Unknown entity type: " + entity_type); } try { cm = new AdjustedCosine(num_entities); } catch (OverflowException) { Console.Error.WriteLine("Too many entities: " + num_entities); throw; } cm.shrinkage = shrinkage; cm.ComputeCorrelations(ratings, entity_type); return(cm); }
/// <summary>Predict ratings (double precision)</summary> /// <param name="recommender">the recommender to use</param> /// <param name="ratings">the ratings to predict</param> /// <param name="writer">the writer object to write the predictions to</param> public static void PredictRatingsDouble(IRecommender recommender, IRatings ratings, BinaryWriter writer) { for (int i = 0; i < ratings.Count; i++) { writer.Write(recommender.Predict(ratings.Users[i], ratings.Items[i]).ToString(CultureInfo.InvariantCulture)); } }
/// <summary>Compute correlations between two entities for given ratings</summary> /// <param name="ratings">the rating data</param> /// <param name="entity_type">the entity type, either USER or ITEM</param> /// <param name="i">the ID of first entity</param> /// <param name="j">the ID of second entity</param> /// <param name="shrinkage">the shrinkage parameter</param> public static float ComputeCorrelation(IRatings ratings, EntityType entity_type, int i, int j, float shrinkage) { if (i == j) return 1; IList<int> ratings1 = (entity_type == EntityType.USER) ? ratings.ByUser[i] : ratings.ByItem[i]; IList<int> ratings2 = (entity_type == EntityType.USER) ? ratings.ByUser[j] : ratings.ByItem[j]; // get common ratings for the two entities HashSet<int> e1 = (entity_type == EntityType.USER) ? ratings.GetItems(ratings1) : ratings.GetUsers(ratings1); HashSet<int> e2 = (entity_type == EntityType.USER) ? ratings.GetItems(ratings2) : ratings.GetUsers(ratings2); e1.IntersectWith(e2); int n = e1.Count; if (n < 2) return 0; List<Ratings> ratings_by_other_entity = (entity_type == EntityType.USER) ? ratings.ByItem : ratings.ByUser; double sum_ij = 0; double sum_ii = 0; double sum_jj = 0; foreach (int other_entity_id in e1) { double average_rating = ratings_by_other_entity[other_entity_id].Average; // get ratings double r1 = 0; double r2 = 0; if (entity_type == EntityType.USER) { r1 = ratings.Get(i, other_entity_id, ratings1); r2 = ratings.Get(j, other_entity_id, ratings2); } else { r1 = ratings.Get(other_entity_id, i, ratings1); r2 = ratings.Get(other_entity_id, j, ratings2); } double dev_i = r1 - average_rating; double dev_j = r2 - average_rating; // update sums sum_ij += dev_i * dev_j; sum_ii += dev_i * dev_i; sum_jj += dev_j * dev_j; } double denominator = Math.Sqrt( sum_ii * sum_jj ); if (denominator == 0) return 0; double adjusted_cosine = sum_ij / denominator; return (float) adjusted_cosine * (n / (n + shrinkage)); }
/// <summary>Rate a given set of instances and write it to a TextWriter</summary> /// <param name="recommender">rating predictor</param> /// <param name="ratings">test cases</param> /// <param name="user_mapping">an <see cref="EntityMapping"/> object for the user IDs</param> /// <param name="item_mapping">an <see cref="EntityMapping"/> object for the item IDs</param> /// <param name="writer">the TextWriter to write the predictions to</param> public static void WritePredictions( IRatingPredictor recommender, IRatings ratings, IEntityMapping user_mapping, IEntityMapping item_mapping, TextWriter writer) { WritePredictions(recommender, ratings, user_mapping, item_mapping, "{0}\t{1}\t{2}", writer); }
/// public override void UpdateRatings(IRatings new_ratings) { base.UpdateRatings(new_ratings); foreach (int user_id in new_ratings.AllUsers) { Retrain(user_id, Ratings.ByUser[user_id]); } }
/// public override void UpdateRatings(IRatings ratings) { base.UpdateRatings(ratings); foreach (int item_id in ratings.AllItems) { Retrain(item_id, Ratings.ByItem[item_id]); } }
/// public override void UpdateRatings(IRatings ratings) { baseline_predictor.UpdateRatings(ratings); foreach (int user_id in ratings.AllUsers) { RetrainUser(user_id); } }
/// public override void UpdateRatings(IRatings ratings) { baseline_predictor.UpdateRatings(ratings); foreach (int item_id in ratings.AllItems) { RetrainItem(item_id); } }
public WorksController(IGenres serv, IWorks serv1, IUsers serv2, IComments serv3, IRatings serv4) { commentServ = serv3; userServ = serv2; workServ = serv1; genreServ = serv; ratingServ = serv4; }
/// public override void AddRatings(IRatings ratings) { baseline_predictor.AddRatings(ratings); for (int index = 0; index < ratings.Count; index++) data_user[ratings.Users[index], ratings.Items[index]] = true; foreach (int user_id in ratings.AllUsers) RetrainUser(user_id); }
/// <summary>Rate a given set of instances and write it to a file</summary> /// <param name="recommender">rating predictor</param> /// <param name="ratings">test cases</param> /// <param name="user_mapping">an <see cref="EntityMapping"/> object for the user IDs</param> /// <param name="item_mapping">an <see cref="EntityMapping"/> object for the item IDs</param> /// <param name="filename">the name of the file to write the predictions to</param> public static void WritePredictions( IRatingPredictor recommender, IRatings ratings, IEntityMapping user_mapping, IEntityMapping item_mapping, string filename) { WritePredictions(recommender, ratings, user_mapping, item_mapping, "{0}\t{1}\t{2}", filename); }
/// <summary>Create a CombinedRatings object from to existing IRatings objects</summary> /// <param name="ratings1">the first data set</param> /// <param name="ratings2">the second data set</param> public CombinedRatings(IRatings ratings1, IRatings ratings2) { Users = new CombinedList<int>(ratings1.Users, ratings2.Users); Items = new CombinedList<int>(ratings1.Items, ratings2.Items); Values = new CombinedList<double>(ratings1, ratings2); MaxUserID = Math.Max(ratings1.MaxUserID, ratings2.MaxUserID); MaxItemID = Math.Max(ratings1.MaxItemID, ratings2.MaxItemID); }
/// <summary>Create a CombinedRatings object from to existing IRatings objects</summary> /// <param name="ratings1">the first data set</param> /// <param name="ratings2">the second data set</param> public CombinedRatings(IRatings ratings1, IRatings ratings2) { Users = new CombinedList <int>(ratings1.Users, ratings2.Users); Items = new CombinedList <int>(ratings1.Items, ratings2.Items); Values = new CombinedList <double>(ratings1, ratings2); MaxUserID = Math.Max(ratings1.MaxUserID, ratings2.MaxUserID); MaxItemID = Math.Max(ratings1.MaxItemID, ratings2.MaxItemID); }
public RateColleagueController(IRepository<Person> personRepository, IRepository<PersonRating> personratingRepository, IRatings ratings) { //_personRepository = new Repository<Person>(); //_personratingRepository = new Repository<personrating>(); _personRepository = personRepository; _personratingRepository = personratingRepository; _ratings = ratings; }
/// public float ComputeCorrelation(IRatings ratings, EntityType entity_type, IList <Tuple <int, float> > entity_ratings, int j) { IList <int> indexes2 = (entity_type == EntityType.USER) ? ratings.ByUser[j] : ratings.ByItem[j]; // get common ratings for the two entities var e1 = new HashSet <int>(from pair in entity_ratings select pair.Item1); var e2 = (entity_type == EntityType.USER) ? ratings.GetItems(indexes2) : ratings.GetUsers(indexes2); e1.IntersectWith(e2); var ratings1 = new Dictionary <int, float>(); for (int index = 0; index < entity_ratings.Count; index++) { if (e1.Contains(entity_ratings[index].Item1)) { ratings1.Add(entity_ratings[index].Item1, entity_ratings[index].Item2); } } int n = e1.Count; if (n < 2) { return(0); } // single-pass variant double i_sum = 0; double j_sum = 0; double ij_sum = 0; double ii_sum = 0; double jj_sum = 0; foreach (int other_entity_id in e1) { // get ratings float r1 = ratings1[other_entity_id]; float r2 = 0; if (entity_type == EntityType.USER) { r2 = ratings.Get(j, other_entity_id, indexes2); } else { r2 = ratings.Get(other_entity_id, j, indexes2); } // update sums i_sum += r1; j_sum += r2; ij_sum += r1 * r2; ii_sum += r1 * r1; jj_sum += r2 * r2; } return(ComputeCorrelation(i_sum, j_sum, ii_sum, jj_sum, ij_sum, n)); }
/// <summary>Predict ratings for Track 1</summary> /// <param name="recommender">the recommender to use</param> /// <param name="ratings">the ratings to predict</param> /// <param name="writer">the writer object to write the predictions to</param> public static void PredictRatings(IRecommender recommender, IRatings ratings, BinaryWriter writer) { for (int i = 0; i < ratings.Count; i++) { double prediction = recommender.Predict(ratings.Users[i], ratings.Items[i]); byte encoded_prediction = (byte)(2.55 * prediction + 0.5); writer.Write(encoded_prediction); } }
/// public float ComputeCorrelation(IRatings ratings, EntityType entity_type, int i, int j) { if (i == j) { return(1); } IList <int> indexes1 = (entity_type == EntityType.USER) ? ratings.ByUser[i] : ratings.ByItem[i]; IList <int> indexes2 = (entity_type == EntityType.USER) ? ratings.ByUser[j] : ratings.ByItem[j]; // get common ratings for the two entities var e1 = (entity_type == EntityType.USER) ? ratings.GetItems(indexes1) : ratings.GetUsers(indexes1); var e2 = (entity_type == EntityType.USER) ? ratings.GetItems(indexes2) : ratings.GetUsers(indexes2); e1.IntersectWith(e2); int n = e1.Count; if (n < 2) { return(0); } // single-pass variant double i_sum = 0; double j_sum = 0; double ij_sum = 0; double ii_sum = 0; double jj_sum = 0; foreach (int other_entity_id in e1) { // get ratings float r1 = 0; float r2 = 0; if (entity_type == EntityType.USER) { r1 = ratings.Get(i, other_entity_id, indexes1); r2 = ratings.Get(j, other_entity_id, indexes2); } else { r1 = ratings.Get(other_entity_id, i, indexes1); r2 = ratings.Get(other_entity_id, j, indexes2); } // update sums i_sum += r1; j_sum += r2; ij_sum += r1 * r2; ii_sum += r1 * r1; jj_sum += r2 * r2; } return(ComputeCorrelation(i_sum, j_sum, ii_sum, jj_sum, ij_sum, n)); }
/// <summary>Compute correlations between two entities for given ratings</summary> /// <param name="ratings">the rating data</param> /// <param name="entity_type">the entity type, either USER or ITEM</param> /// <param name="i">the ID of first entity</param> /// <param name="j">the ID of second entity</param> /// <param name="shrinkage">the shrinkage parameter</param> public static float ComputeCorrelation(IRatings ratings, EntityType entity_type, int i, int j, float shrinkage) { if (i == j) return 1; IList<int> ratings1 = (entity_type == EntityType.USER) ? ratings.ByUser[i] : ratings.ByItem[i]; IList<int> ratings2 = (entity_type == EntityType.USER) ? ratings.ByUser[j] : ratings.ByItem[j]; // get common ratings for the two entities HashSet<int> e1 = (entity_type == EntityType.USER) ? ratings.GetItems(ratings1) : ratings.GetUsers(ratings1); HashSet<int> e2 = (entity_type == EntityType.USER) ? ratings.GetItems(ratings2) : ratings.GetUsers(ratings2); e1.IntersectWith(e2); int n = e1.Count; if (n < 2) return 0; // single-pass variant double i_sum = 0; double j_sum = 0; double ij_sum = 0; double ii_sum = 0; double jj_sum = 0; foreach (int other_entity_id in e1) { // get ratings double r1 = 0; double r2 = 0; if (entity_type == EntityType.USER) { r1 = ratings.Get(i, other_entity_id, ratings1); r2 = ratings.Get(j, other_entity_id, ratings2); } else { r1 = ratings.Get(other_entity_id, i, ratings1); r2 = ratings.Get(other_entity_id, j, ratings2); } // update sums i_sum += r1; j_sum += r2; ij_sum += r1 * r2; ii_sum += r1 * r1; jj_sum += r2 * r2; } double denominator = Math.Sqrt( (n * ii_sum - i_sum * i_sum) * (n * jj_sum - j_sum * j_sum) ); if (denominator == 0) return 0; double pmcc = (n * ij_sum - i_sum * j_sum) / denominator; return (float) pmcc * (n / (n + shrinkage)); }
/// <summary>Create a CombinedRatings object from to existing IRatings objects</summary> /// <param name="ratings1">the first data set</param> /// <param name="ratings2">the second data set</param> public CombinedRatings(IRatings ratings1, IRatings ratings2) { Users = new CombinedList <int>(ratings1.Users, ratings2.Users); Items = new CombinedList <int>(ratings1.Items, ratings2.Items); Values = new CombinedList <float>(ratings1, ratings2); Scale = new RatingScale(ratings1.Scale, ratings2.Scale); MaxUserID = Math.Max(ratings1.MaxUserID, ratings2.MaxUserID); MaxItemID = Math.Max(ratings1.MaxItemID, ratings2.MaxItemID); }
/// <summary>Create a CombinedRatings object from to existing IRatings objects</summary> /// <param name="ratings1">the first data set</param> /// <param name="ratings2">the second data set</param> public CombinedRatings(IRatings ratings1, IRatings ratings2) { Users = new CombinedList<int>(ratings1.Users, ratings2.Users); Items = new CombinedList<int>(ratings1.Items, ratings2.Items); Values = new CombinedList<float>(ratings1, ratings2); Scale = new RatingScale(ratings1.Scale, ratings2.Scale); MaxUserID = Math.Max(ratings1.MaxUserID, ratings2.MaxUserID); MaxItemID = Math.Max(ratings1.MaxItemID, ratings2.MaxItemID); }
public PersonRateController(IRepository<Person> personRepository,IRepository<Team> teamRepository,IRepository<PersonRating> personratingRepository, IRatings ratings, IRatingPeriod ratingPeriod,IRepository<Configuration> config) { _configRepository = config; _ratingPeriod = ratingPeriod; _ratingPeriod.GetCurrentPeriod(); _personRepository = personRepository; _personratingRepository = personratingRepository; _teamRepository = teamRepository; _ratings = ratings; }
/// <summary>Rate a given set of instances and write it to a TextWriter</summary> /// <param name="recommender">rating predictor</param> /// <param name="ratings">test cases</param> /// <param name="writer">the TextWriter to write the predictions to</param> /// <param name="user_mapping">an <see cref="Mapping"/> object for the user IDs</param> /// <param name="item_mapping">an <see cref="Mapping"/> object for the item IDs</param> /// <param name="line_format">a format string specifying the line format; {0} is the user ID, {1} the item ID, {2} the rating</param> /// <param name="header">if specified, write this string at the start of the output</param> public static void WritePredictions( this IRecommender recommender, IRatings ratings, TextWriter writer, IMapping user_mapping = null, IMapping item_mapping = null, string line_format = "{0}\t{1}\t{2}", string header = null) { if (user_mapping == null) { user_mapping = new IdentityMapping(); } if (item_mapping == null) { item_mapping = new IdentityMapping(); } if (header != null) { writer.WriteLine(header); } if (line_format == "ranking") { foreach (int user_id in ratings.AllUsers) { if (ratings.ByUser[user_id].Count > 0) { recommender.WritePredictions( user_id, new List <int>(from index in ratings.ByUser[user_id] select ratings.Items[index]), new int[] { }, ratings.ByUser[user_id].Count, writer, user_mapping, item_mapping); } } } else { for (int index = 0; index < ratings.Count; index++) { writer.WriteLine( string.Format( CultureInfo.InvariantCulture, line_format, user_mapping.ToOriginalID(ratings.Users[index]), item_mapping.ToOriginalID(ratings.Items[index]), recommender.Predict(ratings.Users[index], ratings.Items[index]) ) ); } } }
/// <summary>Create a RatingsProxy object</summary> /// <param name="ratings">a ratings data structure</param> /// <param name="indices">an index list pointing to entries in the ratings</param> public RatingsProxy(IRatings ratings, IList<int> indices) { Users = new ListProxy<int>(ratings.Users, indices); Items = new ListProxy<int>(ratings.Items, indices); Values = new ListProxy<double>(ratings, indices); MaxUserID = ratings.MaxUserID; MaxItemID = ratings.MaxItemID; MaxRating = ratings.MaxRating; MinRating = ratings.MinRating; }
/// <summary>Create a RatingsProxy object</summary> /// <param name="ratings">a ratings data structure</param> /// <param name="indices">an index list pointing to entries in the ratings</param> public RatingsProxy(IRatings ratings, IList <int> indices) { Users = new ListProxy <int>(ratings.Users, indices); Items = new ListProxy <int>(ratings.Items, indices); Values = new ListProxy <double>(ratings, indices); MaxUserID = ratings.MaxUserID; MaxItemID = ratings.MaxItemID; MaxRating = ratings.MaxRating; MinRating = ratings.MinRating; }
/// <summary>Rate a given set of instances and write it to a file</summary> /// <param name="recommender">rating predictor</param> /// <param name="ratings">test cases</param> /// <param name="filename">the name of the file to write the predictions to</param> /// <param name="user_mapping">an <see cref="Mapping"/> object for the user IDs</param> /// <param name="item_mapping">an <see cref="Mapping"/> object for the item IDs</param> /// <param name="line_format">a format string specifying the line format; {0} is the user ID, {1} the item ID, {2} the rating</param> /// <param name="header">if specified, write this string to the first line</param> public static void WritePredictions( this IRecommender recommender, IRatings ratings, string filename, IMapping user_mapping = null, IMapping item_mapping = null, string line_format = "{0}\t{1}\t{2}", string header = null) { using (var writer = FileSystem.CreateStreamWriter(filename)) WritePredictions(recommender, ratings, writer, user_mapping, item_mapping, line_format); }
/// <summary>Create a RatingsProxy object</summary> /// <param name="ratings">a ratings data structure</param> /// <param name="indices">an index list pointing to entries in the ratings</param> public RatingsProxy(IRatings ratings, IList<int> indices) { this.indices = indices; Users = new ListProxy<int>(ratings.Users, indices); Items = new ListProxy<int>(ratings.Items, indices); Values = new ListProxy<float>(ratings, indices); MaxUserID = Users.Max(); MaxItemID = Items.Max(); Scale = ratings.Scale; }
/// <summary>Create a RatingsProxy object</summary> /// <param name="ratings">a ratings data structure</param> /// <param name="indices">an index list pointing to entries in the ratings</param> public RatingsProxy(IRatings ratings, IList <int> indices) { this.indices = indices; Users = new ListProxy <int>(ratings.Users, indices); Items = new ListProxy <int>(ratings.Items, indices); Values = new ListProxy <float>(ratings, indices); MaxUserID = Users.Max(); MaxItemID = Items.Max(); Scale = ratings.Scale; }
/// public override void UpdateRatings(IRatings ratings) { base.UpdateRatings(ratings); foreach (int user_id in ratings.AllUsers) { RetrainUser(user_id); } foreach (int item_id in ratings.AllItems) { RetrainItem(item_id); } }
/// public override void AddRatings(IRatings ratings) { baseline_predictor.AddRatings(ratings); for (int index = 0; index < ratings.Count; index++) { data_item[ratings.Items[index], ratings.Users[index]] = true; } foreach (int item_id in ratings.AllItems) { RetrainItem(item_id); } }
/// public virtual void AddRatings(IRatings new_ratings) { foreach (int user_id in new_ratings.AllUsers) if (user_id > MaxUserID) AddUser(user_id); foreach (int item_id in new_ratings.AllItems) if (item_id > MaxItemID) AddItem(item_id); for (int index = 0; index < new_ratings.Count; index++) Ratings.Add(new_ratings.Users[index], new_ratings.Items[index], new_ratings[index]); }
static void LoadData(string data_dir) { string training_file = Path.Combine(data_dir, track2 ? "trainIdx2.txt" : "trainIdx1.txt"); string test_file = Path.Combine(data_dir, track2 ? "testIdx2.txt" : "testIdx1.txt"); string validation_file = Path.Combine(data_dir, track2 ? "validationIdx2.txt" : "validationIdx1.txt"); string track_file = Path.Combine(data_dir, track2 ? "trackData2.txt" : "trackData1.txt"); string album_file = Path.Combine(data_dir, track2 ? "albumData2.txt" : "albumData1.txt"); string artist_file = Path.Combine(data_dir, track2 ? "artistData2.txt" : "artistData1.txt"); string genre_file = Path.Combine(data_dir, track2 ? "genreData2.txt" : "genreData1.txt"); if (sample_data) { training_file = Path.Combine(data_dir, track2 ? "trainIdx2.firstLines.txt" : "trainIdx1.firstLines.txt"); test_file = Path.Combine(data_dir, track2 ? "testIdx2.firstLines.txt" : "testIdx1.firstLines.txt"); validation_file = Path.Combine(data_dir, track2 ? "validationIdx2.firstLines.txt" : "validationIdx1.firstLines.txt"); } if (good_rating_prob) { // read training data training_ratings = MyMediaLite.IO.KDDCup2011.Ratings.Read80Plus(training_file); // read validation data validation_ratings = MyMediaLite.IO.KDDCup2011.Ratings.Read80Plus(validation_file); } else { // read training data training_ratings = MyMediaLite.IO.KDDCup2011.Ratings.Read(training_file); // read validation data validation_ratings = MyMediaLite.IO.KDDCup2011.Ratings.Read(validation_file); } // combine training and validation ratings complete_ratings = new CombinedRatings(training_ratings, validation_ratings); // read test data test_data = MyMediaLite.IO.KDDCup2011.Ratings.ReadTest(test_file); if (track2) { validation_candidates = MyMediaLite.IO.KDDCup2011.Ratings.ReadTest(Path.Combine(data_dir, sample_data ? "validationCandidatesIdx2.firstLines.txt" : "validationCandidatesIdx2.txt")); } // read item data if (recommender is IKDDCupRecommender) { var kddcup_recommender = recommender as IKDDCupRecommender; kddcup_recommender.ItemInfo = MyMediaLite.IO.KDDCup2011.Items.Read(track_file, album_file, artist_file, genre_file, 1); } }
// TODO as soon as we drop support for Mono 2.6, use default arguments /// <summary>Rate a given set of instances and write it to a TextWriter</summary> /// <param name="recommender">rating predictor</param> /// <param name="ratings">test cases</param> /// <param name="user_mapping">an <see cref="EntityMapping"/> object for the user IDs</param> /// <param name="item_mapping">an <see cref="EntityMapping"/> object for the item IDs</param> /// <param name="line_format">a format string specifying the line format; {0} is the user ID, {1} the item ID, {2} the rating</param> /// <param name="writer">the TextWriter to write the predictions to</param> public static void WritePredictions( IRatingPredictor recommender, IRatings ratings, IEntityMapping user_mapping, IEntityMapping item_mapping, string line_format, TextWriter writer) { for (int index = 0; index < ratings.Count; index++) writer.WriteLine(line_format, user_mapping.ToOriginalID(ratings.Users[index]), item_mapping.ToOriginalID(ratings.Items[index]), recommender.Predict(ratings.Users[index], ratings.Items[index]).ToString(CultureInfo.InvariantCulture)); }
/// <summary>Rate a given set of instances and write it to a file</summary> /// <param name="recommender">rating predictor</param> /// <param name="ratings">test cases</param> /// <param name="user_mapping">an <see cref="EntityMapping"/> object for the user IDs</param> /// <param name="item_mapping">an <see cref="EntityMapping"/> object for the item IDs</param> /// <param name="line_format">a format string specifying the line format; {0} is the user ID, {1} the item ID, {2} the rating</param> /// <param name="filename">the name of the file to write the predictions to</param> public static void WritePredictions( IRatingPredictor recommender, IRatings ratings, IEntityMapping user_mapping, IEntityMapping item_mapping, string line_format, string filename) { if (filename.Equals("-")) WritePredictions(recommender, ratings, user_mapping, item_mapping, line_format, Console.Out); else using ( var writer = new StreamWriter(filename) ) WritePredictions(recommender, ratings, user_mapping, item_mapping, line_format, writer); }
internal void Init(IRatings ratings, bool IsPostBack) { _view = ratings; //if (_webContext.CurrentUser == null) // _view.CanSetRating(false); //else if (Rating.HasRatedBefore(_view.SystemObjectID, _view.SystemObjectRecordID, _webContext.CurrentUser.AccountID)) // _view.CanSetRating(false); //else // _view.CanSetRating(true); _view.SetCurrentRating(Rating.GetCurrentRating(_view.SystemObjectID, _view.SystemObjectRecordID)); }
/// public float ComputeCorrelation(IRatings ratings, EntityType entity_type, int i, int j) { if (i == j) return 1; IList<int> indexes1 = (entity_type == EntityType.USER) ? ratings.ByUser[i] : ratings.ByItem[i]; IList<int> indexes2 = (entity_type == EntityType.USER) ? ratings.ByUser[j] : ratings.ByItem[j]; // get common ratings for the two entities var e1 = (entity_type == EntityType.USER) ? ratings.GetItems(indexes1) : ratings.GetUsers(indexes1); var e2 = (entity_type == EntityType.USER) ? ratings.GetItems(indexes2) : ratings.GetUsers(indexes2); e1.IntersectWith(e2); int n = e1.Count; if (n < 2) return 0; // single-pass variant double i_sum = 0; double j_sum = 0; double ij_sum = 0; double ii_sum = 0; double jj_sum = 0; foreach (int other_entity_id in e1) { // get ratings float r1 = 0; float r2 = 0; if (entity_type == EntityType.USER) { r1 = ratings.Get(i, other_entity_id, indexes1); r2 = ratings.Get(j, other_entity_id, indexes2); } else { r1 = ratings.Get(other_entity_id, i, indexes1); r2 = ratings.Get(other_entity_id, j, indexes2); } // update sums i_sum += r1; j_sum += r2; ij_sum += r1 * r2; ii_sum += r1 * r1; jj_sum += r2 * r2; } return ComputeCorrelation (i_sum, j_sum, ii_sum, jj_sum, ij_sum, n); }
/// <summary>Display dataset statistics</summary> /// <param name="train">the training data</param> /// <param name="test">the test data</param> /// <param name="user_attributes">the user attributes</param> /// <param name="item_attributes">the item attributes</param> /// <param name="display_overlap">if set true, display the user/item overlap between train and test</param> public static string Statistics( this IRatings train, IRatings test = null, List <IBooleanMatrix> user_attributes = null, List <IBooleanMatrix> item_attributes = null, bool display_overlap = false) { // training data stats int num_users = train.AllUsers.Count; int num_items = train.AllItems.Count; long matrix_size = (long)num_users * num_items; long empty_size = (long)matrix_size - train.Count; double sparsity = (double)100L * empty_size / matrix_size; string s = string.Format(CultureInfo.InvariantCulture, "training data: {0} users, {1} items, {2} ratings, sparsity {3,0:0.#####}\n", num_users, num_items, train.Count, sparsity); if (train is ITimedRatings) { var time_train = train as ITimedRatings; s += string.Format(CultureInfo.InvariantCulture, "rating period: {0} to {1}\n", time_train.EarliestTime, time_train.LatestTime); } // test data stats if (test != null) { num_users = test.AllUsers.Count; num_items = test.AllItems.Count; matrix_size = (long)num_users * num_items; empty_size = (long)matrix_size - test.Count; // TODO depends on the eval scheme whether this is correct sparsity = (double)100L * empty_size / matrix_size; s += string.Format(CultureInfo.InvariantCulture, "test data: {0} users, {1} items, {2} ratings, sparsity {3,0:0.#####}\n", num_users, num_items, test.Count, sparsity); if (test is ITimedRatings) { var time_test = test as ITimedRatings; s += string.Format(CultureInfo.InvariantCulture, "rating period: {0} to {1}\n", time_test.EarliestTime, time_test.LatestTime); } } // count and display the overlap between train and test if (display_overlap && test != null) { int num_new_users = 0; int num_new_items = 0; TimeSpan seconds = Wrap.MeasureTime(delegate() { num_new_users = test.AllUsers.Except(train.AllUsers).Count(); num_new_items = test.AllItems.Except(train.AllItems).Count(); }); s += string.Format("{0} new users, {1} new items ({2} seconds)\n", num_new_users, num_new_items, seconds); } return(s + Statistics(user_attributes, item_attributes)); }
static Dictionary <string, float> Evaluate(IRatingPredictor recommender, IRatings ratings, IList <int> indices) { if (indices.Count == 0) { return(null); } double rmse = 0; double mae = 0; double cbd = 0; if (recommender is ITimeAwareRatingPredictor && ratings is ITimedRatings) { var time_aware_recommender = recommender as ITimeAwareRatingPredictor; var timed_ratings = ratings as ITimedRatings; foreach (int index in indices) { float prediction = time_aware_recommender.Predict(timed_ratings.Users[index], timed_ratings.Items[index], timed_ratings.Times[index]); float error = prediction - ratings[index]; rmse += error * error; mae += Math.Abs(error); cbd += ComputeCBD(ratings[index], prediction, ratings.Scale.Min, ratings.Scale.Max); } } else { foreach (int index in indices) { float prediction = recommender.Predict(ratings.Users[index], ratings.Items[index]); float error = prediction - ratings[index]; rmse += error * error; mae += Math.Abs(error); cbd += ComputeCBD(ratings[index], prediction, ratings.Scale.Min, ratings.Scale.Max); } } mae = mae / indices.Count; rmse = Math.Sqrt(rmse / indices.Count); cbd = cbd / indices.Count; var result = new Dictionary <string, float>(); result["RMSE"] = (float)rmse; result["MAE"] = (float)mae; result["NMAE"] = (float)mae / (recommender.MaxRating - recommender.MinRating); result["CBD"] = (float)cbd; return(result); }
/// public virtual void UpdateRatings(IRatings new_ratings) { for (int i = 0; i < new_ratings.Count; i++) { int user_id = new_ratings.Users[i]; int item_id = new_ratings.Items[i]; float rating = new_ratings[i]; int index; if (Ratings.TryGetIndex(user_id, item_id, out index)) Ratings[index] = rating; else throw new Exception(string.Format("Cannot update rating for user {0} and item {1}: No such rating exists.", user_id, item_id)); } }
// TODO as soon as we drop support for Mono 2.6, use default arguments /// <summary>Rate a given set of instances and write it to a TextWriter</summary> /// <param name="recommender">rating predictor</param> /// <param name="ratings">test cases</param> /// <param name="user_mapping">an <see cref="EntityMapping"/> object for the user IDs</param> /// <param name="item_mapping">an <see cref="EntityMapping"/> object for the item IDs</param> /// <param name="line_format">a format string specifying the line format; {0} is the user ID, {1} the item ID, {2} the rating</param> /// <param name="writer">the TextWriter to write the predictions to</param> public static void WritePredictions( IRatingPredictor recommender, IRatings ratings, IEntityMapping user_mapping, IEntityMapping item_mapping, string line_format, TextWriter writer) { for (int index = 0; index < ratings.Count; index++) { writer.WriteLine(line_format, user_mapping.ToOriginalID(ratings.Users[index]), item_mapping.ToOriginalID(ratings.Items[index]), recommender.Predict(ratings.Users[index], ratings.Items[index]).ToString(CultureInfo.InvariantCulture)); } }
public void TestRead() { var reader = new StringReader(@"5951,50,5,2001-01-01 5951,223,5,2001-01-01 5951,260,5,2001-01-01 5951,293,5,2001-01-01 5951,356,4,2001-01-01 5951,364,3,2001-01-01 5951,457,3,2001-01-01 "); IRatings data = TimedRatingData.Read(reader); Assert.AreEqual(7, data.Count); }
public void TestRead() { var reader = new StringReader(@"5951::50::5::881250949 5951::223::5::891717742 5951::260::5::878887116 5951::293::5::880606923 5951::356::4::886397596 5951::364::3::884182806 5951::457::3::879270459 "); IRatings data = MovieLensRatingData.Read(reader, null, null); Assert.AreEqual(7, data.Count); }
/// <summary>Display dataset statistics</summary> /// <param name="train">the training data</param> /// <param name="test">the test data</param> /// <param name="user_attributes">the user attributes</param> /// <param name="item_attributes">the item attributes</param> /// <param name="display_overlap">if set true, display the user/item overlap between train and test</param> public static string Statistics( this IRatings train, IRatings test = null, IBooleanMatrix user_attributes = null, IBooleanMatrix item_attributes = null, bool display_overlap = false) { // training data stats int num_users = train.AllUsers.Count; int num_items = train.AllItems.Count; long matrix_size = (long) num_users * num_items; long empty_size = (long) matrix_size - train.Count; double sparsity = (double) 100L * empty_size / matrix_size; string s = string.Format(CultureInfo.InvariantCulture, "training data: {0} users, {1} items, {2} ratings, sparsity {3,0:0.#####}\n", num_users, num_items, train.Count, sparsity); if (train is ITimedRatings) { var time_train = train as ITimedRatings; s += string.Format(CultureInfo.InvariantCulture, "rating period: {0} to {1}\n", time_train.EarliestTime, time_train.LatestTime); } // test data stats if (test != null) { num_users = test.AllUsers.Count; num_items = test.AllItems.Count; matrix_size = (long) num_users * num_items; empty_size = (long) matrix_size - test.Count; // TODO depends on the eval scheme whether this is correct sparsity = (double) 100L * empty_size / matrix_size; s += string.Format(CultureInfo.InvariantCulture, "test data: {0} users, {1} items, {2} ratings, sparsity {3,0:0.#####}\n", num_users, num_items, test.Count, sparsity); if (test is ITimedRatings) { var time_test = test as ITimedRatings; s += string.Format(CultureInfo.InvariantCulture, "rating period: {0} to {1}\n", time_test.EarliestTime, time_test.LatestTime); } } // count and display the overlap between train and test if (display_overlap && test != null) { int num_new_users = 0; int num_new_items = 0; TimeSpan seconds = Wrap.MeasureTime(delegate() { num_new_users = test.AllUsers.Except(train.AllUsers).Count(); num_new_items = test.AllItems.Except(train.AllItems).Count(); }); s += string.Format("{0} new users, {1} new items ({2} seconds)\n", num_new_users, num_new_items, seconds); } return s + Statistics(user_attributes, item_attributes); }
public void TestReadIgnoreLine() { var reader = new StringReader(@"# first line 5951,50,5,2001-01-01 00:00:00 5951,223,5,2001-01-01 00:00:00 5951,260,5,2001-01-01 00:00:00 5951,293,5,2001-01-01 00:00:00 5951,356,4,2001-01-01 00:00:00 5951,364,3,2001-01-01 00:00:00 5951,457,3,2001-01-01 00:00:00 "); IRatings data = TimedRatingData.Read(reader, null, null, TestRatingFileFormat.WITH_RATINGS, true); Assert.AreEqual(7, data.Count); }
public void TestTimeStamp() { var reader = new StringReader(@"# first line 5951,50,5,881250949 5951,223,5,891717742 5951,260,5,878887116 5951,293,5,880606923 5951,356,4,886397596 5951,364,3,884182806 5951,457,3,879270459 "); IRatings data = TimedRatingData.Read(reader, null, null, TestRatingFileFormat.WITH_RATINGS, true); Assert.AreEqual(7, data.Count); }
public void TestReadIgnoreLine() { var reader = new StringReader(@"# first line 5951,50,5 5951,223,5 5951,260,5 5951,293,5 5951,356,4 5951,364,3 5951,457,3 "); IRatings data = RatingData.Read(reader, null, null, true); Assert.AreEqual(7, data.Count); }
public void TestReadIgnoreLine() { var reader = new StringReader(@"# first line 5951,50,5,2001-01-01 00:00:00 5951,223,5,2001-01-01 00:00:00 5951,260,5,2001-01-01 00:00:00 5951,293,5,2001-01-01 00:00:00 5951,356,4,2001-01-01 00:00:00 5951,364,3,2001-01-01 00:00:00 5951,457,3,2001-01-01 00:00:00 "); IRatings data = StaticRatingData.Read(reader, 7, null, null, RatingType.FLOAT, true); Assert.AreEqual(7, data.Count); }
/// <summary>Performs user-wise fold-in evaluation, but instead of folding in perform a complete re-training with the new data</summary> /// <remarks> /// This method can be quite slow. /// </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 EvaluateFoldInCompleteRetraining(this RatingPredictor 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 = (RatingPredictor) recommender.Clone(); var known_ratings = new RatingsProxy(update_data, update_data.ByUser[user_id]); local_recommender.Ratings = new CombinedRatings(recommender.Ratings, known_ratings); local_recommender.Train(); 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++; } 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; }
/// <summary>Create a RatingsProxy object</summary> /// <param name="ratings">a ratings data structure</param> /// <param name="indices">an index list pointing to entries in the ratings</param> public RatingsProxy(IRatings ratings, IList<int> indices) { this.indices = indices; Users = new ListProxy<int>(ratings.Users, indices); Items = new ListProxy<int>(ratings.Items, indices); Values = new ListProxy<float>(ratings, indices); MaxUserID = -1; MaxItemID = -1; MaxRating = ratings.MaxRating; MinRating = ratings.MinRating; foreach (int index in indices) { if (ratings.Users[index] > MaxUserID) MaxUserID = ratings.Users[index]; if (ratings.Items[index] > MaxItemID) MaxItemID = ratings.Items[index]; } }
/// <summary>Evaluates a rating predictor for RMSE, (N)MAE, and CBD</summary> /// <remarks> /// <para> /// See http://recsyswiki.com/wiki/Root_mean_square_error and http://recsyswiki.com/wiki/Mean_absolute_error /// </para> /// <para> /// For NMAE, see the paper by Goldberg et al. /// </para> /// <para> /// For CBD (capped binomial deviance), see http://www.kaggle.com/c/ChessRatings2/Details/Evaluation /// </para> /// <para> /// If the recommender can take time into account, and the rating dataset provides rating times, /// this information will be used for making rating predictions. /// </para> /// <para> /// Literature: /// <list type="bullet"> /// <item><description> /// Ken Goldberg, Theresa Roeder, Dhruv Gupta, and Chris Perkins: /// Eigentaste: A Constant Time Collaborative Filtering Algorithm. /// nformation Retrieval Journal 2001. /// http://goldberg.berkeley.edu/pubs/eigentaste.pdf /// </description></item> /// </list> /// </para> /// </remarks> /// <param name="recommender">rating predictor</param> /// <param name="test_ratings">test cases</param> /// <param name="training_ratings">the training examples</param> /// <returns>a Dictionary containing the evaluation results</returns> static public RatingPredictionEvaluationResults Evaluate(this IRatingPredictor recommender, IRatings test_ratings, IRatings training_ratings = null) { if (recommender == null) throw new ArgumentNullException("recommender"); if (test_ratings == null) throw new ArgumentNullException("ratings"); var all_indices = Enumerable.Range(0, test_ratings.Count).ToArray(); var results = new RatingPredictionEvaluationResults(Evaluate(recommender, test_ratings, all_indices)); if (training_ratings != null) { var new_user_indices = (from index in all_indices where test_ratings.Users[index] > training_ratings.MaxUserID || training_ratings.CountByUser[test_ratings.Users[index]] == 0 select index).ToArray(); results.NewUserResults = Evaluate(recommender, test_ratings, new_user_indices); var new_item_indices = (from index in all_indices where test_ratings.Items[index] > training_ratings.MaxItemID || training_ratings.CountByItem[test_ratings.Items[index]] == 0 select index).ToArray(); results.NewItemResults = Evaluate(recommender, test_ratings, new_item_indices); results.NewUserNewItemResults = Evaluate(recommender, test_ratings, Enumerable.Intersect(new_user_indices, new_item_indices).ToArray()); } return results; }
/// <summary>Online evaluation for rating prediction</summary> /// <remarks> /// Every rating that is tested is added to the training set afterwards. /// </remarks> /// <param name="recommender">rating predictor</param> /// <param name="ratings">Test cases</param> /// <returns>a Dictionary containing the evaluation results</returns> static public RatingPredictionEvaluationResults EvaluateOnline(this IRatingPredictor recommender, IRatings ratings) { if (recommender == null) throw new ArgumentNullException("recommender"); if (ratings == null) throw new ArgumentNullException("ratings"); var incremental_recommender = recommender as IIncrementalRatingPredictor; if (incremental_recommender == null) throw new ArgumentException("recommender must be of type IIncrementalRatingPredictor"); double rmse = 0; double mae = 0; double cbd = 0; // iterate in random order foreach (int index in ratings.RandomIndex) { float prediction = recommender.Predict(ratings.Users[index], ratings.Items[index]); float error = prediction - ratings[index]; rmse += error * error; mae += Math.Abs(error); cbd += Eval.Ratings.ComputeCBD(ratings[index], prediction, recommender.MinRating, recommender.MaxRating); incremental_recommender.AddRatings(new RatingsProxy(ratings, new int[] { index })); } mae = mae / ratings.Count; rmse = Math.Sqrt(rmse / ratings.Count); cbd = cbd / ratings.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; }
/// <summary>Computes the logistic loss sum</summary> /// <returns>the logistic loss sum</returns> /// <param name='recommender'>the recommender to make predictions with</param> /// <param name='ratings'>the actual ratings</param> /// <param name='min_rating'>the minimal rating</param> /// <param name='rating_range_size'>the size of the rating range: max_rating - min_rating</param> public static double ComputeSum( this IRatingPredictor recommender, IRatings ratings, float min_rating, float rating_range_size) { double sum = 0; for (int i = 0; i < ratings.Count; i++) { double prediction = recommender.Predict(ratings.Users[i], ratings.Items[i]); // map into [0, 1] interval prediction = (prediction - min_rating) / rating_range_size; if (prediction < 0.0) prediction = 0.0; if (prediction > 1.0) prediction = 1.0; double actual_rating = (ratings[i] - min_rating) / rating_range_size; sum -= (actual_rating) * Math.Log(prediction); sum -= (1 - actual_rating) * Math.Log(1 - prediction); } return sum; }
/// <summary>Rate a given set of instances and write it to a TextWriter</summary> /// <param name="recommender">rating predictor</param> /// <param name="ratings">test cases</param> /// <param name="writer">the TextWriter to write the predictions to</param> /// <param name="user_mapping">an <see cref="Mapping"/> object for the user IDs</param> /// <param name="item_mapping">an <see cref="Mapping"/> object for the item IDs</param> /// <param name="line_format">a format string specifying the line format; {0} is the user ID, {1} the item ID, {2} the rating</param> /// <param name="header">if specified, write this string at the start of the output</param> public static void WritePredictions( this IRecommender recommender, IRatings ratings, TextWriter writer, IMapping user_mapping = null, IMapping item_mapping = null, string line_format = "{0}\t{1}\t{2}", string header = null) { if (user_mapping == null) user_mapping = new IdentityMapping(); if (item_mapping == null) item_mapping = new IdentityMapping(); if (header != null) writer.WriteLine(header); if (line_format == "ranking") { foreach (int user_id in ratings.AllUsers) if (ratings.ByUser[user_id].Count > 0) recommender.WritePredictions( user_id, new List<int>(from index in ratings.ByUser[user_id] select ratings.Items[index]), new int[] { }, ratings.ByUser[user_id].Count, writer, user_mapping, item_mapping); } else for (int index = 0; index < ratings.Count; index++) writer.WriteLine( line_format, user_mapping.ToOriginalID(ratings.Users[index]), item_mapping.ToOriginalID(ratings.Items[index]), recommender.Predict(ratings.Users[index], ratings.Items[index]).ToString(CultureInfo.InvariantCulture)); }
/// public override void UpdateRatings(IRatings ratings) { baseline_predictor.UpdateRatings(ratings); foreach (int item_id in ratings.AllItems) RetrainItem(item_id); }
/// public override void AddRatings(IRatings ratings) { base.AddRatings(ratings); ComputeProbabilities(ratings.AllUsers); }
/// <summary>Compute the correlations for a given entity type from a rating dataset</summary> /// <param name="ratings">the rating data</param> /// <param name="entity_type">the EntityType - either USER or ITEM</param> public virtual void ComputeCorrelations(IRatings ratings, EntityType entity_type) { throw new NotSupportedException(); }
/// public override void UpdateRatings(IRatings ratings) { base.UpdateRatings(ratings); foreach (int user_id in ratings.AllUsers) RetrainUser(user_id); foreach (int item_id in ratings.AllItems) RetrainItem(item_id); }
/// public override void AddRatings(IRatings ratings) { lock (this) { base.AddRatings (ratings); foreach (int user_id in ratings.AllUsers) RetrainUser (user_id); foreach (int item_id in ratings.AllItems) RetrainItem (item_id); } }