Ejemplo n.º 1
0
        public override IList <IRecommendedItem> Recommend(long userID, int howMany, IDRescorer rescorer)
        {
            IDataModel dataModel           = GetDataModel();
            int        numItems            = dataModel.GetNumItems();
            List <IRecommendedItem> result = new List <IRecommendedItem>(howMany);

            while (result.Count < howMany)
            {
                var it = dataModel.GetItemIDs();
                it.MoveNext();

                var skipNum = random.nextInt(numItems);
                for (int i = 0; i < skipNum; i++)
                {
                    if (!it.MoveNext())
                    {
                        break;
                    }                           // skip() ??
                }
                long itemID = it.Current;
                if (dataModel.GetPreferenceValue(userID, itemID) == null)
                {
                    result.Add(new GenericRecommendedItem(itemID, randomPref()));
                }
            }
            return(result);
        }
Ejemplo n.º 2
0
        public List <RecommendedItem> recommend(long userID, int howMany, IDRescorer rescorer)
        {
            lock (this.maxHowMany)
            {
                if (howMany > this.maxHowMany[0])
                {
                    this.maxHowMany[0] = howMany;
                }
            }
            if (userID == -9223372036854775808L)
            {
                return(this.recommendationsRetriever.get(-9223372036854775808L).getItems());
            }
            this.setCurrentRescorer(rescorer);
            Recommendations recommendations = this.recommendationCache.get(userID);

            if ((recommendations.getItems().Count < howMany) && !recommendations.isNoMoreRecommendableItems())
            {
                this.clear(userID);
                recommendations = this.recommendationCache.get(userID);
                if (recommendations.getItems().Count < howMany)
                {
                    recommendations.setNoMoreRecommendableItems(true);
                }
            }
            List <RecommendedItem> list = recommendations.getItems();

            return((list.Count > howMany) ? list.GetRange(0, howMany) : list);
        }
Ejemplo n.º 3
0
        public override List <RecommendedItem> recommend(long userID, int howMany, IDRescorer rescorer)
        {
            DataModel model             = this.getDataModel();
            int       n                 = model.getNumItems();
            List <RecommendedItem> list = new List <RecommendedItem>(howMany);

            while (list.Count < howMany)
            {
                IEnumerator <long> enumerator = model.getItemIDs();
                enumerator.MoveNext();
                int num2 = this.random.nextInt(n);
                for (int i = 0; i < num2; i++)
                {
                    if (!enumerator.MoveNext())
                    {
                        break;
                    }
                }
                long current = enumerator.Current;
                if (!model.getPreferenceValue(userID, current).HasValue)
                {
                    list.Add(new GenericRecommendedItem(current, this.randomPref()));
                }
            }
            return(list);
        }
Ejemplo n.º 4
0
        public IList <IRecommendedItem> Recommend(long userID, int howMany, IDRescorer rescorer)
        {
            //Preconditions.checkArgument(howMany >= 1, "howMany must be at least 1");
            lock (maxHowMany) {
                if (howMany > maxHowMany[0])
                {
                    maxHowMany[0] = howMany;
                }
            }

            // Special case, avoid caching an anonymous user
            if (userID == PlusAnonymousUserDataModel.TEMP_USER_ID)
            {
                return(recommendationsRetriever.Get(PlusAnonymousUserDataModel.TEMP_USER_ID).getItems());
            }

            setCurrentRescorer(rescorer);

            Recommendations recommendations = recommendationCache.Get(userID);

            if (recommendations.getItems().Count < howMany && !recommendations.isNoMoreRecommendableItems())
            {
                clear(userID);
                recommendations = recommendationCache.Get(userID);
                if (recommendations.getItems().Count < howMany)
                {
                    recommendations.setNoMoreRecommendableItems(true);
                }
            }

            List <IRecommendedItem> recommendedItems = recommendations.getItems();

            return(recommendedItems.Count > howMany?recommendedItems.GetRange(0, howMany) : recommendedItems);
        }
Ejemplo n.º 5
0
            public CachingRecommender.Recommendations get(long key)
            {
                CachingRecommender.log.debug("Retrieving new recommendations for user ID '{}'", new object[] { key });
                int                    howMany         = this.p.maxHowMany[0];
                IDRescorer             currentRescorer = this.p.currentRescorer;
                List <RecommendedItem> collection      = (currentRescorer == null) ? this.p.recommender.recommend(key, howMany) : this.p.recommender.recommend(key, howMany, currentRescorer);

                return(new CachingRecommender.Recommendations(new List <RecommendedItem>(collection)));
            }
