コード例 #1
0
        public void TestUserRescorer()
        {
            Rescorer <User> rescorer = NullRescorer <User> .Instance;

            Assert.IsNotNull(rescorer);
            User user = new GenericUser <String>("test", new List <Preference>());

            Assert.AreEqual(1.0, rescorer.Rescore(user, 1.0));
            Assert.AreEqual(1.0, rescorer.Rescore(null, 1.0));
            Assert.AreEqual(0.0, rescorer.Rescore(user, 0.0));
            Assert.IsTrue(Double.IsNaN(rescorer.Rescore(user, Double.NaN)));
        }
コード例 #2
0
        public void TestItemRescorer()
        {
            Rescorer <Item> rescorer = NullRescorer <Item> .Instance;

            Assert.IsNotNull(rescorer);
            Item item = new GenericItem <String>("test");

            Assert.AreEqual(1.0, rescorer.Rescore(item, 1.0));
            Assert.AreEqual(1.0, rescorer.Rescore(null, 1.0));
            Assert.AreEqual(0.0, rescorer.Rescore(item, 0.0));
            Assert.IsTrue(Double.IsNaN(rescorer.Rescore(item, Double.NaN)));
        }
コード例 #3
0
        public virtual void TestBasic()
        {
            // create a sort field and sort by it (reverse order)
            Query       query = new TermQuery(new Term("body", "contents"));
            IndexReader r     = searcher.IndexReader;
            // Just first pass query
            TopDocs hits = searcher.Search(query, 10);

            AreEqual(3, hits.TotalHits);
            AreEqual("3", r.Document(hits.ScoreDocs[0].Doc).Get("id"));
            AreEqual("1", r.Document(hits.ScoreDocs[1].Doc).Get("id"));
            AreEqual("2", r.Document(hits.ScoreDocs[2].Doc).Get("id"));
            // Now, rescore:
            Expression     e        = JavascriptCompiler.Compile("sqrt(_score) + ln(popularity)");
            SimpleBindings bindings = new SimpleBindings();

            bindings.Add(new SortField("popularity", SortField.Type_e.INT));
            bindings.Add(new SortField("_score", SortField.Type_e.SCORE));
            Rescorer rescorer = e.GetRescorer(bindings);

            hits = rescorer.Rescore(searcher, hits, 10);
            AreEqual(3, hits.TotalHits);
            AreEqual("2", r.Document(hits.ScoreDocs[0].Doc).Get("id"));
            AreEqual("1", r.Document(hits.ScoreDocs[1].Doc).Get("id"));
            AreEqual("3", r.Document(hits.ScoreDocs[2].Doc).Get("id"));
            string expl = rescorer.Explain(searcher, searcher.Explain(query, hits.ScoreDocs[0].Doc), hits.ScoreDocs[0].Doc).ToString();

            // Confirm the explanation breaks out the individual
            // variables:
            IsTrue(expl.Contains("= variable \"popularity\""));
            // Confirm the explanation includes first pass details:
            IsTrue(expl.Contains("= first pass score"));
            IsTrue(expl.Contains("body:contents in"));
        }
コード例 #4
0
        public int Compare(RecommendedItem o1, RecommendedItem o2)
        {
            double rescored1 = rescorer.Rescore(o1.Item, o1.Value);
            double rescored2 = rescorer.Rescore(o2.Item, o2.Value);

            Debug.Assert(!double.IsNaN(rescored1));
            Debug.Assert(!double.IsNaN(rescored2));
            if (rescored1 < rescored2)
            {
                return(1);
            }
            else if (rescored1 > rescored2)
            {
                return(-1);
            }
            else
            {
                return(0);
            }
        }
コード例 #5
0
            public double Estimate(Item item)
            {
                Pair <Item, Item> pair = new Pair <Item, Item>(toItem, item);

                if (rescorer.IsFiltered(pair))
                {
                    return(Double.NaN);
                }

                double originalEstimate = correlation.GetItemCorrelation(toItem, item);

                return(rescorer.Rescore(pair, originalEstimate));
            }
コード例 #6
0
            public double Estimate(User user)
            {
                Pair <User, User> pair = new Pair <User, User>(toUser, user);

                if (rescorer.IsFiltered(pair))
                {
                    return(Double.NaN);
                }

                double originalEstimate = correlation.GetUserCorrelation(toUser, user);

                return(rescorer.Rescore(pair, originalEstimate));
            }
コード例 #7
0
        /**
         * {@inheritDoc}
         */

        public override IList <RecommendedItem> Recommend(Object userID, int howMany, Rescorer <Item> rescorer)
        {
            if (userID == null || rescorer == null)
            {
                throw new ArgumentNullException("userID or rescorer is null");
            }
            if (howMany < 1)
            {
                throw new ArgumentException("howMany must be at least 1");
            }
            CheckClustersBuilt();

            if (log.IsDebugEnabled)
            {
                log.Debug("Recommending items for user ID '" + userID + '\'');
            }

            IList <RecommendedItem> recommended;

            topRecsByUserID.TryGetValue(userID, out recommended);
            if (recommended == null)
            {
                recommended = new List <RecommendedItem>();
                return(recommended);
            }

            User theUser = this.DataModel.GetUser(userID);
            List <RecommendedItem> rescored = new List <RecommendedItem>(recommended.Count);

            // Only add items the user doesn't already have a preference for.
            // And that the rescorer doesn't "reject".
            foreach (RecommendedItem recommendedItem in recommended)
            {
                Item item = recommendedItem.Item;

                if (rescorer.IsFiltered(item))
                {
                    continue;
                }

                if (theUser.GetPreferenceFor(item.ID) == null &&
                    !double.IsNaN(rescorer.Rescore(item, recommendedItem.Value)))
                {
                    rescored.Add(recommendedItem);
                }
            }
            rescored.Sort(new ByRescoreComparator(rescorer));

            return(rescored);
        }
