Пример #1
0
        protected List <Rating> GetRecommendations(MyTable ratingTable, MyTable W, int K = 80, int N = 10)
        {
            MyTable recommendedTable = new MyTable();

            foreach (int userId in ratingTable.Keys)
            {
                Hashtable Nu = (Hashtable)ratingTable[userId]; // ratings of user u

                if (!W.ContainsMainKey(userId))                // NOTE: a user bought an item which had only rated by him.
                {
                    continue;
                }

                List <Link> similarUsers = GetSimilarUsers(W, userId, K);
                foreach (Link l in similarUsers)
                {
                    int       vId = l.To;                        // similar user v
                    Hashtable Nv  = (Hashtable)ratingTable[vId]; // ratings of user v
                    foreach (int iId in Nv.Keys)
                    {
                        if (Nu.ContainsKey(iId))
                        {
                            continue;
                        }

                        if (recommendedTable.ContainsKey(userId, iId))
                        {
                            double _t = (double)recommendedTable[userId, iId];
                            recommendedTable[userId, iId] = _t + l.Weight;
                        }
                        else
                        {
                            recommendedTable.Add(userId, iId, l.Weight);
                        }
                    }
                }
            }

            List <Rating> recommendedItems = new List <Rating>();

            foreach (int uId in recommendedTable.Keys)
            {
                List <Rating> li       = new List <Rating>();
                Hashtable     subTable = (Hashtable)recommendedTable[uId];
                foreach (int iId in subTable.Keys)
                {
                    double _t = (double)subTable[iId];
                    li.Add(new Rating(uId, iId, _t));
                }
                List <Rating> sortedLi = li.OrderByDescending(r => r.Score).ToList();
                recommendedItems.AddRange(sortedLi.GetRange(0, Math.Min(sortedLi.Count, N)));
            }
            return(recommendedItems);
        }
Пример #2
0
        protected MyTable GetRecommendationsByTFIDFPlusPlus(MyTable ratingTable, MyTable userTagTable,
                                                            Hashtable tagUsersTable, MyTable tagItemTable, Hashtable itemTagsTable)
        {
            MyTable recommendTable = new MyTable();

            int[] userIds = new int[ratingTable.Keys.Count];
            ratingTable.Keys.CopyTo(userIds, 0);
            Parallel.ForEach(userIds, userId =>
            {
                Hashtable subTable = (Hashtable)ratingTable[userId];
                if (userTagTable.ContainsMainKey(userId))
                {
                    Hashtable tagTable = (Hashtable)userTagTable[userId];
                    foreach (int tagId in tagTable.Keys)
                    {
                        if (!tagItemTable.ContainsMainKey(tagId))
                        {
                            continue;
                        }
                        Hashtable itemTable = (Hashtable)tagItemTable[tagId];
                        foreach (int itemId in itemTable.Keys)
                        {
                            // if user has rated this item
                            if (subTable.ContainsKey(itemId))
                            {
                                continue;
                            }

                            List <Link> n_b = (List <Link>)tagUsersTable[tagId];  // # of users who used this tag
                            List <Link> n_i = (List <Link>)itemTagsTable[itemId]; // # of users who used this tag
                            double wut      = (double)tagTable[tagId];
                            double wti      = (double)itemTable[itemId];
                            double pui      = wut / Math.Log(1 + n_b.Count) * wti / Math.Log(1 + n_i.Count);

                            lock (recommendTable)
                            {
                                if (recommendTable.ContainsKey(userId, itemId))
                                {
                                    recommendTable[userId, itemId] = (double)recommendTable[userId, itemId] + pui;
                                }
                                else
                                {
                                    recommendTable.Add(userId, itemId, pui);
                                }
                            }
                        }
                    }
                }
            });

            return(recommendTable);
        }
Пример #3
0
        protected MyTable GetRecommendations(MyTable ratingTable, MyTable userTagTable, MyTable tagItemTable)
        {
            MyTable recommendTable = new MyTable();

            int[] userIds = new int[ratingTable.Keys.Count];
            ratingTable.Keys.CopyTo(userIds, 0);
            Parallel.ForEach(userIds, userId =>
            {
                Hashtable subTable = (Hashtable)ratingTable[userId];
                if (userTagTable.ContainsMainKey(userId))
                {
                    Hashtable tagTable = (Hashtable)userTagTable[userId];
                    foreach (int tagId in tagTable.Keys)
                    {
                        if (!tagItemTable.ContainsMainKey(tagId))
                        {
                            continue;
                        }
                        Hashtable itemTable = (Hashtable)tagItemTable[tagId];
                        foreach (int itemId in itemTable.Keys)
                        {
                            // if user has rated this item
                            if (subTable.ContainsKey(itemId))
                            {
                                continue;
                            }

                            double wut = (double)tagTable[tagId];
                            double wti = (double)itemTable[itemId];
                            double p   = wut * wti;

                            lock (recommendTable)
                            {
                                if (recommendTable.ContainsKey(userId, itemId))
                                {
                                    recommendTable[userId, itemId] = (double)recommendTable[userId, itemId] + p;
                                }
                                else
                                {
                                    recommendTable.Add(userId, itemId, p);
                                }
                            }
                        }
                    }
                }
            });

            return(recommendTable);
        }
Пример #4
0
        /// <summary>
        /// Mean average precision
        /// https://www.kaggle.com/c/coupon-purchase-prediction#evaluation
        /// </summary>
        /// <param name="recommended">sorted predicted ratings</param>
        /// <param name="test">real ratings</param>
        /// <returns></returns>
        public static double MAP(List <Rating> recommendations, List <Rating> test, int k = 5)
        {
            Hashtable recommendedRatings  = Tools.GetUserItemsTable(recommendations);
            MyTable   testTable           = Tools.GetRatingTable(test); // mark
            int       validateUserCounter = 0;
            double    _MAP = 0.0;

            foreach (int userId in recommendedRatings.Keys)
            {
                if (testTable.ContainsMainKey(userId))
                {
                    List <Rating> recommendedUserRatings = (List <Rating>)recommendedRatings[userId];
                    Hashtable     testUserRatings        = (Hashtable)testTable[userId];

                    int   length   = (k > recommendedUserRatings.Count ? recommendedUserRatings.Count : k);
                    int[] accuracy = new int[length];
                    int   correctlyPredictedItems = 0;
                    for (int i = 0; i < length; i++)
                    {
                        if (testUserRatings.ContainsKey(recommendedUserRatings[i].ItemId))  // correctly predicted
                        {
                            correctlyPredictedItems++;
                            accuracy[i] = correctlyPredictedItems;
                        }
                    }

                    if (correctlyPredictedItems > 0)
                    {
                        double APu = 0.0;   // average precision of user u
                        for (int i = 0; i < length; i++)
                        {
                            APu += (accuracy[i] * 1.0 / (i + 1));
                        }
                        APu  /= length;
                        _MAP += APu;
                    }
                    validateUserCounter++;  // recommended users which also in test
                }
            }

            if (validateUserCounter > 0)
            {
                return(_MAP / validateUserCounter);
            }

            return(0.0);
        }