Ejemplo n.º 6
0
        public override List <RecommendedItem> recommend(long userID, int howMany, IDRescorer rescorer)
        {
            log.debug("Recommending items for user ID '{}'", new object[] { userID });
            PreferenceArray        preferencesFromUser = this.getDataModel().getPreferencesFromUser(userID);
            List <RecommendedItem> list = TopItems.getTopItems(howMany, this.getAllOtherItems(userID, preferencesFromUser).GetEnumerator(), rescorer, new Estimator(this, userID));

            log.debug("Recommendations are: {}", new object[] { list });
            return(list);
        }
Ejemplo n.º 7
0
        public void testUserRescorer()
        {
            IDRescorer rescorer = NullRescorer.getUserInstance();

            Assert.NotNull(rescorer);
            Assert.AreEqual(1.0, rescorer.rescore(1L, 1.0), EPSILON);
            Assert.AreEqual(1.0, rescorer.rescore(0L, 1.0), EPSILON);
            Assert.AreEqual(0.0, rescorer.rescore(1L, 0.0), EPSILON);
            Assert.True(Double.IsNaN(rescorer.rescore(1L, Double.NaN)));
        }
Ejemplo n.º 8
0
            public Recommendations Get(long key)
            {
                log.Debug("Retrieving new recommendations for user ID '{}'", key);
                int        howMany         = p.maxHowMany[0];
                IDRescorer rescorer        = p.currentRescorer;
                var        recommendations =
                    rescorer == null?p.recommender.Recommend(key, howMany) : p.recommender.Recommend(key, howMany, rescorer);

                return(new Recommendations(new List <IRecommendedItem>(recommendations)));
            }
Ejemplo n.º 9
0
        public static List <IRecommendedItem> GetTopItems(int howMany,
                                                          IEnumerator <long> possibleItemIDs,
                                                          IDRescorer rescorer,
                                                          IEstimator <long> estimator)
        {
            //Preconditions.checkArgument(possibleItemIDs != null, "possibleItemIDs is null");
            //Preconditions.checkArgument(estimator != null, "estimator is null");

            var    topItems       = new SortedSet <IRecommendedItem>(ByValueRecommendedItemComparator.getReverseInstance());
            bool   full           = false;
            double lowestTopValue = Double.NegativeInfinity;

            while (possibleItemIDs.MoveNext())
            {
                long itemID = possibleItemIDs.Current;
                if (rescorer == null || !rescorer.isFiltered(itemID))
                {
                    double preference;
                    try {
                        preference = estimator.Estimate(itemID);
                    } catch (NoSuchItemException nsie) {
                        continue;
                    }
                    double rescoredPref = rescorer == null ? preference : rescorer.rescore(itemID, preference);
                    if (!Double.IsNaN(rescoredPref) && (!full || rescoredPref > lowestTopValue))
                    {
                        topItems.Add(new GenericRecommendedItem(itemID, (float)rescoredPref));
                        if (full)
                        {
                            topItems.Remove(topItems.Min);
                        }
                        else if (topItems.Count > howMany)
                        {
                            full = true;
                            topItems.Remove(topItems.Min); //     topItems.poll();
                        }
                        lowestTopValue = topItems.Min.GetValue();
                    }
                }
            }
            int size = topItems.Count;

            if (size == 0)
            {
                return(new List <IRecommendedItem>());
            }
            List <IRecommendedItem> result = new List <IRecommendedItem>(size);

            result.AddRange(topItems);
            result.Reverse();
            //Collections.sort(result, ByValueRecommendedItemComparator.getInstance());
            return(result);
        }
        public void testRecommender()
        {
            var mockRecommender = new MockRecommender(0);

            IRecommender cachingRecommender = new CachingRecommender(mockRecommender);

            cachingRecommender.Recommend(1, 1);
            Assert.AreEqual(1, mockRecommender.recommendCount);
            cachingRecommender.Recommend(2, 1);
            Assert.AreEqual(2, mockRecommender.recommendCount);
            cachingRecommender.Recommend(1, 1);
            Assert.AreEqual(2, mockRecommender.recommendCount);
            cachingRecommender.Recommend(2, 1);
            Assert.AreEqual(2, mockRecommender.recommendCount);
            cachingRecommender.Refresh(null);
            cachingRecommender.Recommend(1, 1);
            Assert.AreEqual(3, mockRecommender.recommendCount);
            cachingRecommender.Recommend(2, 1);
            Assert.AreEqual(4, mockRecommender.recommendCount);
            cachingRecommender.Recommend(3, 1);
            Assert.AreEqual(5, mockRecommender.recommendCount);

            // Results from this recommend() method can be cached...
            IDRescorer rescorer = NullRescorer.getItemInstance();

            cachingRecommender.Refresh(null);
            cachingRecommender.Recommend(1, 1, rescorer);
            Assert.AreEqual(6, mockRecommender.recommendCount);
            cachingRecommender.Recommend(2, 1, rescorer);
            Assert.AreEqual(7, mockRecommender.recommendCount);
            cachingRecommender.Recommend(1, 1, rescorer);
            Assert.AreEqual(7, mockRecommender.recommendCount);
            cachingRecommender.Recommend(2, 1, rescorer);
            Assert.AreEqual(7, mockRecommender.recommendCount);

            // until you switch Rescorers
            cachingRecommender.Recommend(1, 1, null);
            Assert.AreEqual(8, mockRecommender.recommendCount);
            cachingRecommender.Recommend(2, 1, null);
            Assert.AreEqual(9, mockRecommender.recommendCount);

            cachingRecommender.Refresh(null);
            cachingRecommender.EstimatePreference(1, 1);
            Assert.AreEqual(10, mockRecommender.recommendCount);
            cachingRecommender.EstimatePreference(1, 2);
            Assert.AreEqual(11, mockRecommender.recommendCount);
            cachingRecommender.EstimatePreference(1, 2);
            Assert.AreEqual(11, mockRecommender.recommendCount);
        }
