예제 #1
0
        /// <summary>
        /// Returns a distance-based similarity score for person1 and person2
        /// </summary>
        /// <param name="user1"></param>
        /// <param name="user2"></param>
        /// <returns></returns>
        public double CalculateSimilarity(UserRating user1, UserRating user2)
        {
            var sharedItems = new List <uint>();

            // Get the list of shared movies
            foreach (var movieId in user1.GetRatedMovies())
            {
                if (user2.HasRating(movieId))
                {
                    sharedItems.Add(movieId);
                }
            }

            // if they have no ratings in common, return 0
            if (sharedItems.Count == 0)
            {
                return(0);
            }

            // Add up the squares of all the differences
            var sumOfSquares = 0.0;

            foreach (var movieID in sharedItems)
            {
                sumOfSquares += Math.Pow(user1.GetRating(movieID) - user2.GetRating(movieID), 2);
            }

            return(1 / (1 + sumOfSquares));
        }
예제 #2
0
        /// <summary>
        /// Gets recommendations for a person by using a weighted average
        /// of every other user's rankings
        /// </summary>
        /// <param name=""></param>
        /// <param name=""></param>
        /// <param name=""></param>
        /// <returns></returns>
        public List <Tuple <double, uint> > GetRecommendations(UserRating person)
        {
            var totals  = new Dictionary <uint, double>();
            var simSums = new Dictionary <uint, double>();

            foreach (var other in UserRatings.Values)
            {
                if (other.UserID == person.UserID)
                {
                    continue;
                }
                var similarity = CalculateSimilarity(person, other);
                //# ignore scores of zero or lower
                if (similarity <= 0)
                {
                    continue;
                }

                foreach (var item in other.GetRatedMovies())
                {
                    // only score movies I haven't seen yet
                    if (!person.HasRating(item) || person.GetRating(item) == 0)
                    {
                        // Similarity * Score
                        if (totals.ContainsKey(item))
                        {
                            totals[item]  += other.GetRating(item) * similarity;
                            simSums[item] += similarity;
                        }
                        else
                        {
                            totals.Add(item, other.GetRating(item) * similarity);
                            simSums.Add(item, similarity);
                        }
                    }
                }
            }

            var rankings = new List <Tuple <double, uint> >();

            // Create the normalized list
            foreach (var item in totals.Keys)
            {
                rankings.Add(new Tuple <double, uint>(totals[item] / simSums[item], item));
            }

            // Return the sorted list
            rankings.Sort();
            rankings.Reverse();
            return(rankings);
        }