コード例 #1
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);
        }
コード例 #2
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)));
            }
        }
コード例 #3
0
        public static ItemsForInputAndEvaluation <MalUserListEntries> DivideClassifiedForInputAndEvaluation(
            ClassifiedUserInput <MalUserListEntries> classifiedInput, double fractionToSetAsideForEvaluation)
        {
            IDictionary <int, MalListEntry> entriesForInput = new Dictionary <int, MalListEntry>();
            HashSet <int> likedAnimesForEvaluation          = new HashSet <int>();
            HashSet <int> unlikedAnimesForEvaluation        = new HashSet <int>();

            // Recommender could potentially use someone's "plan to watch" list to infer information about the user's taste...or something.
            foreach (KeyValuePair <int, MalListEntry> otherEntry in classifiedInput.Other.Entries)
            {
                entriesForInput.Add(otherEntry);
            }

            List <int> likedAnimeIds   = new List <int>(classifiedInput.Liked.Entries.Keys);
            List <int> unlikedAnimeIds = new List <int>(classifiedInput.NotLiked.Entries.Keys);

            likedAnimeIds.Shuffle();
            unlikedAnimeIds.Shuffle();

            int numLikedForEvaluation   = (int)(likedAnimeIds.Count * fractionToSetAsideForEvaluation);
            int numUnlikedForEvaluation = (int)(unlikedAnimeIds.Count * fractionToSetAsideForEvaluation);

            for (int i = 0; i < numLikedForEvaluation; i++)
            {
                likedAnimesForEvaluation.Add(likedAnimeIds[i]);
            }
            for (int i = numLikedForEvaluation; i < likedAnimeIds.Count; i++)
            {
                entriesForInput[likedAnimeIds[i]] = classifiedInput.Liked.Entries[likedAnimeIds[i]];
            }

            for (int i = 0; i < numUnlikedForEvaluation; i++)
            {
                unlikedAnimesForEvaluation.Add(unlikedAnimeIds[i]);
            }
            for (int i = numUnlikedForEvaluation; i < unlikedAnimeIds.Count; i++)
            {
                entriesForInput[unlikedAnimeIds[i]] = classifiedInput.NotLiked.Entries[unlikedAnimeIds[i]];
            }

            return(new ItemsForInputAndEvaluation <MalUserListEntries>()
            {
                ItemsForInput = new MalUserListEntries(entriesForInput, classifiedInput.Liked.AnimesEligibleForRecommendation,
                                                       classifiedInput.Liked.MalUsername, classifiedInput.Liked.OkToRecommendPredicate),
                LikedItemsForEvaluation = likedAnimesForEvaluation,
                UnlikedItemsForEvaluation = unlikedAnimesForEvaluation
            });
        }
コード例 #4
0
        public static ItemsForInputAndEvaluation<MalUserListEntries> DivideClassifiedForInputAndEvaluation(
            ClassifiedUserInput<MalUserListEntries> classifiedInput, double fractionToSetAsideForEvaluation)
        {
            IDictionary<int, MalListEntry> entriesForInput = new Dictionary<int, MalListEntry>();
            HashSet<int> likedAnimesForEvaluation = new HashSet<int>();
            HashSet<int> unlikedAnimesForEvaluation = new HashSet<int>();

            // Recommender could potentially use someone's "plan to watch" list to infer information about the user's taste...or something.
            foreach (KeyValuePair<int, MalListEntry> otherEntry in classifiedInput.Other.Entries)
            {
                entriesForInput.Add(otherEntry);
            }

            List<int> likedAnimeIds = new List<int>(classifiedInput.Liked.Entries.Keys);
            List<int> unlikedAnimeIds = new List<int>(classifiedInput.NotLiked.Entries.Keys);

            likedAnimeIds.Shuffle();
            unlikedAnimeIds.Shuffle();

            int numLikedForEvaluation = (int)(likedAnimeIds.Count * fractionToSetAsideForEvaluation);
            int numUnlikedForEvaluation = (int)(unlikedAnimeIds.Count * fractionToSetAsideForEvaluation);

            for (int i = 0; i < numLikedForEvaluation; i++)
            {
                likedAnimesForEvaluation.Add(likedAnimeIds[i]);
            }
            for (int i = numLikedForEvaluation; i < likedAnimeIds.Count; i++)
            {
                entriesForInput[likedAnimeIds[i]] = classifiedInput.Liked.Entries[likedAnimeIds[i]];
            }

            for (int i = 0; i < numUnlikedForEvaluation; i++)
            {
                unlikedAnimesForEvaluation.Add(unlikedAnimeIds[i]);
            }
            for (int i = numUnlikedForEvaluation; i < unlikedAnimeIds.Count; i++)
            {
                entriesForInput[unlikedAnimeIds[i]] = classifiedInput.NotLiked.Entries[unlikedAnimeIds[i]];
            }

            return new ItemsForInputAndEvaluation<MalUserListEntries>()
            {
                ItemsForInput = new MalUserListEntries(entriesForInput, classifiedInput.Liked.AnimesEligibleForRecommendation,
                    classifiedInput.Liked.MalUsername, classifiedInput.Liked.OkToRecommendPredicate),
                LikedItemsForEvaluation = likedAnimesForEvaluation,
                UnlikedItemsForEvaluation = unlikedAnimesForEvaluation
            };
        }