Ejemplo n.º 11
0
        public override IList <IRecommendedItem> Recommend(long userID, int howMany, IDRescorer rescorer)
        {
            //Preconditions.checkArgument(howMany >= 1, "howMany must be at least 1");
            log.Debug("Recommending items for user ID '{}'", userID);

            IPreferenceArray preferencesFromUser = GetDataModel().GetPreferencesFromUser(userID);
            FastIDSet        possibleItemIDs     = GetAllOtherItems(userID, preferencesFromUser);

            List <IRecommendedItem> topItems = TopItems.GetTopItems(howMany, possibleItemIDs.GetEnumerator(), rescorer,
                                                                    new Estimator(this, userID));

            log.Debug("Recommendations are: {}", topItems);

            return(topItems);
        }
Ejemplo n.º 12
0
        public static long[] GetTopUsers(int howMany,
                                         IEnumerator <long> allUserIDs,
                                         IDRescorer rescorer,
                                         IEstimator <long> estimator)
        {
            var    topUsers       = new SortedSet <SimilarUser>();
            bool   full           = false;
            double lowestTopValue = Double.NegativeInfinity;

            while (allUserIDs.MoveNext())
            {
                long userID = allUserIDs.Current;
                if (rescorer != null && rescorer.isFiltered(userID))
                {
                    continue;
                }
                double similarity;
                try {
                    similarity = estimator.Estimate(userID);
                } catch (NoSuchUserException nsue) {
                    continue;
                }
                double rescoredSimilarity = rescorer == null ? similarity : rescorer.rescore(userID, similarity);
                if (!Double.IsNaN(rescoredSimilarity) && (!full || rescoredSimilarity > lowestTopValue))
                {
                    topUsers.Add(new SimilarUser(userID, rescoredSimilarity));
                    if (full)
                    {
                        topUsers.Remove(topUsers.Max); // topUsers.poll();
                    }
                    else if (topUsers.Count > howMany)
                    {
                        full = true;
                        topUsers.Remove(topUsers.Max); // topUsers.poll();
                    }
                    lowestTopValue = topUsers.Max.getSimilarity();
                }
            }
            int size = topUsers.Count;

            if (size == 0)
            {
                return(NO_IDS);
            }
            List <SimilarUser> sorted = new List <SimilarUser>(size);

            return(topUsers.Select(s => s.getUserID()).ToArray());
        }
Ejemplo n.º 13
0
 private void setCurrentRescorer(IDRescorer rescorer)
 {
     if (rescorer == null)
     {
         if (this.currentRescorer != null)
         {
             this.currentRescorer = null;
             this.clear();
         }
     }
     else if (!rescorer.Equals(this.currentRescorer))
     {
         this.currentRescorer = rescorer;
         this.clear();
     }
 }
Ejemplo n.º 14
0
        public override List <RecommendedItem> recommend(long userID, int howMany, IDRescorer rescorer)
        {
            log.debug("Recommending items for user ID '{}'", new object[] { userID });
            long[] theNeighborhood = this.neighborhood.getUserNeighborhood(userID);
            if (theNeighborhood.Length == 0)
            {
                return(new List <RecommendedItem>());
            }
            FastIDSet set = this.getAllOtherItems(theNeighborhood, userID);

            TopItems.Estimator <long> estimator = new Estimator(this, userID, theNeighborhood);
            List <RecommendedItem>    list      = TopItems.getTopItems(howMany, set.GetEnumerator(), rescorer, estimator);

            log.debug("Recommendations are: {}", new object[] { list });
            return(list);
        }
