public IRating RecommendSubject(IRater rater, ISubject subject)
        {
            var raters   = ratings.Select(r => r.Rater.Id).ToArray();
            var subjects = ratings.Select(r => r.Subject.Id).ToArray();
            var rates    = ratings.Select(r => r.Value).ToArray();

            Vector[] xData = new Vector[raters.Length];
            for (int i = 0; i < xData.Length; ++i)
            {
                xData[i] = Vector.FromArray(raters[i], subjects[i], 1);
            }

            VariableArray <Vector> x = Variable.Observed(xData);
            var Y = Variable.Observed(rates, x.Range);
            Variable <Vector> w     = Variable.Random(new VectorGaussian(Vector.Zero(3), PositiveDefiniteMatrix.Identity(3)));
            Range             j     = Y.Range;
            double            noise = 0.1;

            Y[j] = Variable.GaussianFromMeanAndVariance(Variable.InnerProduct(w, x[j]), noise);

            var Engine     = new InferenceEngine(new ExpectationPropagation());
            var WPosterior = Engine.Infer <VectorGaussian>(w);

            double [] ratersTest = new double[1];
            ratersTest[0] = rater.Id;
            double [] subjectsTest = new double[1];
            subjectsTest[0] = subject.Id;

            var yTest = BayesPointMachine(ratersTest, subjectsTest, WPosterior);
            var pred  = Engine.Infer <DistributionStructArray <Gaussian, double> >(yTest);

            return(new SimpleRating(rater, subject, pred[0].Point));
        }
Esempio n. 2
0
        internal override decimal Weight(IRater baseRater, IRater neighbour)
        {
            var isBaseUserCached  = !_notCachedWeights.TryUpdate(baseRater.Id, false, true);
            var isNeighbourCached = !_notCachedWeights.TryUpdate(neighbour.Id, false, true);
            var areCached         = isBaseUserCached && isNeighbourCached;

            var key          = string.Format("{0}_{1}", baseRater.Id, neighbour.Id);
            var reverseKey   = string.Format("{0}_{1}", neighbour.Id, baseRater.Id);
            var cachedWeight = 0M;

            if (areCached && _userWeightsCache.TryGetValue(key, out cachedWeight))
            {
                return(cachedWeight);
            }
            if (areCached && _userWeightsCache.TryGetValue(reverseKey, out cachedWeight))
            {
                return(cachedWeight);
            }

            cachedWeight = _algorithm.Weight(baseRater, neighbour);

            _userWeightsCache[key] = cachedWeight;

            return(cachedWeight);
        }
Esempio n. 3
0
        /// <summary>
        /// Get a list of all users and their ratings on every article
        /// </summary>
        public UserArticleRatingsTable GetUserArticleRatingsTable(IRater rater)
        {
            UserArticleRatingsTable table = new UserArticleRatingsTable();

            table.UserIndexToID    = db.Users.OrderBy(x => x.UserID).Select(x => x.UserID).Distinct().ToList();
            table.ArticleIndexToID = db.Articles.OrderBy(x => x.ArticleID).Select(x => x.ArticleID).Distinct().ToList();

            foreach (int userId in table.UserIndexToID)
            {
                table.Users.Add(new UserArticleRatings(userId, table.ArticleIndexToID.Count));
            }

            var userArticleRatingGroup = db.UserActions
                                         .GroupBy(x => new { x.UserID, x.ArticleID })
                                         .Select(g => new { g.Key.UserID, g.Key.ArticleID, Rating = rater.GetRating(g.ToList()) })
                                         .ToList();

            foreach (var userAction in userArticleRatingGroup)
            {
                int userIndex    = table.UserIndexToID.IndexOf(userAction.UserID);
                int articleIndex = table.ArticleIndexToID.IndexOf(userAction.ArticleID);

                table.Users[userIndex].ArticleRatings[articleIndex] = userAction.Rating;
            }

            return(table);
        }
        internal override decimal Weight(IRater baseRater, IRater neighbour)
        {
            var helper = new RatingService();

            var baseSum     = baseRater.Ratings.Sum(p => p.Value * p.Value);
            var neighSum    = neighbour.Ratings.Sum(p => p.Value * p.Value);
            var denominator = (decimal)(Math.Sqrt(baseSum) * Math.Sqrt(neighSum));
            var sum         = 0M;

            foreach (var pair in helper.GetCommonRatings(baseRater, neighbour))
            {
                var ratingBase  = (decimal)pair.FirstRating.Value;
                var ratingNeigh = (decimal)pair.SecondRating.Value;

                sum += ratingBase * ratingNeigh;
            }

            if (denominator == 0)
            {
                return(0);
            }

            var result = sum / denominator;

            return(result);
        }
 public UserCollaborativeFilterRecommender(IComparer userComparer, IRater implicitRater, int numberOfNeighbors, int latentFeatures)
 {
     comparer               = userComparer;
     rater                  = implicitRater;
     neighborCount          = numberOfNeighbors;
     latentUserFeatureCount = latentFeatures;
 }
