示例#1
0
        public virtual PreferenceArray getPreferencesForItem(long itemID)
        {
            if (this.tempPrefs == null)
            {
                return(this._delegate.getPreferencesForItem(itemID));
            }
            PreferenceArray delegatePrefs = null;

            try
            {
                delegatePrefs = this._delegate.getPreferencesForItem(itemID);
            }
            catch (NoSuchItemException)
            {
                log.debug("Item {} unknown", new object[] { itemID });
            }
            for (int i = 0; i < this.tempPrefs.length(); i++)
            {
                if (this.tempPrefs.getItemID(i) == itemID)
                {
                    return(cloneAndMergeInto(delegatePrefs, itemID, this.tempPrefs.getUserID(i), this.tempPrefs.getValue(i)));
                }
            }
            if (delegatePrefs == null)
            {
                throw new NoSuchItemException(itemID);
            }
            return(delegatePrefs);
        }
        public static void evaluate(Recommender recommender, DataModel model, int samples, RunningAverage tracker, string tag)
        {
            printHeader();
            IEnumerator <long> enumerator = recommender.getDataModel().getUserIDs();

            while (enumerator.MoveNext())
            {
                long current = enumerator.Current;
                List <RecommendedItem> items = recommender.recommend(current, model.getNumItems());
                PreferenceArray        prefs = model.getPreferencesFromUser(current);
                prefs.sortByValueReversed();
                FastIDSet modelSet = new FastIDSet();
                long      num2     = setBits(modelSet, items, samples);
                FastIDSet set2     = new FastIDSet();
                num2 = Math.Max(num2, setBits(set2, prefs, samples));
                int max = Math.Min(mask(modelSet, set2, num2), samples);
                if (max >= 2)
                {
                    long[] itemsL = getCommonItems(modelSet, items, max);
                    long[] itemsR = getCommonItems(modelSet, prefs, max);
                    double datum  = scoreCommonSubset(tag, current, samples, max, itemsL, itemsR);
                    tracker.addDatum(datum);
                }
            }
        }
示例#3
0
        protected virtual float doEstimatePreference(long userID, PreferenceArray preferencesFromUser, long itemID)
        {
            double num  = 0.0;
            double num2 = 0.0;
            int    num3 = 0;

            double[] numArray = this.similarity.itemSimilarities(itemID, preferencesFromUser.getIDs());
            for (int i = 0; i < numArray.Length; i++)
            {
                double d = numArray[i];
                if (!double.IsNaN(d))
                {
                    num  += d * preferencesFromUser.getValue(i);
                    num2 += d;
                    num3++;
                }
            }
            if (num3 <= 1)
            {
                return(float.NaN);
            }
            float estimate = (float)(num / num2);

            if (this.capper != null)
            {
                estimate = this.capper.capEstimate(estimate);
            }
            return(estimate);
        }
示例#4
0
        public GenericDataModel(FastByIDMap <PreferenceArray> userData, FastByIDMap <FastByIDMap <DateTime?> > timestamps)
        {
            this.preferenceFromUsers = userData;
            FastByIDMap <List <Preference> > data = new FastByIDMap <List <Preference> >();
            FastIDSet set = new FastIDSet();
            int       num = 0;
            float     negativeInfinity = float.NegativeInfinity;
            float     positiveInfinity = float.PositiveInfinity;

            foreach (KeyValuePair <long, PreferenceArray> pair in this.preferenceFromUsers.entrySet())
            {
                PreferenceArray array = pair.Value;
                array.sortByItem();
                foreach (Preference preference in array)
                {
                    long key = preference.getItemID();
                    set.add(key);
                    List <Preference> list = data.get(key);
                    if (list == null)
                    {
                        list = new List <Preference>(2);
                        data.put(key, list);
                    }
                    list.Add(preference);
                    float num5 = preference.getValue();
                    if (num5 > negativeInfinity)
                    {
                        negativeInfinity = num5;
                    }
                    if (num5 < positiveInfinity)
                    {
                        positiveInfinity = num5;
                    }
                }
                if ((++num % 0x2710) == 0)
                {
                    log.info("Processed {0} users", new object[] { num });
                }
            }
            log.info("Processed {0} users", new object[] { num });
            this.setMinPreference(positiveInfinity);
            this.setMaxPreference(negativeInfinity);
            this.itemIDs = set.toArray();
            set          = null;
            Array.Sort <long>(this.itemIDs);
            this.preferenceForItems = toDataMap(data, false);
            foreach (KeyValuePair <long, PreferenceArray> pair in this.preferenceForItems.entrySet())
            {
                pair.Value.sortByUser();
            }
            this.userIDs = new long[userData.size()];
            int num6 = 0;

            foreach (long num7 in userData.Keys)
            {
                this.userIDs[num6++] = num7;
            }
            Array.Sort <long>(this.userIDs);
            this.timestamps = timestamps;
        }
