/// <summary>Evaluate Track 2 on a validation set</summary> /// <param name="recommender">the recommender to use</param> /// <param name="candidates">the candidate items (per user)</param> /// <param name="hits">the real items (per user)</param> /// <returns>the error rate on this validation split</returns> public static double EvaluateTrack2(IRecommender recommender, Dictionary <int, IList <int> > candidates, Dictionary <int, IList <int> > hits) { int hit_count = 0; foreach (int user_id in candidates.Keys) { IList <int> user_candidates = candidates[user_id]; var predictions = new double[user_candidates.Count]; for (int i = 0; i < user_candidates.Count; i++) { predictions[i] = recommender.Predict(user_id, user_candidates[i]); } var positions = new List <int>(new int[] { 0, 1, 2, 3, 4, 5 }); positions.Sort(delegate(int pos1, int pos2) { return(predictions[pos2].CompareTo(predictions[pos1])); }); var user_true_items = new HashSet <int>(hits[user_id]); for (int i = 0; i < user_true_items.Count; i++) { if (user_true_items.Contains(user_candidates[positions[i]])) { hit_count++; } } } int num_pos = hits.Keys.Sum(u => hits[u].Count); return(1 - (double)hit_count / num_pos); }
/// <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>Evaluate Track 2 on a validation set</summary> /// <param name="recommender">the recommender to use</param> /// <param name="candidates">the candidate items (per user)</param> /// <param name="hits">the real items (per user)</param> /// <returns>the error rate on this validation split</returns> public static double EvaluateTrack2(IRecommender recommender, Dictionary<int, IList<int>> candidates, Dictionary<int, IList<int>> hits) { int hit_count = 0; foreach (int user_id in candidates.Keys) { IList<int> user_candidates = candidates[user_id]; var predictions = new double[user_candidates.Count]; for (int i = 0; i < user_candidates.Count; i++) predictions[i] = recommender.Predict(user_id, user_candidates[i]); var positions = new List<int>(new int[] { 0, 1, 2, 3, 4, 5 }); positions.Sort(delegate(int pos1, int pos2) { return predictions[pos2].CompareTo(predictions[pos1]); } ); var user_true_items = new HashSet<int>(hits[user_id]); for (int i = 0; i < user_true_items.Count; i++) if (user_true_items.Contains(user_candidates[positions[i]])) hit_count++; } int num_pos = hits.Keys.Sum(u => hits[u].Count); return 1 - (double) hit_count / num_pos; }
/// <summary>Predict items for Track 2</summary> /// <param name="recommender">the recommender to use</param> /// <param name="candidates">a mapping from user IDs to the candidate items</param> /// <param name="writer">the writer object to write the predictions to</param> public static void PredictTrack2(IRecommender recommender, Dictionary <int, IList <int> > candidates, TextWriter writer) { foreach (int user_id in candidates.Keys) // this is ordered, but is it guaranteed? { IList <int> user_candidates = candidates[user_id]; var predictions = new double[user_candidates.Count]; for (int i = 0; i < user_candidates.Count; i++) { predictions[i] = recommender.Predict(user_id, user_candidates[i]); } var positions = new List <int>(new int[] { 0, 1, 2, 3, 4, 5 }); positions.Sort(delegate(int pos1, int pos2) { return(predictions[pos2].CompareTo(predictions[pos1])); }); for (int i = 0; i < user_candidates.Count; i++) { if (positions.IndexOf(i) < 3) { writer.Write("1"); } else { writer.Write("0"); } } } }
/// <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); } }
/// <summary>Predict item scores for Track 2</summary> /// <param name="recommender">the recommender to use</param> /// <param name="candidates">a mapping from user IDs to the candidate items</param> /// <param name="writer">the writer to write the scores to</param> public static void PredictScoresTrack2(IRecommender recommender, Dictionary <int, IList <int> > candidates, BinaryWriter writer) { foreach (int user_id in candidates.Keys) { foreach (int item_id in candidates[user_id]) { writer.Write(recommender.Predict(user_id, item_id)); } } }
/// <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>Predict items for a given user</summary> /// <param name="recommender">the recommender to use</param> /// <param name="user_id">the numerical ID of the user</param> /// <param name="relevant_items">a collection of numerical IDs of relevant items</param> /// <returns>an ordered list of items, the most likely item first</returns> public static int[] PredictItems(IRecommender recommender, int user_id, ICollection<int> relevant_items) { var result = new List<WeightedItem>(); foreach (int item_id in relevant_items) result.Add( new WeightedItem(item_id, recommender.Predict(user_id, item_id))); result.Sort(); result.Reverse(); var return_array = new int[result.Count]; for (int i = 0; i < return_array.Length; i++) return_array[i] = result[i].item_id; return return_array; }
/// <summary>predict items for a specific users</summary> /// <param name="recommender">the <see cref="IRecommender"/> object to use for the predictions</param> /// <param name="user_id">the user ID</param> /// <param name="max_item_id">the maximum item ID</param> /// <returns>a list sorted list of item IDs</returns> public static int[] PredictItems(IRecommender recommender, int user_id, int max_item_id) { var result = new List<WeightedItem>(); for (int item_id = 0; item_id <= max_item_id; item_id++) result.Add( new WeightedItem(item_id, recommender.Predict(user_id, item_id))); result.Sort(); result.Reverse(); var return_array = new int[max_item_id + 1]; for (int i = 0; i < return_array.Length; i++) return_array[i] = result[i].item_id; return return_array; }
/// <summary>Write item predictions (scores) to a TextWriter object</summary> /// <param name="recommender">the <see cref="IRecommender"/> to use for making the predictions</param> /// <param name="user_id">the ID of the user to make recommendations for</param> /// <param name="relevant_items">the list of candidate items</param> /// <param name="ignore_items">a list of items for which no predictions should be made</param> /// <param name="num_predictions">the number of items to return per user, -1 if there should be no limit</param> /// <param name="user_mapping">an <see cref="IEntityMapping"/> object for the user IDs</param> /// <param name="item_mapping">an <see cref="IEntityMapping"/> object for the item IDs</param> /// <param name="writer">the <see cref="TextWriter"/> to write to</param> static public void WritePredictions( IRecommender recommender, int user_id, ICollection <int> relevant_items, ICollection <int> ignore_items, int num_predictions, IEntityMapping user_mapping, IEntityMapping item_mapping, TextWriter writer) { var score_list = new List <WeightedItem>(); foreach (int item_id in relevant_items) { score_list.Add(new WeightedItem(item_id, recommender.Predict(user_id, item_id))); } score_list.Sort(); score_list.Reverse(); int prediction_count = 0; writer.Write("{0}\t[", user_mapping.ToOriginalID(user_id)); foreach (var wi in score_list) { if (!ignore_items.Contains(wi.item_id) && wi.weight > double.MinValue) { if (prediction_count == 0) { writer.Write("{0}:{1}", item_mapping.ToOriginalID(wi.item_id), wi.weight.ToString(CultureInfo.InvariantCulture)); } else { writer.Write(",{0}:{1}", item_mapping.ToOriginalID(wi.item_id), wi.weight.ToString(CultureInfo.InvariantCulture)); } prediction_count++; } if (prediction_count == num_predictions) { break; } } writer.WriteLine("]"); }
/// <summary>Predict items for a given user</summary> /// <param name="recommender">the recommender to use</param> /// <param name="user_id">the numerical ID of the user</param> /// <param name="relevant_items">a collection of numerical IDs of relevant items</param> /// <returns>an ordered list of items, the most likely item first</returns> static public int[] PredictItems(IRecommender recommender, int user_id, ICollection <int> relevant_items) { var result = new List <WeightedItem>(); foreach (int item_id in relevant_items) { result.Add(new WeightedItem(item_id, recommender.Predict(user_id, item_id))); } result.Sort(); result.Reverse(); var return_array = new int[result.Count]; for (int i = 0; i < return_array.Length; i++) { return_array[i] = result[i].item_id; } return(return_array); }
/// <summary>predict items for a specific users</summary> /// <param name="recommender">the <see cref="IRecommender"/> object to use for the predictions</param> /// <param name="user_id">the user ID</param> /// <param name="max_item_id">the maximum item ID</param> /// <returns>a list sorted list of item IDs</returns> static public int[] PredictItems(IRecommender recommender, int user_id, int max_item_id) { var result = new List <WeightedItem>(); for (int item_id = 0; item_id <= max_item_id; item_id++) { result.Add(new WeightedItem(item_id, recommender.Predict(user_id, item_id))); } result.Sort(); result.Reverse(); var return_array = new int[max_item_id + 1]; for (int i = 0; i < return_array.Length; i++) { return_array[i] = result[i].item_id; } return(return_array); }
/// <summary>Predict item scores for Track 2</summary> /// <param name="recommender">the recommender to use</param> /// <param name="candidates">a mapping from user IDs to the candidate items</param> /// <param name="writer">the writer to write the scores to</param> public static void PredictScoresTrack2(IRecommender recommender, Dictionary<int, IList<int>> candidates, BinaryWriter writer) { foreach (int user_id in candidates.Keys) foreach (int item_id in candidates[user_id]) writer.Write(recommender.Predict(user_id, item_id)); }
/// <summary>Write item predictions (scores) to a TextWriter object</summary> /// <param name="recommender">the <see cref="IRecommender"/> to use for making the predictions</param> /// <param name="user_id">the ID of the user to make recommendations for</param> /// <param name="relevant_items">the list of candidate items</param> /// <param name="ignore_items">a list of items for which no predictions should be made</param> /// <param name="num_predictions">the number of items to return per user, -1 if there should be no limit</param> /// <param name="user_mapping">an <see cref="IEntityMapping"/> object for the user IDs</param> /// <param name="item_mapping">an <see cref="IEntityMapping"/> object for the item IDs</param> /// <param name="writer">the <see cref="TextWriter"/> to write to</param> public static void WritePredictions( IRecommender recommender, int user_id, ICollection<int> relevant_items, ICollection<int> ignore_items, int num_predictions, IEntityMapping user_mapping, IEntityMapping item_mapping, TextWriter writer) { var score_list = new List<WeightedItem>(); foreach (int item_id in relevant_items) score_list.Add( new WeightedItem(item_id, recommender.Predict(user_id, item_id))); score_list.Sort(); score_list.Reverse(); int prediction_count = 0; writer.Write("{0}\t[", user_mapping.ToOriginalID(user_id)); foreach (var wi in score_list) { if (!ignore_items.Contains(wi.item_id) && wi.weight > double.MinValue) { if (prediction_count == 0) writer.Write("{0}:{1}", item_mapping.ToOriginalID(wi.item_id), wi.weight.ToString(CultureInfo.InvariantCulture)); else writer.Write(",{0}:{1}", item_mapping.ToOriginalID(wi.item_id), wi.weight.ToString(CultureInfo.InvariantCulture)); prediction_count++; } if (prediction_count == num_predictions) break; } writer.WriteLine("]"); }
/// <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); } }
/// <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>Predict items for Track 2</summary> /// <param name="recommender">the recommender to use</param> /// <param name="candidates">a mapping from user IDs to the candidate items</param> /// <param name="writer">the writer object to write the predictions to</param> public static void PredictTrack2(IRecommender recommender, Dictionary<int, IList<int>> candidates, TextWriter writer) { foreach (int user_id in candidates.Keys) // this is ordered, but is it guaranteed? { IList<int> user_candidates = candidates[user_id]; var predictions = new double[user_candidates.Count]; for (int i = 0; i < user_candidates.Count; i++) predictions[i] = recommender.Predict(user_id, user_candidates[i]); var positions = new List<int>(new int[] { 0, 1, 2, 3, 4, 5 }); positions.Sort(delegate(int pos1, int pos2) { return predictions[pos2].CompareTo(predictions[pos1]); } ); for (int i = 0; i < user_candidates.Count; i++) if (positions.IndexOf(i) < 3) writer.Write("1"); else writer.Write("0"); } }