Esempio n. 6
0
        public virtual IEnumerable <IRating> RecommendSubjects(IRater rater, IEnumerable <ISubject> subjects, int take = -1, int skip = 0)
        {
            var dict = new Dictionary <ISubject, IRating>();

            foreach (var subject in subjects)
            {
                if (!dict.ContainsKey(subject))
                {
                    dict[subject] = RecommendSubject(rater, subject);
                }
            }

            var sortedList = dict.Values.Where(p => p != null).Where(p => p.Value != null).OrderByDescending(p => p.Value).AsEnumerable();

            if (skip > 0)
            {
                sortedList = sortedList.Skip(skip);
            }
            if (take > 0)
            {
                sortedList = sortedList.Take(take);
            }

            return(sortedList);
        }
Esempio n. 7
0
        public virtual IRating RecommendSubject(IRater rater, ISubject subject)
        {
            var alreadyRated = Ratings.Find(p => p.Rater.Id == rater.Id && p.Subject.Id == subject.Id);

            if (alreadyRated != null)
            {
                return(alreadyRated);
            }

            var ratings = Ratings.Where(p => p.Subject.Id == subject.Id && p.Rater.Id != rater.Id).ToList();

            if (!ratings.Any())
            {
                return(null);
            }

            var meanVote = RatersMeanVote(rater);
            var options  = new ParallelOptions()
            {
                MaxDegreeOfParallelism = Environment.ProcessorCount
            };
            var sumBag       = new ConcurrentBag <decimal>();
            var weightSumBag = new ConcurrentBag <decimal>();

            Parallel.ForEach(ratings, options, rating =>
            {
                try
                {
                    var weight = Weight(rater, rating.Rater);
                    var mean   = RatersMeanVote(rating.Rater);
                    var value  = (decimal)rating.Value;
                    var diff   = value - mean;
                    var val    = weight * diff;

                    weightSumBag.Add(weight);
                    sumBag.Add(val);
                }
                catch (Exception) { }
            });

            var sum       = sumBag.Sum();
            var weightSum = weightSumBag.Sum();

            if (weightSum == 0)
            {
                return(null);
            }

            var kappa  = 1 / weightSum;
            var result = meanVote + kappa * sum;
            var res    = (double)result;
            var rate   = new SimpleRating(rater, subject, res);

            return(rate);
        }
Esempio n. 8
0
 protected virtual void Initialize(IRater firstRater, IRater secondRater) //O(nlogn)
 {
     FirstRater        = firstRater;
     SecondRater       = secondRater;
     RatingsFirstSort  = firstRater.Ratings.OrderBy(p => p.Subject.Id);
     RatingsSecondSort = secondRater.Ratings.OrderBy(p => p.Subject.Id);
     IndexFirst        = 0;
     IndexSecond       = 0;
     CountFirst        = RatingsFirstSort.Count();
     CountSecond       = RatingsSecondSort.Count();
 }
Esempio n. 9
0
        internal override decimal Weight(IRater baseRater, IRater neighbour)
        {
            var weight = (double)_algorithm.Weight(baseRater, neighbour);

            if (weight >= 0)
            {
                return((decimal)Math.Pow(weight, Ro));
            }

            return((decimal) - Math.Pow(-weight, Ro));
        }
Esempio n. 10
0
        protected internal virtual decimal RatersMeanVote(IRater rater)
        {
            var sum   = 0M;
            var count = 0;

            foreach (var rating in rater.Ratings)
            {
                sum += (decimal)rating.Value;
                ++count;
            }

            return(sum / count);
        }
