Beispiel #1
0
        /// <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);
            }
        }
Beispiel #2
0
        /// <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);
        }
Beispiel #3
0
        /// <summary>
        /// Randomly sample negative ratings for each user from his/her rated ratings.
        /// Recommender systems in action, p84, vector xiang
        /// </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 = ratingTable.GetSubKeyArray().AsParallel().Cast <int>().ToArray();

            var random = Core.Random.GetInstance();

            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);
        }
Beispiel #4
0
        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);
        }
Beispiel #5
0
        /// <summary>
        /// Iterate over the training data, uniformly sample from user-item pairs without replacement.
        /// </summary>
        protected virtual void IterateWithoutReplacementUniformPair(MyTable ratingTable, double gamma = 0.01, double lambda = 0.01, double lambda_bias = 0.01)
        {
            int[] itemIds = ratingTable.GetSubKeyArray().AsParallel().Cast <int>().OrderBy(k => k).ToArray();
            var   random  = Core.Random.GetInstance();      // need to be a static member?

            foreach (int userId in ratingTable.Keys)
            {
                Hashtable itemsTable = (Hashtable)ratingTable[userId];
                foreach (int itemId in itemsTable.Keys)
                {
                    // 1. sample a negative feedback for each positive feedback
                    int otherItemId = SampleOtherItemId(userId, itemsTable, itemIds, random);

                    UpdateFactors(userId, itemId, otherItemId, gamma, lambda, lambda_bias);
                }
            }
        }
Beispiel #6
0
        /// <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);
        }
Beispiel #7
0
        /// <summary>
        /// Iterate over the training data, uniformly sample from user-item pairs with replacement.
        /// </summary>
        protected virtual void IterateWithReplacementUniformPair(List <Rating> ratings, MyTable ratingTable, double gamma = 0.01, double lambda = 0.01, double lambda_bias = 0.01)
        {
            int[] itemIds         = ratingTable.GetSubKeyArray().AsParallel().Cast <int>().OrderBy(k => k).ToArray();
            var   random          = Core.Random.GetInstance();
            int   numberOfRatings = ratings.Count;

            for (int ii = 0; ii < numberOfRatings; ii++)
            {
                Rating r      = ratings[random.Next(numberOfRatings)];
                int    userId = r.UserId;
                int    itemId = r.ItemId;

                Hashtable itemsTable = (Hashtable)ratingTable[userId];
                // 1. sample a negative feedback for each positive feedback
                int otherItemId = SampleOtherItemId(userId, itemsTable, itemIds, random);

                UpdateFactors(userId, itemId, otherItemId, gamma, lambda, lambda_bias);
            }
        }