Ejemplo n.º 15
0
        public static long[] getTopUsers(int howMany, IEnumerator <long> allUserIDs, IDRescorer rescorer, Estimator <long> estimator)
        {
            SortedSet <SimilarUser> set = new SortedSet <SimilarUser>();
            bool   flag             = false;
            double negativeInfinity = double.NegativeInfinity;

            while (allUserIDs.MoveNext())
            {
                long current = allUserIDs.Current;
                if ((rescorer == null) || !rescorer.isFiltered(current))
                {
                    double num3;
                    try
                    {
                        num3 = estimator.estimate(current);
                    }
                    catch (NoSuchUserException)
                    {
                        continue;
                    }
                    double d = (rescorer == null) ? num3 : rescorer.rescore(current, num3);
                    if (!double.IsNaN(d) && (!flag || (d > negativeInfinity)))
                    {
                        set.Add(new SimilarUser(current, d));
                        if (flag)
                        {
                            set.Remove(set.Max);
                        }
                        else if (set.Count > howMany)
                        {
                            flag = true;
                            set.Remove(set.Max);
                        }
                        negativeInfinity = set.Max.getSimilarity();
                    }
                }
            }
            int count = set.Count;

            if (count == 0)
            {
                return(NO_IDS);
            }
            List <SimilarUser> list = new List <SimilarUser>(count);

            return((from s in set select s.getUserID()).ToArray <long>());
        }
Ejemplo n.º 16
0
        public override List <RecommendedItem> recommend(long userID, int howMany, IDRescorer rescorer)
        {
            log.debug("Recommending items for user ID '{}'", new object[] { userID });
            PreferenceArray preferencesFromUser = this.getDataModel().getPreferencesFromUser(userID);

            if (preferencesFromUser.length() == 0)
            {
                return(new List <RecommendedItem>());
            }
            FastIDSet set = this.getAllOtherItems(userID, preferencesFromUser);

            TopItems.Estimator <long> estimator = new Estimator(this, userID, preferencesFromUser);
            List <RecommendedItem>    list      = TopItems.getTopItems(howMany, set.GetEnumerator(), rescorer, estimator);

            log.debug("Recommendations are: {}", new object[] { list });
            return(list);
        }
Ejemplo n.º 17
0
 private void setCurrentRescorer(IDRescorer rescorer)
 {
     if (rescorer == null)
     {
         if (currentRescorer != null)
         {
             currentRescorer = null;
             clear();
         }
     }
     else
     {
         if (!rescorer.Equals(currentRescorer))
         {
             currentRescorer = rescorer;
             clear();
         }
     }
 }
Ejemplo n.º 18
0
  public override IList<IRecommendedItem> Recommend(long userID, int howMany, IDRescorer rescorer) {
    IDataModel dataModel = GetDataModel();
    int numItems = dataModel.GetNumItems();
	List<IRecommendedItem> result = new List<IRecommendedItem>(howMany);
    while (result.Count < howMany) {
      var it = dataModel.GetItemIDs();
	  it.MoveNext();

	  var skipNum = random.nextInt(numItems);
	  for (int i=0; i<skipNum; i++)
		if (!it.MoveNext()) { break; }  // skip() ??
      
	  long itemID = it.Current;
      if (dataModel.GetPreferenceValue(userID, itemID) == null) {
        result.Add(new GenericRecommendedItem(itemID, randomPref()));
      }
    }
    return result;
  }
Ejemplo n.º 19
0
        public override List <RecommendedItem> recommend(long userID, int howMany, IDRescorer rescorer)
        {
            // Preconditions.checkArgument(howMany >= 1, "howMany must be at least 1");
            if (howMany < 1)
            {
                throw new Exception("howMany must be at least 1");
            }
            ;
            buildClusters();

            log.debug("Recommending items for user ID '{}'", userID);

            List <RecommendedItem> recommended = topRecsByUserID.get(userID);

            if (recommended == null)
            {
                return(new List <RecommendedItem>());
            }

            DataModel dataModel             = getDataModel();
            List <RecommendedItem> rescored = new List <RecommendedItem>(); //Lists.newArrayListWithCapacity(recommended.size());

            // Only add items the user doesn't already have a preference for.
            // And that the rescorer doesn't "reject".
            foreach (RecommendedItem recommendedItem in recommended)
            {
                long itemID = recommendedItem.getItemID();
                if (rescorer != null && rescorer.isFiltered(itemID))
                {
                    continue;
                }
                if (dataModel.getPreferenceValue(userID, itemID) == null &&
                    (rescorer == null || !Double.IsNaN(rescorer.rescore(itemID, recommendedItem.getValue()))))
                {
                    rescored.Add(recommendedItem);
                }
            }

            rescored.Sort(new ByRescoreComparator(rescorer));

            return(rescored);
        }