Esempio n. 11
0
        protected internal override decimal RatersMeanVote(IRater rater)
        {
            var isCached = !_notCachedMeanVotes.TryUpdate(rater.Id, false, true);
            var value    = 0M;

            if (isCached && _userMeanVotesCache.TryGetValue(rater.Id, out value))
            {
                return(value);
            }

            value = base.RatersMeanVote(rater);

            _userMeanVotesCache[rater.Id] = value;

            return(value);
        }
        public IRating RecommendSubject(IRater rater, ISubject subject)
        {
            var key         = CreateCacheKey(rater, subject);
            var cachedValue = 0D;

            if (_cache.TryGetValue(key, out cachedValue))
            {
                return(new SimpleRating(rater, subject, cachedValue));
            }

            var rating = _algorithm.RecommendSubject(rater, subject);

            if (rating != null)
            {
                _cache[key] = rating.Value;
            }

            return(rating);
        }
        public IEnumerable <IRating> RecommendSubjects(IRater rater, IEnumerable <ISubject> subjects, int take = -1, int skip = 0)
        {
            var cachedResults     = new ConcurrentBag <IRating>();
            var notCachedSubjects = new ConcurrentBag <ISubject>();
            var options           = new ParallelOptions()
            {
                MaxDegreeOfParallelism = Environment.ProcessorCount
            };

            Parallel.ForEach(subjects, options, subject =>
            {
                var key   = CreateCacheKey(rater, subject);
                var value = 0D;
                if (_cache.TryGetValue(key, out value))
                {
                    var ranking = new SimpleRating(rater, subject, value);
                    cachedResults.Add(ranking);
                }
                else
                {
                    notCachedSubjects.Add(subject);
                }
            });

            var partial = _algorithm.RecommendSubjects(rater, notCachedSubjects);

            var results = partial.ToList();

            results.AddRange(cachedResults);

            var sorted = results.OrderByDescending(p => p.Value).AsEnumerable();

            if (skip > 0)
            {
                sorted = sorted.Skip(skip);
            }
            if (take > 0)
            {
                sorted = sorted.Take(take);
            }

            return(sorted);
        }