コード例 #8
0
            public double Estimate(Item item)
            {
                RunningAverage average = new FullRunningAverage();

                foreach (Item toItem in toItems)
                {
                    Pair <Item, Item> pair = new Pair <Item, Item>(toItem, item);
                    if (rescorer.IsFiltered(pair))
                    {
                        continue;
                    }
                    double estimate = correlation.GetItemCorrelation(toItem, item);
                    estimate = rescorer.Rescore(pair, estimate);
                    average.AddDatum(estimate);
                }
                return(average.Average);
            }
コード例 #9
0
ファイル: TopItems.cs プロジェクト: radtek/taste.net
        public static IList <RecommendedItem> GetTopItems(int howMany,
                                                          IEnumerable <Item> allItems,
                                                          Rescorer <Item> rescorer,
                                                          Estimator <Item> estimator)
        {
            if (allItems == null || rescorer == null || estimator == null)
            {
                throw new ArgumentNullException("argument is null");
            }

            LinkedList <RecommendedItem> topItems = new LinkedList <RecommendedItem>();

            bool full = false;

            foreach (Item item in allItems)
            {
                if (item.IsRecommendable && !rescorer.IsFiltered(item))
                {
                    double preference   = estimator.Estimate(item);
                    double rescoredPref = rescorer.Rescore(item, preference);
                    LinkedListNode <RecommendedItem> node = topItems.Last;

                    if (!Double.IsNaN(rescoredPref) &&
                        (!full || rescoredPref > node.Value.Value))
                    {
                        // I think this is faster than Collections.binarySearch() over a LinkedList since our
                        // comparisons are cheap, which binarySearch() economizes at the expense of more traversals.
                        // We also know that the right position tends to be at the end of the list.
                        while (node != null && node.Previous != null)
                        {
                            node = node.Previous;
                            if (rescoredPref <= node.Value.Value)
                            {
                                node = node.Next;
                                break;
                            }

                            if (node == topItems.First)
                            {
                                break;
                            }
                        }

                        RecommendedItem newItem = new GenericRecommendedItem(item, rescoredPref);

                        if (node == null)
                        {
                            topItems.AddFirst(newItem);
                        }
                        else if (topItems.Count == 1)
                        {
                            // special handling in this case is to avoid problems
                            // with negative preferences. Imagine -0.3 being added
                            // first followed by -0.6. If we simply did AddAfter,
                            // those items would be out of sequence - cc
                            if (rescoredPref > node.Value.Value)
                            {
                                topItems.AddAfter(node, newItem);
                            }
                            else
                            {
                                topItems.AddBefore(node, newItem);
                            }
                        }
                        else
                        {
                            topItems.AddAfter(node, newItem);
                        }

                        if (full)
                        {
                            topItems.RemoveLast();
                        }
                        else if (topItems.Count > howMany)
                        {
                            full = true;
                            topItems.RemoveLast();
                        }
                    }
                }
            }

            List <RecommendedItem> result = new List <RecommendedItem>(topItems.Count);

            foreach (RecommendedItem item in topItems)
            {
                result.Add(item);
            }
            return(result);
        }
コード例 #10
0
ファイル: TopItems.cs プロジェクト: radtek/taste.net
        public static List <User> GetTopUsers(int howMany,
                                              IEnumerable <User> allUsers,
                                              Rescorer <User> rescorer,
                                              Estimator <User> estimator)
        {
            LinkedList <SimilarUser> topUsers = new LinkedList <SimilarUser>();
            bool full = false;

            foreach (User user in allUsers)
            {
                if (rescorer.IsFiltered(user))
                {
                    continue;
                }

                double similarity         = estimator.Estimate(user);
                double rescoredSimilarity = rescorer.Rescore(user, similarity);

                LinkedListNode <SimilarUser> node = topUsers.Last;
                if (!double.IsNaN(rescoredSimilarity) &&
                    (!full || rescoredSimilarity > node.Value.Similarity))
                {
                    //SimilarUser _user = new SimilarUser(user, similarity);
                    SimilarUser _user = new SimilarUser(user, rescoredSimilarity);
                    if (node == null)
                    {
                        topUsers.AddLast(_user);
                    }
                    else if (node.Previous == null) // 1 node
                    {
                        if (rescoredSimilarity > node.Value.Similarity)
                        {
                            topUsers.AddAfter(node, _user);
                        }
                        else
                        {
                            topUsers.AddBefore(node, _user);
                        }
                    }
                    else
                    {
                        while (node != null && node.Previous != null && (node != topUsers.First))
                        {
                            node = node.Previous;
                            if (rescoredSimilarity <= node.Value.Similarity)
                            {
                                topUsers.AddBefore(node, _user);
                                break;
                            }
                        }
                    }
                    if (full)
                    {
                        topUsers.RemoveLast();
                    }
                    else if (topUsers.Count > howMany)
                    {
                        full = true;
                        topUsers.RemoveLast();
                    }
                }
            }

            List <User> result = new List <User>(topUsers.Count);

            foreach (SimilarUser similarUser in topUsers)
            {
                result.Add(similarUser.User);
            }
            return(result);
        }