private void AddRecommender <TUserRatings>(int userId, TUserRatings ratings, IUserInputClassifier <TUserRatings> recommenderRatingClassifier)
            where TUserRatings : IInputForUserWithItemIds
        {
            ClassifiedUserInput <TUserRatings> classifiedRatings = recommenderRatingClassifier.Classify(ratings);

            List <int>  recs        = new List <int>(classifiedRatings.Liked.ItemIds);
            Recommender recommender = new Recommender(userId, recs);

            Recommenders.Add(recommender);
        }
Beispiel #2
0
        public IBasicTrainingData <IPositiveFeedbackForUser> AsPositiveFeedback(IUserInputClassifier <MalUserListEntries> classifier)
        {
            Dictionary <int, IPositiveFeedbackForUser> basicUsers = new Dictionary <int, IPositiveFeedbackForUser>();

            foreach (int userId in Users.Keys)
            {
                basicUsers[userId] = Users[userId].AsPositiveFeedback(classifier);
            }

            return(new BasicTrainingData <IPositiveFeedbackForUser>(basicUsers));
        }
Beispiel #3
0
        private SingleUserEvaluationResults GetSingleUserEvaluationResults <TInput, TRecommendation>(
            IRecommendationSource <TInput, IEnumerable <TRecommendation>, TRecommendation> recSource,
            TInput user,
            IUserInputClassifier <TInput> goodBadClassifier,
            Func <ClassifiedUserInput <TInput>, double, ItemsForInputAndEvaluation <TInput> > inputDivisionFunc,
            int numRecsToTryToGet)

            where TInput : IInputForUser
            where TRecommendation : IRecommendation
        {
            // Divide into liked and unliked.
            // Set aside a random X% of the liked and a random X% of the unliked
            ClassifiedUserInput <TInput>        classified = goodBadClassifier.Classify(user);
            ItemsForInputAndEvaluation <TInput> divided    = inputDivisionFunc(classified, FractionOfInputToSetAsideForEvaluation);

            // Get top N recommendations
            // Keep count of hits and false positives

            List <int> recommendedIds            = new List <int>();
            int        truePositivesForThisUser  = 0;
            int        falsePositivesForThisUser = 0;
            int        unknownsForThisUser       = 0;

            foreach (TRecommendation recommendation in recSource.GetRecommendations(divided.ItemsForInput, numRecsToTryToGet))
            {
                recommendedIds.Add(recommendation.ItemId);

                if (divided.LikedItemsForEvaluation.Contains(recommendation.ItemId))
                {
                    truePositivesForThisUser++;
                }
                else if (divided.UnlikedItemsForEvaluation.Contains(recommendation.ItemId))
                {
                    falsePositivesForThisUser++;
                }
                else
                {
                    unknownsForThisUser++;
                }
            }

            int falseNegativesForThisUser = divided.LikedItemsForEvaluation.Count - truePositivesForThisUser;

            SingleUserEvaluationResults results = new SingleUserEvaluationResults()
            {
                TruePositives  = truePositivesForThisUser,
                FalsePositives = falsePositivesForThisUser,
                Unknowns       = unknownsForThisUser,
                FalseNegatives = falseNegativesForThisUser,
            };

            return(results);
        }
Beispiel #4
0
        public IPositiveFeedbackForUser AsPositiveFeedback(IUserInputClassifier <MalUserListEntries> classifier, Predicate <int> additionalOkToRecommendPredicate)
        {
            ClassifiedUserInput <MalUserListEntries> classified = classifier.Classify(this);
            HashSet <int> basicFeedback = new HashSet <int>(classified.Liked.Entries.Select(itemIdEntryPair => itemIdEntryPair.Key));

            if (additionalOkToRecommendPredicate == null)
            {
                return(new BasicPositiveFeedbackForUserWithOkToRecommendPredicate(basicFeedback, ItemIsOkToRecommend));
            }
            else
            {
                return(new BasicPositiveFeedbackForUserWithOkToRecommendPredicate(basicFeedback, (itemId) =>
                                                                                  ItemIsOkToRecommend(itemId) && additionalOkToRecommendPredicate(itemId)));
            }
        }
