/// <summary> /// Get recommendations based on the trained model? /// </summary> /// <param name="ratingTable"></param> /// <param name="N"></param> /// <returns></returns> protected List <Rating> GetRecommendations(MyTable ratingTable, int N = 10) { List <Rating> recommendedItems = new List <Rating>(); var itemIds = ratingTable.GetSubKeyArray().AsParallel().Cast <int>().ToArray(); var userIds = ratingTable.GetMainKeyArray().AsParallel().Cast <int>().ToArray(); Parallel.ForEach(userIds, userId => { Hashtable Nu = (Hashtable)ratingTable[userId]; // ratings of user u List <Rating> predictedRatings = new List <Rating>(); foreach (int itemId in itemIds) { if (!Nu.ContainsKey(itemId)) { double p = Predict(userId, itemId); predictedRatings.Add(new Rating(userId, itemId, p)); } } List <Rating> sortedLi = predictedRatings.OrderByDescending(r => r.Score).ToList(); lock (recommendedItems) { recommendedItems.AddRange(sortedLi.GetRange(0, Math.Min(sortedLi.Count, N))); } }); return(recommendedItems); }
/// <summary> /// Iterate over the training data, uniformly sample from users with replacement. /// TODO /// </summary> protected virtual void IterateWithReplacementUniformUser(List <Rating> ratings, MyTable ratingTable, double gamma = 0.01, double lambda = 0.01, double lambda_bias = 0.01) { int[] userIds = ratingTable.GetMainKeyArray().AsParallel().Cast <int>().OrderBy(k => k).ToArray(); int[] itemIds = ratingTable.GetSubKeyArray().AsParallel().Cast <int>().OrderBy(k => k).ToArray(); var random = Core.Random.GetInstance(); int numberOfRatings = ratings.Count; int userId, itemId, otherItemId; for (int i = 0; i < numberOfRatings; i++) { while (true) { // randomly select a user userId = userIds[random.Next(userIds.Length)]; Hashtable itemsTable = (Hashtable)ratingTable[userId]; // copy Hashtable itemsTableCopy = new Hashtable(itemsTable); // bugs,2018.02.13 var triple = SampleItemPair(userId, itemsTable, itemIds, random); itemId = triple.Item2; otherItemId = triple.Item3; break; } UpdateFactors(userId, itemId, otherItemId, gamma, lambda, lambda_bias); } }
protected List <Rating> GetRecommendations(MyTable ratingTable, double miu, int N = 10, bool multiThread = false) { List <Rating> recommendedItems = new List <Rating>(); int[] subKeys = ratingTable.GetSubKeyArray().AsParallel().Cast <int>().ToArray(); if (multiThread) { int[] mainKeys = ratingTable.GetMainKeyArray().AsParallel().Cast <int>().ToArray(); Parallel.ForEach(mainKeys, userId => { Hashtable Nu = (Hashtable)ratingTable[userId]; // ratings of user u List <Rating> predictedRatings = new List <Rating>(); foreach (int itemId in subKeys) { if (!Nu.ContainsKey(itemId)) { double p = Predict(userId, itemId, miu); predictedRatings.Add(new Rating(userId, itemId, p)); } } List <Rating> sortedLi = predictedRatings.OrderByDescending(r => r.Score).ToList(); lock (recommendedItems) { recommendedItems.AddRange(sortedLi.GetRange(0, Math.Min(sortedLi.Count, N))); } }); } else { foreach (int userId in ratingTable.Keys) { Hashtable Nu = (Hashtable)ratingTable[userId]; // ratings of user u List <Rating> predictedRatings = new List <Rating>(); foreach (int itemId in subKeys) { if (!Nu.ContainsKey(itemId)) { double p = Predict(userId, itemId, miu); predictedRatings.Add(new Rating(userId, itemId, p)); } } List <Rating> sortedLi = predictedRatings.OrderByDescending(r => r.Score).ToList(); recommendedItems.AddRange(sortedLi.GetRange(0, Math.Min(sortedLi.Count, N))); } } return(recommendedItems); }
/// <summary> /// /// </summary> /// <param name="ratingTable"></param> /// <param name="ratio"></param> /// <returns>list of triples: user id - item id - other item id</returns> protected List <Tuple <int, int, int> > SampleTriples(MyTable ratingTable, int ratio = 100) { int[] userIds = ratingTable.GetMainKeyArray().AsParallel().Cast <int>().OrderBy(k => k).ToArray(); int[] itemIds = ratingTable.GetSubKeyArray().AsParallel().Cast <int>().OrderBy(k => k).ToArray(); List <Tuple <int, int, int> > list = new List <Tuple <int, int, int> >(); var random = Core.Random.GetInstance(); // need to be a static member? for (int i = 0; i < userIds.Length * ratio; i++) { // randomly select a user int userId = userIds[random.Next(userIds.Length)]; Hashtable itemsTable = (Hashtable)ratingTable[userId]; var triple = SampleItemPair(userId, itemsTable, itemIds, random); list.Add(triple); } return(list); }