protected List <Rating> GetRecommendations(MyTable ratingTable, int N = 30) { List <Rating> recommendedItems = new List <Rating>(); ArrayList list = ratingTable.GetSubKeyList(); int[] mainKeys = new int[ratingTable.Keys.Count]; ratingTable.Keys.CopyTo(mainKeys, 0); Parallel.ForEach(mainKeys, userId => { Hashtable Nu = (Hashtable)ratingTable[userId]; // ratings of user u List <Rating> predictedRatings = new List <Rating>(); foreach (int itemId in list) { if (!Nu.ContainsKey(itemId)) { double p = Predict(userId, itemId, -1); predictedRatings.Add(new Rating(userId, itemId, p)); } } List <Rating> sortedLi = predictedRatings.OrderByDescending(r => r.Score).ToList(); var selectedLi = sortedLi.GetRange(0, Math.Min(sortedLi.Count, N)); lock (recommendedItems) { recommendedItems.AddRange(selectedLi); } }); return(recommendedItems); }
/// <summary> /// Randomly sample negative ratings for each user from his/her rated ratings /// </summary> /// <param name="ratings">positive ratings</param> /// <param name="ratio">ratio = #(negative samples) / #(positive samples)</param> /// <param name="verbose"></param> /// <returns></returns> public static List <Rating> RandomSelectNegativeSamples(List <Rating> ratings, int ratio = 1, bool verbose = false) { if (verbose) { Console.WriteLine("ratio,{0}", ratio); } List <Rating> positiveRatings = new List <Rating>(); foreach (Rating r in ratings) { positiveRatings.Add(new Rating(r.UserId, r.ItemId, 1.0)); } MyTable ratingTable = GetRatingTable(positiveRatings); int[] items = (int[])ratingTable.GetSubKeyList().ToArray(typeof(int)); Random random = new Random(); foreach (int uId in ratingTable.Keys) { Hashtable subTable = (Hashtable)ratingTable[uId]; int counter = 0, ratedItems = subTable.Count; while ((counter < ratedItems * ratio) && (counter < items.Length - ratedItems)) { int iId = items[random.Next(items.Length)]; if (!subTable.ContainsKey(iId)) { subTable.Add(iId, 0.0); // negative samples counter++; } } } List <Rating> samples = new List <Rating>(); foreach (int uId in ratingTable.Keys) { Hashtable subTable = (Hashtable)ratingTable[uId]; foreach (int iId in subTable.Keys) { double score = (double)subTable[iId]; samples.Add(new Rating(uId, iId, score)); } } return(samples); }