Beispiel #5
0
        /// <summary>
        ///
        /// </summary>
        /// <typeparam name="TInput"></typeparam>
        /// <typeparam name="TRecommendation"></typeparam>
        /// <param name="recSource">A recommendation source that has already been trained.</param>
        /// <param name="users">The users to use in evaluation by getting recommendations for them.</param>
        /// <param name="goodBadClassifier">Classifier to classify input for a user into liked items and unliked items. If an
        /// item was left out of the input passed to the recommendation source and it gets recommended, this determines whether
        /// it gets considered a true positive or a false positive.</param>
        /// <param name="inputDivisionFunc">Takes a user's classified input and a fraction to set aside (.2 for 20%) and returns
        /// a new user input object and the items that were set aside.</param>
        /// <param name="numRecsToTryToGet">Number of recommendations to try to get for each user.</param>
        /// <returns></returns>
        public EvaluationResults Evaluate <TInput, TRecommendation>(
            IRecommendationSource <TInput, IEnumerable <TRecommendation>, TRecommendation> recSource,
            ICollection <TInput> users,
            IUserInputClassifier <TInput> goodBadClassifier,
            Func <ClassifiedUserInput <TInput>, double, ItemsForInputAndEvaluation <TInput> > inputDivisionFunc,
            int numRecsToTryToGet)

            where TInput : IInputForUser
            where TRecommendation : IRecommendation
        {
            EvaluationResults results = new EvaluationResults()
            {
                TotalTruePositives  = 0,
                TotalFalsePositives = 0,
                TotalUnknown        = 0,
                TotalFalseNegatives = 0,
                TotalPrecision      = 0,
                NumPrecision        = 0,
                TotalRecall         = 0,
                NumRecall           = 0
            };

            foreach (TInput user in users)
            {
                SingleUserEvaluationResults userResults = GetSingleUserEvaluationResults(recSource, user, goodBadClassifier,
                                                                                         inputDivisionFunc, numRecsToTryToGet);

                results.TotalTruePositives  += userResults.TruePositives;
                results.TotalFalsePositives += userResults.FalsePositives;
                results.TotalUnknown        += userResults.Unknowns;
                results.TotalFalseNegatives += userResults.FalseNegatives;

                if (userResults.Precision.HasValue)
                {
                    results.TotalPrecision += userResults.Precision.Value;
                    results.NumPrecision++;
                }

                if (userResults.Recall.HasValue)
                {
                    results.TotalRecall += userResults.Recall.Value;
                    results.NumRecall++;
                }
            }

            return(results);
        }
Beispiel #6
0
 public IPositiveFeedbackForUser AsPositiveFeedback(IUserInputClassifier <MalUserListEntries> classifier)
 {
     return(AsPositiveFeedback(classifier, null));
 }
        public IPositiveFeedbackForUser AsPositiveFeedback(IUserInputClassifier<MalUserListEntries> classifier, Predicate<int> additionalOkToRecommendPredicate)
        {
            ClassifiedUserInput<MalUserListEntries> classified = classifier.Classify(this);
            HashSet<int> basicFeedback = new HashSet<int>(classified.Liked.Entries.Select(itemIdEntryPair => itemIdEntryPair.Key));

            if (additionalOkToRecommendPredicate == null)
            {
                return new BasicPositiveFeedbackForUserWithOkToRecommendPredicate(basicFeedback, ItemIsOkToRecommend);
            }
            else
            {
                return new BasicPositiveFeedbackForUserWithOkToRecommendPredicate(basicFeedback, (itemId) =>
                    ItemIsOkToRecommend(itemId) && additionalOkToRecommendPredicate(itemId));
            }
        }
 public IPositiveFeedbackForUser AsPositiveFeedback(IUserInputClassifier<MalUserListEntries> classifier)
 {
     return AsPositiveFeedback(classifier, null);
 }
Beispiel #9
0
 public AnimeRecsTrainingData(TUnderlyingTrainingData trainingData, IUserInputClassifier <TUserRatings> recommenderRatingClassifier)
 {
     TrainingData = trainingData;
     RecommenderRatingClassifier = recommenderRatingClassifier;
 }