Esempio n. 14
0
        public virtual IEnumerable <Pair> GetCommonRatings(IRater firstRater, IRater secondRater) //O(n)
        {
            if (FirstRater != firstRater || SecondRater != secondRater)
            {
                Initialize(firstRater, secondRater);
            }

            while (IndexFirst < CountFirst && IndexSecond < CountSecond)
            {
                var firstRating  = RatingsFirstSort.ElementAt(IndexFirst);
                var secondRating = RatingsSecondSort.ElementAt(IndexSecond);

                var pair = ProcessRatings(firstRating, secondRating);

                if (pair != null)
                {
                    yield return(pair);
                }
            }
        }
        internal override decimal Weight(IRater baseRater, IRater neighbour)
        {
            var helper = new RatingService();

            var frequencySum          = 0M;
            var commonRatingsSum      = 0M;
            var baseRatingsSum        = 0M;
            var neighRatingsSum       = 0M;
            var baseRatingsSquareSum  = 0M;
            var neighRatingsSquareSum = 0M;

            foreach (var pair in helper.GetCommonRatings(baseRater, neighbour))
            {
                var baseRating  = (decimal)pair.FirstRating.Value;
                var neighRating = (decimal)pair.SecondRating.Value;
                var frequency   = GetFrequency(pair.FirstRating.Subject);

                frequencySum     += frequency;
                commonRatingsSum += frequency * baseRating * neighRating;
                baseRatingsSum   += frequency * baseRating;
                neighRatingsSum  += frequency * neighRating;

                baseRatingsSquareSum  += frequency * (baseRating * baseRating);
                neighRatingsSquareSum += frequency * (neighRating * neighRating);
            }

            var numerator    = frequencySum * commonRatingsSum - baseRatingsSum * neighRatingsSum;
            var firstFactor  = frequencySum * (baseRatingsSquareSum - baseRatingsSum * baseRatingsSum);
            var secondFactor = frequencySum * (neighRatingsSquareSum - neighRatingsSum * neighRatingsSum);
            var factors      = (double)(firstFactor * secondFactor);
            var denominator  = (decimal)Math.Sqrt(Math.Abs(factors));

            if (denominator == 0)
            {
                return(0);
            }

            var result = numerator / denominator;

            return(result);
        }
        public IEnumerable <IRating> RecommendSubjects(IRater rater, IEnumerable <ISubject> subjects, int take = -1, int skip = 0)
        {
            var raters       = ratings.Select(r => r.Rater.Id).ToArray();
            var subjectsInit = ratings.Select(r => r.Subject.Id).ToArray();
            var rates        = ratings.Select(r => r.Value).ToArray();

            Vector[] xData = new Vector[raters.Length];
            for (int i = 0; i < xData.Length; ++i)
            {
                xData[i] = Vector.FromArray(raters[i], subjectsInit[i], 1);
            }

            VariableArray <Vector> x = Variable.Observed(xData);
            var Y = Variable.Observed(rates, x.Range);
            Variable <Vector> w     = Variable.Random(new VectorGaussian(Vector.Zero(3), PositiveDefiniteMatrix.Identity(3)));
            Range             j     = Y.Range;
            double            noise = 0.1;

            Y[j] = Variable.GaussianFromMeanAndVariance(Variable.InnerProduct(w, x[j]), noise);

            var Engine     = new InferenceEngine(new ExpectationPropagation());
            var WPosterior = Engine.Infer <VectorGaussian>(w);

            var subjectsArray = subjects.ToArray();

            var ratersTest      = Enumerable.Repeat((double)rater.Id, subjectsArray.Length).ToArray();
            var subjectsIdsTest = subjects.Select(s => (double)s.Id).ToArray();

            var yTest = BayesPointMachine(ratersTest, subjectsIdsTest, WPosterior);
            var pred  = Engine.Infer <DistributionStructArray <Gaussian, double> >(yTest);

            var results = new List <IRating>();

            for (int i = 0; i < subjectsArray.Length; ++i)
            {
                results.Add(new SimpleRating(rater, subjectsArray[i], pred[i].Point));
            }

            return(results.OrderBy(r => r.Value).Skip(skip).Take(take));
        }
        /// <summary>
        /// Get a list of all users and their ratings on every article
        /// </summary>
        public UserArticleRatingsTable GetUserArticleRatingsTable(IRater rater)
        {
            UserArticleRatingsTable table = new UserArticleRatingsTable();

            table.UserIndexToID    = db.Users.OrderBy(x => x.UserID).Select(x => x.UserID).Distinct().ToList();
            table.ArticleIndexToID = db.Articles.OrderBy(x => x.ArticleID).Select(x => x.ArticleID).Distinct().ToList();
            table.Ang1             = db.Articles.Select(x => x.Name).ToList();
            List <string> name = new List <string>();

            name = table.Ang1;
            foreach (int userId in table.UserIndexToID)
            {
                table.Users.Add(new UserArticleRatings(userId, table.ArticleIndexToID.Count));
            }

            List <ArticleAndTag> articleTags = new List <ArticleAndTag>();

            foreach (Article article in db.Articles)
            {
                table.art.Add(new ArticleAndTag(article.ArticleID, article.Name, article.Tags));
            }


            var userArticleRatingGroup = db.UserActions
                                         .GroupBy(x => new { x.UserID, x.ArticleID })
                                         .Select(g => new { g.Key.UserID, g.Key.ArticleID, Rating = rater.GetRating(g.ToList()) })
                                         .ToList();

            foreach (var userAction in userArticleRatingGroup)
            {
                int userIndex    = table.UserIndexToID.IndexOf(userAction.UserID);
                int articleIndex = table.ArticleIndexToID.IndexOf(userAction.ArticleID);

                table.Users[userIndex].ArticleRatings[articleIndex] = userAction.Rating;
            }

            return(table);
        }
        public override IEnumerable <Pair> GetCommonRatings(IRater firstRater, IRater secondRater)
        {
            var list = base.GetCommonRatings(firstRater, secondRater);

            foreach (var pair in list)
            {
                yield return(pair);
            }

            var tail = GetRatingTail(ref IndexFirst, CountFirst, RatingsFirstSort, firstRater, true);

            foreach (var pair in tail)
            {
                yield return(pair);
            }

            tail = GetRatingTail(ref IndexSecond, CountSecond, RatingsSecondSort, secondRater, false);

            foreach (var pair in tail)
            {
                yield return(pair);
            }
        }
        internal override decimal Weight(IRater baseRater, IRater neighbour)
        {
            var helper = GetRatingService();

            var baseUsersMean       = RatersMeanVote(baseRater);
            var neighbourMean       = RatersMeanVote(neighbour);
            var numerator           = 0M;
            var denominatorSumBase  = 0M;
            var denominatorSumNeigh = 0M;

            foreach (var pair in helper.GetCommonRatings(baseRater, neighbour))
            {
                var ratingBase  = (decimal)pair.FirstRating.Value;
                var ratingNeigh = (decimal)pair.SecondRating.Value;

                var diffBase  = ratingBase - baseUsersMean;
                var diffNeigh = ratingNeigh - neighbourMean;

                numerator           += diffBase * diffNeigh;
                denominatorSumBase  += diffBase * diffBase;
                denominatorSumNeigh += diffNeigh * diffNeigh;
            }
            ;

            var tmp         = (double)(denominatorSumBase * denominatorSumNeigh);
            var denominator = (decimal)Math.Sqrt(tmp);

            if (denominator == 0)
            {
                return(0);
            }

            var result = numerator / denominator;

            return(result);
        }
 public ItemCollaborativeFilterRecommender(IComparer itemComparer, IRater implicitRater, int numberOfNeighbors)
 {
     comparer      = itemComparer;
     rater         = implicitRater;
     neighborCount = numberOfNeighbors;
 }
 public SimpleRating(IRater rater, ISubject subject, double value)
 {
     Rater   = rater;
     Subject = subject;
     Value   = value;
 }
 public UserCollaborativeFilterRecommender(IComparer userComparer, IRater implicitRater, int numberOfNeighbors)
     : this(userComparer, implicitRater, numberOfNeighbors, 100)
 {
 }
 private string CreateCacheKey(IRater rater, ISubject subject)
 {
     return(string.Format("{0}_{1}", rater.Id, subject.Id));
 }