示例#5
0
        public void removeItemPref(long userID, long itemIDA, float prefValue)
        {
            PreferenceArray userPreferences = dataModel.getPreferencesFromUser(userID);

            try
            {
                buildAverageDiffsLock.EnterWriteLock();

                FastByIDMap <RunningAverage> aMap = averageDiffs.get(itemIDA);

                int length = userPreferences.length();
                for (int i = 0; i < length; i++)
                {
                    long  itemIDB = userPreferences.getItemID(i);
                    float bValue  = userPreferences.getValue(i);

                    if (itemIDA < itemIDB)
                    {
                        if (aMap != null)
                        {
                            RunningAverage average = aMap.get(itemIDB);
                            if (average != null)
                            {
                                if (average.getCount() <= 1)
                                {
                                    aMap.remove(itemIDB);
                                }
                                else
                                {
                                    average.removeDatum(bValue - prefValue);
                                }
                            }
                        }
                    }
                    else if (itemIDA > itemIDB)
                    {
                        FastByIDMap <RunningAverage> bMap = averageDiffs.get(itemIDB);
                        if (bMap != null)
                        {
                            RunningAverage average = bMap.get(itemIDA);
                            if (average != null)
                            {
                                if (average.getCount() <= 1)
                                {
                                    aMap.remove(itemIDA);
                                }
                                else
                                {
                                    average.removeDatum(prefValue - bValue);
                                }
                            }
                        }
                    }
                }
            }
            finally
            {
                buildAverageDiffsLock.ExitWriteLock();
            }
        }
示例#6
0
        public RandomRecommender(DataModel dataModel)
            : base(dataModel)
        {
            this.random = RandomUtils.getRandom();
            float negativeInfinity        = float.NegativeInfinity;
            float positiveInfinity        = float.PositiveInfinity;
            IEnumerator <long> enumerator = dataModel.getUserIDs();

            while (enumerator.MoveNext())
            {
                long            current = enumerator.Current;
                PreferenceArray array   = dataModel.getPreferencesFromUser(current);
                for (int i = 0; i < array.length(); i++)
                {
                    float num5 = array.getValue(i);
                    if (num5 < positiveInfinity)
                    {
                        positiveInfinity = num5;
                    }
                    if (num5 > negativeInfinity)
                    {
                        negativeInfinity = num5;
                    }
                }
            }
            this.minPref = positiveInfinity;
            this.maxPref = negativeInfinity;
        }
示例#7
0
        private static PreferenceArray cloneAndMergeInto(PreferenceArray delegatePrefs, long itemID, long newUserID, float value)
        {
            int             num4;
            int             num   = (delegatePrefs == null) ? 0 : delegatePrefs.length();
            int             size  = num + 1;
            PreferenceArray array = new GenericItemPreferenceArray(size);

            array.setItemID(0, itemID);
            int i = 0;

            while ((i < num) && (newUserID > delegatePrefs.getUserID(i)))
            {
                i++;
            }
            for (num4 = 0; num4 < i; num4++)
            {
                array.setUserID(num4, delegatePrefs.getUserID(num4));
                array.setValue(num4, delegatePrefs.getValue(num4));
            }
            array.setUserID(i, newUserID);
            array.setValue(i, value);
            for (num4 = i + 1; num4 < size; num4++)
            {
                array.setUserID(num4, delegatePrefs.getUserID(num4 - 1));
                array.setValue(num4, delegatePrefs.getValue(num4 - 1));
            }
            return(array);
        }
示例#8
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);
        }
示例#9
0
 public static double[] ratingVector(PreferenceArray prefs)
 {
     double[] numArray = new double[prefs.length()];
     for (int i = 0; i < prefs.length(); i++)
     {
         numArray[i] = prefs.get(i).getValue();
     }
     return(numArray);
 }
示例#10
0
 public void setTempPrefs(PreferenceArray prefs)
 {
     this.tempPrefs = prefs;
     this.prefItemIDs.clear();
     for (int i = 0; i < prefs.length(); i++)
     {
         this.prefItemIDs.add(prefs.getItemID(i));
     }
 }