Ejemplo n.º 20
0
        public override IList <IRecommendedItem> Recommend(long userID, int howMany, IDRescorer rescorer)
        {
            //Preconditions.checkArgument(howMany >= 1, "howMany must be at least 1");

            log.Debug("Recommending items for user ID '{}'", userID);

            long[] theNeighborhood = neighborhood.GetUserNeighborhood(userID);

            if (theNeighborhood.Length == 0)
            {
                return(new List <IRecommendedItem>());
            }

            FastIDSet allItemIDs = getAllOtherItems(theNeighborhood, userID);

            TopItems.IEstimator <long> estimator = new Estimator(this, userID, theNeighborhood);

            List <IRecommendedItem> topItems = TopItems
                                               .GetTopItems(howMany, allItemIDs.GetEnumerator(), rescorer, estimator);

            log.Debug("Recommendations are: {}", topItems);
            return(topItems);
        }
Ejemplo n.º 21
0
 public IList<IRecommendedItem> Recommend(long userID, int howMany, IDRescorer rescorer)
 {
     return Recommend(userID, howMany);
 }
 public abstract IList<IRecommendedItem> Recommend(long userID, int howMany, IDRescorer rescorer);
Ejemplo n.º 23
0
 public ByRescoreComparator(IDRescorer rescorer)
 {
     this.rescorer = rescorer;
 }
 public IList <IRecommendedItem> Recommend(long userID, int howMany, IDRescorer rescorer)
 {
     return(Recommend(userID, howMany));
 }