Esempio n. 24
0
 public MatrixFactorizationRecommender(IRater implicitRater)
     : this(20, implicitRater)
 {
 }
Esempio n. 25
0
 public MatrixFactorizationRecommender(int features, IRater implicitRater)
 {
     numFeatures        = features;
     learningIterations = 100;
     rater = implicitRater;
 }
Esempio n. 26
0
        public static ScoreResults Score(this IRecommender classifier, UserBehaviorDatabase db, IRater rater)
        {
            UserBehaviorTransformer ubt           = new UserBehaviorTransformer(db);
            UserArticleRatingsTable actualRatings = ubt.GetUserArticleRatingsTable(rater);

            var distinctUserArticlePairs = db.UserActions.GroupBy(x => new { x.UserID, x.ArticleID }).ToList();

            double score = 0.0;
            int    count = 0;

            foreach (var userArticle in distinctUserArticlePairs)
            {
                int userIndex    = actualRatings.UserIndexToID.IndexOf(userArticle.Key.UserID);
                int articleIndex = actualRatings.ArticleIndexToID.IndexOf(userArticle.Key.ArticleID);

                double actualRating = actualRatings.Users[userIndex].ArticleRatings[articleIndex];

                if (actualRating != 0)
                {
                    double predictedRating = classifier.GetRating(userArticle.Key.UserID, userArticle.Key.ArticleID);

                    score += Math.Pow(predictedRating - actualRating, 2);
                    count++;
                }
            }

            if (count > 0)
            {
                score = Math.Sqrt(score / count);
            }

            return(new ScoreResults(score));
        }
Esempio n. 27
0
 internal abstract decimal Weight(IRater baseRater, IRater neighbour);
        private IEnumerable <Pair> GetRatingTail(ref int index, int count, IEnumerable <IRating> ratings, IRater rater, bool isSecondFake)
        {
            var list = new LinkedList <Pair>();

            while (index < count)
            {
                var rating     = ratings.ElementAt(index);
                var ratingFake = new SimpleRating(rater, rating.Subject, _defaultValue);
                var pair       = isSecondFake
                    ? new Pair()
                {
                    FirstRating = rating, SecondRating = ratingFake
                }
                    : new Pair()
                {
                    FirstRating = ratingFake, SecondRating = rating
                };

                ++index;

                list.AddLast(pair);
            }

            return(list);
        }