示例#11
0
        private float doEstimatePreference(long userID, long itemID)
        {
            double          count           = 0.0;
            double          totalPreference = 0.0;
            PreferenceArray prefs           = getDataModel().getPreferencesFromUser(userID);

            RunningAverage[] averages = diffStorage.getDiffs(userID, itemID, prefs);
            int size = prefs.length();

            for (int i = 0; i < size; i++)
            {
                RunningAverage averageDiff = averages[i];
                if (averageDiff != null)
                {
                    double averageDiffValue = averageDiff.getAverage();
                    if (weighted)
                    {
                        double weight = averageDiff.getCount();
                        if (stdDevWeighted)
                        {
                            var raaStdDev = averageDiff as RunningAverageAndStdDev;
                            if (raaStdDev != null)
                            {
                                double stdev = raaStdDev.getStandardDeviation();
                                if (!Double.IsNaN(stdev))
                                {
                                    weight /= 1.0 + stdev;
                                }
                            }

                            // If stdev is NaN, then it is because count is 1. Because we're weighting by count,
                            // the weight is already relatively low. We effectively assume stdev is 0.0 here and
                            // that is reasonable enough. Otherwise, dividing by NaN would yield a weight of NaN
                            // and disqualify this pref entirely
                            // (Thanks Daemmon)
                        }
                        totalPreference += weight * (prefs.getValue(i) + averageDiffValue);
                        count           += weight;
                    }
                    else
                    {
                        totalPreference += prefs.getValue(i) + averageDiffValue;
                        count           += 1.0;
                    }
                }
            }
            if (count <= 0.0)
            {
                RunningAverage itemAverage = diffStorage.getAverageItemPref(itemID);
                return(itemAverage == null ? float.NaN : (float)itemAverage.getAverage());
            }
            else
            {
                return((float)(totalPreference / count));
            }
        }
示例#12
0
        public override PreferenceArray getPreferencesFromUser(long userID)
        {
            PreferenceArray array = this.preferenceFromUsers.get(userID);

            if (array == null)
            {
                throw new NoSuchUserException(userID);
            }
            return(array);
        }
示例#13
0
        protected IList <Tuple <int, double> > sparseUserRatingVector(PreferenceArray prefs)
        {
            List <Tuple <int, double> > list = new List <Tuple <int, double> >(prefs.length());

            foreach (Preference preference in prefs)
            {
                list.Add(new Tuple <int, double>((int)preference.getItemID(), (double)preference.getValue()));
            }
            return(list);
        }
示例#14
0
        public override PreferenceArray getPreferencesForItem(long itemID)
        {
            PreferenceArray array = this.preferenceForItems.get(itemID);

            if (array == null)
            {
                throw new NoSuchItemException(itemID);
            }
            return(array);
        }
示例#15
0
            public double averateRating(long itemID)
            {
                PreferenceArray array   = this.dataModel.getPreferencesForItem(itemID);
                RunningAverage  average = new FullRunningAverage();

                foreach (Preference preference in array)
                {
                    average.addDatum((double)preference.getValue());
                }
                return(average.getAverage());
            }
示例#16
0
        public override float estimatePreference(long userID, long itemID)
        {
            PreferenceArray preferencesFromUser = this.getDataModel().getPreferencesFromUser(userID);
            float?          nullable            = getPreferenceForItem(preferencesFromUser, itemID);

            if (nullable.HasValue)
            {
                return(nullable.Value);
            }
            return(this.doEstimatePreference(userID, preferencesFromUser, itemID));
        }
        private double getEvaluation(FastByIDMap <PreferenceArray> testPrefs, Recommender recommender)
        {
            this.reset();
            List <Action> callables         = new List <Action>();
            AtomicInteger noEstimateCounter = new AtomicInteger();

            using (IEnumerator <KeyValuePair <long, PreferenceArray> > enumerator = testPrefs.entrySet().GetEnumerator())
            {
                while (enumerator.MoveNext())
                {
                    Action item = null;
                    KeyValuePair <long, PreferenceArray> entry = enumerator.Current;
                    if (item == null)
                    {
                        item = delegate
                        {
                            long            userID = entry.Key;
                            PreferenceArray array  = entry.Value;
                            foreach (Preference preference in array)
                            {
                                float f = float.NaN;
                                try
                                {
                                    f = recommender.estimatePreference(userID, preference.getItemID());
                                }
                                catch (NoSuchUserException)
                                {
                                    log.info("User exists in test data but not training data: {}", new object[] { userID });
                                }
                                catch (NoSuchItemException)
                                {
                                    log.info("Item exists in test data but not training data: {}", new object[] { preference.getItemID() });
                                }
                                if (float.IsNaN(f))
                                {
                                    noEstimateCounter.incrementAndGet();
                                }
                                else
                                {
                                    f = this.capEstimatedPreference(f);
                                    this.processOneEstimate(f, preference);
                                }
                            }
                        };
                    }
                    callables.Add(item);
                }
            }
            log.info("Beginning evaluation of {} users", new object[] { callables.Count });
            RunningAverageAndStdDev timing = new FullRunningAverageAndStdDev();

            execute(callables, noEstimateCounter, timing);
            return(this.computeFinalEvaluation());
        }
        public void setTempPrefs(PreferenceArray prefs, long anonymousUserID)
        {
            this.tempPrefs[anonymousUserID] = prefs;
            FastIDSet set = new FastIDSet();

            for (int i = 0; i < prefs.length(); i++)
            {
                set.add(prefs.getItemID(i));
            }
            this.prefItemIDs[anonymousUserID] = set;
        }