Ejemplo n.º 25
0
 public abstract List <RecommendedItem> recommend(long userID, int howMany, IDRescorer rescorer);
  public IRStatistics Evaluate(IRecommenderBuilder recommenderBuilder,
                               IDataModelBuilder dataModelBuilder,
                               IDataModel dataModel,
                               IDRescorer rescorer,
                               int at,
                               double relevanceThreshold,
                               double evaluationPercentage) {

    //Preconditions.checkArgument(recommenderBuilder != null, "recommenderBuilder is null");
    //Preconditions.checkArgument(dataModel != null, "dataModel is null");
    //Preconditions.checkArgument(at >= 1, "at must be at least 1");
    //Preconditions.checkArgument(evaluationPercentage > 0.0 && evaluationPercentage <= 1.0,
    //    "Invalid evaluationPercentage: " + evaluationPercentage + ". Must be: 0.0 < evaluationPercentage <= 1.0");

    int numItems = dataModel.GetNumItems();
    IRunningAverage precision = new FullRunningAverage();
    IRunningAverage recall = new FullRunningAverage();
    IRunningAverage fallOut = new FullRunningAverage();
    IRunningAverage nDCG = new FullRunningAverage();
    int numUsersRecommendedFor = 0;
    int numUsersWithRecommendations = 0;

    var it = dataModel.GetUserIDs();
    while (it.MoveNext()) {

      long userID = it.Current;

      if (random.nextDouble() >= evaluationPercentage) {
        // Skipped
        continue;
      }

	  var stopWatch = new System.Diagnostics.Stopwatch();
	  stopWatch.Start();

      IPreferenceArray prefs = dataModel.GetPreferencesFromUser(userID);

      // List some most-preferred items that would count as (most) "relevant" results
      double theRelevanceThreshold = Double.IsNaN(relevanceThreshold) ? computeThreshold(prefs) : relevanceThreshold;
      FastIDSet relevantItemIDs = dataSplitter.GetRelevantItemsIDs(userID, at, theRelevanceThreshold, dataModel);

      int numRelevantItems = relevantItemIDs.Count();
      if (numRelevantItems <= 0) {
        continue;
      }

      FastByIDMap<IPreferenceArray> trainingUsers = new FastByIDMap<IPreferenceArray>(dataModel.GetNumUsers());
      var it2 = dataModel.GetUserIDs();
      while (it2.MoveNext()) {
        dataSplitter.ProcessOtherUser(userID, relevantItemIDs, trainingUsers, it2.Current, dataModel);
      }

      IDataModel trainingModel = dataModelBuilder == null ? new GenericDataModel(trainingUsers)
          : dataModelBuilder.BuildDataModel(trainingUsers);
      try {
        trainingModel.GetPreferencesFromUser(userID);
      } catch (NoSuchUserException nsee) {
        continue; // Oops we excluded all prefs for the user -- just move on
      }

      int size = numRelevantItems + trainingModel.GetItemIDsFromUser(userID).Count();
      if (size < 2 * at) {
        // Really not enough prefs to meaningfully evaluate this user
        continue;
      }

      IRecommender recommender = recommenderBuilder.BuildRecommender(trainingModel);

      int intersectionSize = 0;
      var recommendedItems = recommender.Recommend(userID, at, rescorer);
      foreach (IRecommendedItem recommendedItem in recommendedItems) {
        if (relevantItemIDs.Contains(recommendedItem.GetItemID())) {
          intersectionSize++;
        }
      }

      int numRecommendedItems = recommendedItems.Count;

      // Precision
      if (numRecommendedItems > 0) {
        precision.AddDatum((double) intersectionSize / (double) numRecommendedItems);
      }

      // Recall
      recall.AddDatum((double) intersectionSize / (double) numRelevantItems);

      // Fall-out
      if (numRelevantItems < size) {
        fallOut.AddDatum((double) (numRecommendedItems - intersectionSize)
                         / (double) (numItems - numRelevantItems));
      }

      // nDCG
      // In computing, assume relevant IDs have relevance 1 and others 0
      double cumulativeGain = 0.0;
      double idealizedGain = 0.0;
      for (int i = 0; i < numRecommendedItems; i++) {
        IRecommendedItem item = recommendedItems[i];
        double discount = 1.0 / log2(i + 2.0); // Classical formulation says log(i+1), but i is 0-based here
        if (relevantItemIDs.Contains(item.GetItemID())) {
          cumulativeGain += discount;
        }
        // otherwise we're multiplying discount by relevance 0 so it doesn't do anything

        // Ideally results would be ordered with all relevant ones first, so this theoretical
        // ideal list starts with number of relevant items equal to the total number of relevant items
        if (i < numRelevantItems) {
          idealizedGain += discount;
        }
      }
      if (idealizedGain > 0.0) {
        nDCG.AddDatum(cumulativeGain / idealizedGain);
      }

      // Reach
      numUsersRecommendedFor++;
      if (numRecommendedItems > 0) {
        numUsersWithRecommendations++;
      }

	  stopWatch.Stop();

      log.Info("Evaluated with user {} in {}ms", userID, stopWatch.ElapsedMilliseconds);
      log.Info("Precision/recall/fall-out/nDCG/reach: {} / {} / {} / {} / {}",
               precision.GetAverage(), recall.GetAverage(), fallOut.GetAverage(), nDCG.GetAverage(),
               (double) numUsersWithRecommendations / (double) numUsersRecommendedFor);
    }

    return new IRStatisticsImpl(
        precision.GetAverage(),
        recall.GetAverage(),
        fallOut.GetAverage(),
        nDCG.GetAverage(),
        (double) numUsersWithRecommendations / (double) numUsersRecommendedFor);
  }
        public IRStatistics evaluate(RecommenderBuilder recommenderBuilder, DataModelBuilder dataModelBuilder, DataModel dataModel, IDRescorer rescorer, int at, double relevanceThreshold, double evaluationPercentage)
        {
            int                num        = dataModel.getNumItems();
            RunningAverage     average    = new FullRunningAverage();
            RunningAverage     average2   = new FullRunningAverage();
            RunningAverage     average3   = new FullRunningAverage();
            RunningAverage     average4   = new FullRunningAverage();
            int                num2       = 0;
            int                num3       = 0;
            IEnumerator <long> enumerator = dataModel.getUserIDs();

            while (enumerator.MoveNext())
            {
                long current = enumerator.Current;
                if (this.random.nextDouble() < evaluationPercentage)
                {
                    Stopwatch stopwatch = new Stopwatch();
                    stopwatch.Start();
                    PreferenceArray prefs           = dataModel.getPreferencesFromUser(current);
                    double          num5            = double.IsNaN(relevanceThreshold) ? computeThreshold(prefs) : relevanceThreshold;
                    FastIDSet       relevantItemIDs = this.dataSplitter.getRelevantItemsIDs(current, at, num5, dataModel);
                    int             num6            = relevantItemIDs.size();
                    if (num6 > 0)
                    {
                        FastByIDMap <PreferenceArray> trainingUsers = new FastByIDMap <PreferenceArray>(dataModel.getNumUsers());
                        IEnumerator <long>            enumerator2   = dataModel.getUserIDs();
                        while (enumerator2.MoveNext())
                        {
                            this.dataSplitter.processOtherUser(current, relevantItemIDs, trainingUsers, enumerator2.Current, dataModel);
                        }
                        DataModel model = (dataModelBuilder == null) ? new GenericDataModel(trainingUsers) : dataModelBuilder.buildDataModel(trainingUsers);
                        try
                        {
                            model.getPreferencesFromUser(current);
                        }
                        catch (NoSuchUserException)
                        {
                            continue;
                        }
                        int num7 = num6 + model.getItemIDsFromUser(current).size();
                        if (num7 >= (2 * at))
                        {
                            Recommender            recommender = recommenderBuilder.buildRecommender(model);
                            int                    num8        = 0;
                            List <RecommendedItem> list        = recommender.recommend(current, at, rescorer);
                            foreach (RecommendedItem item in list)
                            {
                                if (relevantItemIDs.contains(item.getItemID()))
                                {
                                    num8++;
                                }
                            }
                            int count = list.Count;
                            if (count > 0)
                            {
                                average.addDatum(((double)num8) / ((double)count));
                            }
                            average2.addDatum(((double)num8) / ((double)num6));
                            if (num6 < num7)
                            {
                                average3.addDatum(((double)(count - num8)) / ((double)(num - num6)));
                            }
                            double num10 = 0.0;
                            double num11 = 0.0;
                            for (int i = 0; i < count; i++)
                            {
                                RecommendedItem item2 = list[i];
                                double          num13 = 1.0 / log2(i + 2.0);
                                if (relevantItemIDs.contains(item2.getItemID()))
                                {
                                    num10 += num13;
                                }
                                if (i < num6)
                                {
                                    num11 += num13;
                                }
                            }
                            if (num11 > 0.0)
                            {
                                average4.addDatum(num10 / num11);
                            }
                            num2++;
                            if (count > 0)
                            {
                                num3++;
                            }
                            stopwatch.Stop();
                            log.info("Evaluated with user {} in {}ms", new object[] { current, stopwatch.ElapsedMilliseconds });
                            log.info("Precision/recall/fall-out/nDCG/reach: {} / {} / {} / {} / {}", new object[] { average.getAverage(), average2.getAverage(), average3.getAverage(), average4.getAverage(), ((double)num3) / ((double)num2) });
                        }
                    }
                }
            }
            return(new IRStatisticsImpl(average.getAverage(), average2.getAverage(), average3.getAverage(), average4.getAverage(), ((double)num3) / ((double)num2)));
        }