示例#19
0
        public override FastIDSet getItemIDsFromUser(long userID)
        {
            PreferenceArray array = this.getPreferencesFromUser(userID);
            int             size  = array.length();
            FastIDSet       set   = new FastIDSet(size);

            for (int i = 0; i < size; i++)
            {
                set.add(array.getItemID(i));
            }
            return(set);
        }
示例#20
0
        private int countPreferences()
        {
            int num = 0;
            IEnumerator <long> enumerator = this.dataModel.getUserIDs();

            while (enumerator.MoveNext())
            {
                PreferenceArray array = this.dataModel.getPreferencesFromUser(enumerator.Current);
                num += array.length();
            }
            return(num);
        }
示例#21
0
        public void addItemPref(long userID, long itemIDA, float prefValue)
        {
            PreferenceArray userPreferences = dataModel.getPreferencesFromUser(userID);

            try
            {
                buildAverageDiffsLock.EnterWriteLock();

                FastByIDMap <RunningAverage> aMap = averageDiffs.get(itemIDA);
                if (aMap == null)
                {
                    aMap = new FastByIDMap <RunningAverage>();
                    averageDiffs.put(itemIDA, aMap);
                }
                int length = userPreferences.length();
                for (int i = 0; i < length; i++)
                {
                    long  itemIDB = userPreferences.getItemID(i);
                    float bValue  = userPreferences.getValue(i);
                    if (itemIDA < itemIDB)
                    {
                        RunningAverage average = aMap.get(itemIDB);
                        if (average == null)
                        {
                            average = buildRunningAverage();
                            aMap.put(itemIDB, average);
                        }
                        average.addDatum(bValue - prefValue);
                    }
                    else
                    {
                        FastByIDMap <RunningAverage> bMap = averageDiffs.get(itemIDB);
                        if (bMap == null)
                        {
                            bMap = new FastByIDMap <RunningAverage>();
                            averageDiffs.put(itemIDB, bMap);
                        }
                        RunningAverage average = bMap.get(itemIDA);
                        if (average == null)
                        {
                            average = buildRunningAverage();
                            bMap.put(itemIDA, average);
                        }
                        average.addDatum(prefValue - bValue);
                    }
                }
            }
            finally
            {
                buildAverageDiffsLock.ExitWriteLock();
            }
        }
示例#22
0
        public override int getNumUsersWithPreferenceFor(long itemID1, long itemID2)
        {
            PreferenceArray array = this.preferenceForItems.get(itemID1);

            if (array == null)
            {
                return(0);
            }
            PreferenceArray array2 = this.preferenceForItems.get(itemID2);

            if (array2 == null)
            {
                return(0);
            }
            int  num  = array.length();
            int  num2 = array2.length();
            int  num3 = 0;
            int  i    = 0;
            int  num5 = 0;
            long num6 = array.getUserID(0);
            long num7 = array2.getUserID(0);

            while (true)
            {
                if (num6 < num7)
                {
                    if (++i == num)
                    {
                        return(num3);
                    }
                    num6 = array.getUserID(i);
                }
                else if (num6 > num7)
                {
                    if (++num5 == num2)
                    {
                        return(num3);
                    }
                    num7 = array2.getUserID(num5);
                }
                else
                {
                    num3++;
                    if ((++i == num) || (++num5 == num2))
                    {
                        return(num3);
                    }
                    num6 = array.getUserID(i);
                    num7 = array2.getUserID(num5);
                }
            }
        }
示例#23
0
        private static float?getPreferenceForItem(PreferenceArray preferencesFromUser, long itemID)
        {
            int num = preferencesFromUser.length();

            for (int i = 0; i < num; i++)
            {
                if (preferencesFromUser.getItemID(i) == itemID)
                {
                    return(new float?(preferencesFromUser.getValue(i)));
                }
            }
            return(null);
        }
        public override PreferenceArray getPreferencesForItem(long itemID)
        {
            int num;

            if (this.tempPrefs.Count == 0)
            {
                return(base.getDelegate().getPreferencesForItem(itemID));
            }
            PreferenceArray array = null;

            try
            {
                array = base.getDelegate().getPreferencesForItem(itemID);
            }
            catch (NoSuchItemException)
            {
            }
            List <Preference> list = new List <Preference>();

            foreach (KeyValuePair <long, PreferenceArray> pair in this.tempPrefs)
            {
                PreferenceArray array2 = pair.Value;
                num = 0;
                while (num < array2.length())
                {
                    if (array2.getItemID(num) == itemID)
                    {
                        list.Add(array2.get(num));
                    }
                    num++;
                }
            }
            int             num2   = (array == null) ? 0 : array.length();
            int             count  = list.Count;
            int             num4   = 0;
            PreferenceArray array3 = new GenericItemPreferenceArray(num2 + count);

            for (num = 0; num < num2; num++)
            {
                array3.set(num4++, array.get(num));
            }
            foreach (Preference preference in list)
            {
                array3.set(num4++, preference);
            }
            if (array3.length() == 0)
            {
                throw new NoSuchItemException(itemID);
            }
            return(array3);
        }
示例#25
0
        public override float?getPreferenceValue(long userID, long itemID)
        {
            PreferenceArray array = this.getPreferencesFromUser(userID);
            int             num   = array.length();

            for (int i = 0; i < num; i++)
            {
                if (array.getItemID(i) == itemID)
                {
                    return(new float?(array.getValue(i)));
                }
            }
            return(null);
        }
        public FastIDSet getRelevantItemsIDs(long userID, int at, double relevanceThreshold, DataModel dataModel)
        {
            PreferenceArray array = dataModel.getPreferencesFromUser(userID);
            FastIDSet       set   = new FastIDSet(at);

            array.sortByValueReversed();
            for (int i = 0; (i < array.length()) && (set.size() < at); i++)
            {
                if (array.getValue(i) >= relevanceThreshold)
                {
                    set.add(array.getItemID(i));
                }
            }
            return(set);
        }
        private static long setBits(FastIDSet modelSet, PreferenceArray prefs, int max)
        {
            long num = -1L;

            for (int i = 0; (i < prefs.length()) && (i < max); i++)
            {
                long key = prefs.getItemID(i);
                modelSet.add(key);
                if (key > num)
                {
                    num = key;
                }
            }
            return(num);
        }
        private static double computeThreshold(PreferenceArray prefs)
        {
            if (prefs.length() < 2)
            {
                return(double.NegativeInfinity);
            }
            RunningAverageAndStdDev dev = new FullRunningAverageAndStdDev();
            int num = prefs.length();

            for (int i = 0; i < num; i++)
            {
                dev.addDatum((double)prefs.getValue(i));
            }
            return(dev.getAverage() + dev.getStandardDeviation());
        }
 public override float?getPreferenceValue(long userID, long itemID)
 {
     if (this.isAnonymousUser(userID))
     {
         PreferenceArray array = this.tempPrefs[userID];
         for (int i = 0; i < array.length(); i++)
         {
             if (array.getItemID(i) == itemID)
             {
                 return(new float?(array.getValue(i)));
             }
         }
         return(null);
     }
     return(base.getDelegate().getPreferenceValue(userID, itemID));
 }
示例#30
0
        public List <RecommendedItem> recommendedBecause(long userID, long itemID, int howMany)
        {
            DataModel model = this.getDataModel();

            TopItems.Estimator <long> estimator = new RecommendedBecauseEstimator(this, userID, itemID);
            PreferenceArray           array     = model.getPreferencesFromUser(userID);
            int       size = array.length();
            FastIDSet set  = new FastIDSet(size);

            for (int i = 0; i < size; i++)
            {
                set.add(array.getItemID(i));
            }
            set.remove(itemID);
            return(TopItems.getTopItems(howMany, set.GetEnumerator(), null, estimator));
        }