Ejemplo n.º 28
0
        public static List <RecommendedItem> getTopItems(int howMany, IEnumerator <long> possibleItemIDs, IDRescorer rescorer, Estimator <long> estimator)
        {
            SortedSet <RecommendedItem> collection = new SortedSet <RecommendedItem>(ByValueRecommendedItemComparator.getReverseInstance());
            bool   flag             = false;
            double negativeInfinity = double.NegativeInfinity;

            while (possibleItemIDs.MoveNext())
            {
                long current = possibleItemIDs.Current;
                if ((rescorer == null) || !rescorer.isFiltered(current))
                {
                    double num3;
                    try
                    {
                        num3 = estimator.estimate(current);
                    }
                    catch (NoSuchItemException)
                    {
                        continue;
                    }
                    double d = (rescorer == null) ? num3 : rescorer.rescore(current, num3);
                    if (!double.IsNaN(d) && (!flag || (d > negativeInfinity)))
                    {
                        collection.Add(new GenericRecommendedItem(current, (float)d));
                        if (flag)
                        {
                            collection.Remove(collection.Min);
                        }
                        else if (collection.Count > howMany)
                        {
                            flag = true;
                            collection.Remove(collection.Min);
                        }
                        negativeInfinity = collection.Min.getValue();
                    }
                }
            }
            int count = collection.Count;

            if (count == 0)
            {
                return(new List <RecommendedItem>());
            }
            List <RecommendedItem> list = new List <RecommendedItem>(count);

            list.AddRange(collection);
            list.Reverse();
            return(list);
        }
Ejemplo n.º 29
0
        public IRStatistics Evaluate(IRecommenderBuilder recommenderBuilder,
                                     IDataModelBuilder dataModelBuilder,
                                     IDataModel dataModel,
                                     IDRescorer rescorer,
                                     int at,
                                     double relevanceThreshold,
                                     double evaluationPercentage)
        {
            //Preconditions.checkArgument(recommenderBuilder != null, "recommenderBuilder is null");
            //Preconditions.checkArgument(dataModel != null, "dataModel is null");
            //Preconditions.checkArgument(at >= 1, "at must be at least 1");
            //Preconditions.checkArgument(evaluationPercentage > 0.0 && evaluationPercentage <= 1.0,
            //    "Invalid evaluationPercentage: " + evaluationPercentage + ". Must be: 0.0 < evaluationPercentage <= 1.0");

            int             numItems  = dataModel.GetNumItems();
            IRunningAverage precision = new FullRunningAverage();
            IRunningAverage recall    = new FullRunningAverage();
            IRunningAverage fallOut   = new FullRunningAverage();
            IRunningAverage nDCG      = new FullRunningAverage();
            int             numUsersRecommendedFor      = 0;
            int             numUsersWithRecommendations = 0;

            var it = dataModel.GetUserIDs();

            while (it.MoveNext())
            {
                long userID = it.Current;

                if (random.nextDouble() >= evaluationPercentage)
                {
                    // Skipped
                    continue;
                }

                var stopWatch = new System.Diagnostics.Stopwatch();
                stopWatch.Start();

                IPreferenceArray prefs = dataModel.GetPreferencesFromUser(userID);

                // List some most-preferred items that would count as (most) "relevant" results
                double    theRelevanceThreshold = Double.IsNaN(relevanceThreshold) ? computeThreshold(prefs) : relevanceThreshold;
                FastIDSet relevantItemIDs       = dataSplitter.GetRelevantItemsIDs(userID, at, theRelevanceThreshold, dataModel);

                int numRelevantItems = relevantItemIDs.Count();
                if (numRelevantItems <= 0)
                {
                    continue;
                }

                FastByIDMap <IPreferenceArray> trainingUsers = new FastByIDMap <IPreferenceArray>(dataModel.GetNumUsers());
                var it2 = dataModel.GetUserIDs();
                while (it2.MoveNext())
                {
                    dataSplitter.ProcessOtherUser(userID, relevantItemIDs, trainingUsers, it2.Current, dataModel);
                }

                IDataModel trainingModel = dataModelBuilder == null ? new GenericDataModel(trainingUsers)
          : dataModelBuilder.BuildDataModel(trainingUsers);
                try {
                    trainingModel.GetPreferencesFromUser(userID);
                } catch (NoSuchUserException nsee) {
                    continue; // Oops we excluded all prefs for the user -- just move on
                }

                int size = numRelevantItems + trainingModel.GetItemIDsFromUser(userID).Count();
                if (size < 2 * at)
                {
                    // Really not enough prefs to meaningfully evaluate this user
                    continue;
                }

                IRecommender recommender = recommenderBuilder.BuildRecommender(trainingModel);

                int intersectionSize = 0;
                var recommendedItems = recommender.Recommend(userID, at, rescorer);
                foreach (IRecommendedItem recommendedItem in recommendedItems)
                {
                    if (relevantItemIDs.Contains(recommendedItem.GetItemID()))
                    {
                        intersectionSize++;
                    }
                }

                int numRecommendedItems = recommendedItems.Count;

                // Precision
                if (numRecommendedItems > 0)
                {
                    precision.AddDatum((double)intersectionSize / (double)numRecommendedItems);
                }

                // Recall
                recall.AddDatum((double)intersectionSize / (double)numRelevantItems);

                // Fall-out
                if (numRelevantItems < size)
                {
                    fallOut.AddDatum((double)(numRecommendedItems - intersectionSize)
                                     / (double)(numItems - numRelevantItems));
                }

                // nDCG
                // In computing, assume relevant IDs have relevance 1 and others 0
                double cumulativeGain = 0.0;
                double idealizedGain  = 0.0;
                for (int i = 0; i < numRecommendedItems; i++)
                {
                    IRecommendedItem item     = recommendedItems[i];
                    double           discount = 1.0 / log2(i + 2.0); // Classical formulation says log(i+1), but i is 0-based here
                    if (relevantItemIDs.Contains(item.GetItemID()))
                    {
                        cumulativeGain += discount;
                    }
                    // otherwise we're multiplying discount by relevance 0 so it doesn't do anything

                    // Ideally results would be ordered with all relevant ones first, so this theoretical
                    // ideal list starts with number of relevant items equal to the total number of relevant items
                    if (i < numRelevantItems)
                    {
                        idealizedGain += discount;
                    }
                }
                if (idealizedGain > 0.0)
                {
                    nDCG.AddDatum(cumulativeGain / idealizedGain);
                }

                // Reach
                numUsersRecommendedFor++;
                if (numRecommendedItems > 0)
                {
                    numUsersWithRecommendations++;
                }

                stopWatch.Stop();

                log.Info("Evaluated with user {} in {}ms", userID, stopWatch.ElapsedMilliseconds);
                log.Info("Precision/recall/fall-out/nDCG/reach: {} / {} / {} / {} / {}",
                         precision.GetAverage(), recall.GetAverage(), fallOut.GetAverage(), nDCG.GetAverage(),
                         (double)numUsersWithRecommendations / (double)numUsersRecommendedFor);
            }

            return(new IRStatisticsImpl(
                       precision.GetAverage(),
                       recall.GetAverage(),
                       fallOut.GetAverage(),
                       nDCG.GetAverage(),
                       (double)numUsersWithRecommendations / (double)numUsersRecommendedFor));
        }