public static void Evaluate(IRecommender recommender, IDataModel model, int samples, IRunningAverage tracker, String tag) { printHeader(); var users = recommender.GetDataModel().GetUserIDs(); while (users.MoveNext()) { long userID = users.Current; var recs1 = recommender.Recommend(userID, model.GetNumItems()); IPreferenceArray prefs2 = model.GetPreferencesFromUser(userID); prefs2.SortByValueReversed(); FastIDSet commonSet = new FastIDSet(); long maxItemID = setBits(commonSet, recs1, samples); FastIDSet otherSet = new FastIDSet(); maxItemID = Math.Max(maxItemID, setBits(otherSet, prefs2, samples)); int max = mask(commonSet, otherSet, maxItemID); max = Math.Min(max, samples); if (max < 2) { continue; } long[] items1 = getCommonItems(commonSet, recs1, max); long[] items2 = getCommonItems(commonSet, prefs2, max); double variance = scoreCommonSubset(tag, userID, samples, max, items1, items2); tracker.AddDatum(variance); } }
public void ProcessOtherUser(long userID, FastIDSet relevantItemIDs, FastByIDMap <IPreferenceArray> trainingUsers, long otherUserID, IDataModel dataModel) { IPreferenceArray prefs2Array = dataModel.GetPreferencesFromUser(otherUserID); // If we're dealing with the very user that we're evaluating for precision/recall, if (userID == otherUserID) { // then must remove all the test IDs, the "relevant" item IDs List <IPreference> prefs2 = new List <IPreference>(prefs2Array.Length()); foreach (IPreference pref in prefs2Array) { if (!relevantItemIDs.Contains(pref.GetItemID())) { prefs2.Add(pref); } } if (prefs2.Count > 0) { trainingUsers.Put(otherUserID, new GenericUserPreferenceArray(prefs2)); } } else { // otherwise just add all those other user's prefs trainingUsers.Put(otherUserID, prefs2Array); } }
public RandomRecommender(IDataModel dataModel) : base(dataModel) { float maxPref = float.NegativeInfinity; float minPref = float.PositiveInfinity; var userIterator = dataModel.GetUserIDs(); while (userIterator.MoveNext()) { long userID = userIterator.Current; IPreferenceArray prefs = dataModel.GetPreferencesFromUser(userID); for (int i = 0; i < prefs.Length(); i++) { float prefValue = prefs.GetValue(i); if (prefValue < minPref) { minPref = prefValue; } if (prefValue > maxPref) { maxPref = prefValue; } } } this.minPref = minPref; this.maxPref = maxPref; }
private static IPreferenceArray cloneAndMergeInto(IPreferenceArray delegatePrefs, long itemID, long newUserID, float value) { int length = delegatePrefs == null ? 0 : delegatePrefs.Length(); int newLength = length + 1; IPreferenceArray newPreferenceArray = new GenericItemPreferenceArray(newLength); // Set item ID once newPreferenceArray.SetItemID(0, itemID); int positionToInsert = 0; while (positionToInsert < length && newUserID > delegatePrefs.GetUserID(positionToInsert)) { positionToInsert++; } for (int i = 0; i < positionToInsert; i++) { newPreferenceArray.SetUserID(i, delegatePrefs.GetUserID(i)); newPreferenceArray.SetValue(i, delegatePrefs.GetValue(i)); } newPreferenceArray.SetUserID(positionToInsert, newUserID); newPreferenceArray.SetValue(positionToInsert, value); for (int i = positionToInsert + 1; i < newLength; i++) { newPreferenceArray.SetUserID(i, delegatePrefs.GetUserID(i - 1)); newPreferenceArray.SetValue(i, delegatePrefs.GetValue(i - 1)); } return(newPreferenceArray); }
private void buildAverageDiffs() { lock (this) { //buildAveragesLock.writeLock().lock(); IDataModel dataModel = GetDataModel(); var it = dataModel.GetUserIDs(); while (it.MoveNext()) { IPreferenceArray prefs = dataModel.GetPreferencesFromUser(it.Current); int size = prefs.Length(); for (int i = 0; i < size; i++) { long itemID = prefs.GetItemID(i); IRunningAverage average = itemAverages.Get(itemID); if (average == null) { average = new FullRunningAverage(); itemAverages.Put(itemID, average); } average.AddDatum(prefs.GetValue(i)); } } } //finally { //buildAveragesLock.writeLock().unlock(); //} }
public virtual IPreferenceArray GetPreferencesForItem(long itemID) { if (tempPrefs == null) { return(_delegate.GetPreferencesForItem(itemID)); } IPreferenceArray delegatePrefs = null; try { delegatePrefs = _delegate.GetPreferencesForItem(itemID); } catch (NoSuchItemException nsie) { // OK. Probably an item that only the anonymous user has //if (log.isDebugEnabled()) { log.Debug("Item {} unknown", itemID); //} } for (int i = 0; i < tempPrefs.Length(); i++) { if (tempPrefs.GetItemID(i) == itemID) { return(cloneAndMergeInto(delegatePrefs, itemID, tempPrefs.GetUserID(i), tempPrefs.GetValue(i))); } } if (delegatePrefs == null) { // No, didn't find it among the anonymous user prefs throw new NoSuchItemException(itemID); } return(delegatePrefs); }
protected virtual float doEstimatePreference(long userID, IPreferenceArray preferencesFromUser, long itemID) { double preference = 0.0; double totalSimilarity = 0.0; int count = 0; double[] similarities = similarity.ItemSimilarities(itemID, preferencesFromUser.GetIDs()); for (int i = 0; i < similarities.Length; i++) { double theSimilarity = similarities[i]; if (!Double.IsNaN(theSimilarity)) { // Weights can be negative! preference += theSimilarity * preferencesFromUser.GetValue(i); totalSimilarity += theSimilarity; count++; } } // Throw out the estimate if it was based on no data points, of course, but also if based on // just one. This is a bit of a band-aid on the 'stock' item-based algorithm for the moment. // The reason is that in this case the estimate is, simply, the user's rating for one item // that happened to have a defined similarity. The similarity score doesn't matter, and that // seems like a bad situation. if (count <= 1) { return(float.NaN); } float estimate = (float)(preference / totalSimilarity); if (capper != null) { estimate = capper.capEstimate(estimate); } return(estimate); }
public static double[] ratingVector(IPreferenceArray prefs) { double[] ratings = new double[prefs.Length()]; for (int n = 0; n < prefs.Length(); n++) { ratings[n] = prefs.Get(n).GetValue(); } return(ratings); //, true); new DenseVector( }
public override IPreferenceArray GetPreferencesForItem(long itemID) { if (tempPrefs.Count == 0) { return(getDelegate().GetPreferencesForItem(itemID)); } IPreferenceArray delegatePrefs = null; try { delegatePrefs = getDelegate().GetPreferencesForItem(itemID); } catch (NoSuchItemException nsie) { // OK. Probably an item that only the anonymous user has //if (log.isDebugEnabled()) { // log.debug("Item {} unknown", itemID); //} } List <IPreference> anonymousPreferences = new List <IPreference>(); foreach (var prefsMap in tempPrefs) { IPreferenceArray singleUserTempPrefs = prefsMap.Value; for (int i = 0; i < singleUserTempPrefs.Length(); i++) { if (singleUserTempPrefs.GetItemID(i) == itemID) { anonymousPreferences.Add(singleUserTempPrefs.Get(i)); } } } int delegateLength = delegatePrefs == null ? 0 : delegatePrefs.Length(); int anonymousPrefsLength = anonymousPreferences.Count; int prefsCounter = 0; // Merge the delegate and anonymous preferences into a single array IPreferenceArray newPreferenceArray = new GenericItemPreferenceArray(delegateLength + anonymousPrefsLength); for (int i = 0; i < delegateLength; i++) { newPreferenceArray.Set(prefsCounter++, delegatePrefs.Get(i)); } foreach (IPreference anonymousPreference in anonymousPreferences) { newPreferenceArray.Set(prefsCounter++, anonymousPreference); } if (newPreferenceArray.Length() == 0) { // No, didn't find it among the anonymous user prefs throw new NoSuchItemException(itemID); } return(newPreferenceArray); }
protected IList <Tuple <int, double> > sparseUserRatingVector(IPreferenceArray prefs) { var ratings = new List <Tuple <int, double> >(prefs.Length()); foreach (IPreference preference in prefs) { ratings.Add(new Tuple <int, double>((int)preference.GetItemID(), preference.GetValue())); } return(ratings); }
public void SetTempPrefs(IPreferenceArray prefs) { //Preconditions.checkArgument(prefs != null && prefs.Length() > 0, "prefs is null or empty"); this.tempPrefs = prefs; this.prefItemIDs.Clear(); for (int i = 0; i < prefs.Length(); i++) { this.prefItemIDs.Add(prefs.GetItemID(i)); } }
/// @throws NoSuchUserException /// if there is no such user public override IPreferenceArray GetPreferencesFromUser(long userID) { IPreferenceArray prefs = preferenceFromUsers.Get(userID); if (prefs == null) { throw new NoSuchUserException(userID); } return(prefs); }
public override IPreferenceArray GetPreferencesForItem(long itemID) { IPreferenceArray prefs = preferenceForItems.Get(itemID); if (prefs == null) { throw new NoSuchItemException(itemID); } return(prefs); }
public double averateRating(long itemID) { IPreferenceArray prefs = dataModel.GetPreferencesForItem(itemID); IRunningAverage avg = new FullRunningAverage(); foreach (IPreference pref in prefs) { avg.AddDatum(pref.GetValue()); } return(avg.GetAverage()); }
public override float EstimatePreference(long userID, long itemID) { IPreferenceArray preferencesFromUser = GetDataModel().GetPreferencesFromUser(userID); float? actualPref = getPreferenceForItem(preferencesFromUser, itemID); if (actualPref.HasValue) { return(actualPref.Value); } return(doEstimatePreference(userID, preferencesFromUser, itemID)); }
public override int GetNumUsersWithPreferenceFor(long itemID1, long itemID2) { IPreferenceArray prefs1 = preferenceForItems.Get(itemID1); if (prefs1 == null) { return(0); } IPreferenceArray prefs2 = preferenceForItems.Get(itemID2); if (prefs2 == null) { return(0); } int size1 = prefs1.Length(); int size2 = prefs2.Length(); int count = 0; int i = 0; int j = 0; long userID1 = prefs1.GetUserID(0); long userID2 = prefs2.GetUserID(0); while (true) { if (userID1 < userID2) { if (++i == size1) { break; } userID1 = prefs1.GetUserID(i); } else if (userID1 > userID2) { if (++j == size2) { break; } userID2 = prefs2.GetUserID(j); } else { count++; if (++i == size1 || ++j == size2) { break; } userID1 = prefs1.GetUserID(i); userID2 = prefs2.GetUserID(j); } } return(count); }
public void ratingVector() { IPreferenceArray prefs = dataModel.GetPreferencesFromUser(1); double[] ratingVector = ALSWRFactorizer.ratingVector(prefs); Assert.AreEqual(prefs.Length(), ratingVector.Length); Assert.AreEqual(prefs.Get(0).GetValue(), ratingVector[0], EPSILON); Assert.AreEqual(prefs.Get(1).GetValue(), ratingVector[1], EPSILON); Assert.AreEqual(prefs.Get(2).GetValue(), ratingVector[2], EPSILON); }
public void testTranspose() { FileDataModel tModel = new FileDataModel(testFileName, true, FileDataModel.DEFAULT_MIN_RELOAD_INTERVAL_MS); IPreferenceArray userPrefs = tModel.GetPreferencesFromUser(456); Assert.NotNull(userPrefs, "user prefs are null and it shouldn't be"); IPreferenceArray pref = tModel.GetPreferencesForItem(123); Assert.NotNull(pref, "pref is null and it shouldn't be"); Assert.AreEqual(3, pref.Length(), "pref Size: " + pref.Length().ToString() + " is not: " + 3); }
private int countPreferences() { int numPreferences = 0; var userIDs = dataModel.GetUserIDs(); while (userIDs.MoveNext()) { IPreferenceArray preferencesFromUser = dataModel.GetPreferencesFromUser(userIDs.Current); numPreferences += preferencesFromUser.Length(); } return(numPreferences); }
public override FastIDSet GetItemIDsFromUser(long userID) { IPreferenceArray prefs = GetPreferencesFromUser(userID); int size = prefs.Length(); FastIDSet result = new FastIDSet(size); for (int i = 0; i < size; i++) { result.Add(prefs.GetItemID(i)); } return(result); }
/// This computation is in a technical sense, wrong, since in the domain of "bool preference users" where /// all preference values are 1, this method should only ever return 1.0 or NaN. This isn't terribly useful /// however since it means results can't be ranked by preference value (all are 1). So instead this returns a /// sum of similarities. protected override float doEstimatePreference(long userID, IPreferenceArray preferencesFromUser, long itemID) { double[] similarities = getSimilarity().ItemSimilarities(itemID, preferencesFromUser.GetIDs()); bool foundAPref = false; double totalSimilarity = 0.0; foreach (double theSimilarity in similarities) { if (!Double.IsNaN(theSimilarity)) { foundAPref = true; totalSimilarity += theSimilarity; } } return foundAPref ? (float) totalSimilarity : float.NaN; }
private static float?getPreferenceForItem(IPreferenceArray preferencesFromUser, long itemID) { int size = preferencesFromUser.Length(); for (int i = 0; i < size; i++) { if (preferencesFromUser.GetItemID(i) == itemID) { return(preferencesFromUser.GetValue(i)); } } return(null); }
public override float?GetPreferenceValue(long userID, long itemID) { IPreferenceArray prefs = GetPreferencesFromUser(userID); int size = prefs.Length(); for (int i = 0; i < size; i++) { if (prefs.GetItemID(i) == itemID) { return(prefs.GetValue(i)); } } return(null); }
/// Sets temporary preferences for a given anonymous user. public void SetTempPrefs(IPreferenceArray prefs, long anonymousUserID) { //Preconditions.checkArgument(prefs != null && prefs.Length() > 0, "prefs is null or empty"); this.tempPrefs[anonymousUserID] = prefs; FastIDSet userPrefItemIDs = new FastIDSet(); for (int i = 0; i < prefs.Length(); i++) { userPrefItemIDs.Add(prefs.GetItemID(i)); } this.prefItemIDs[anonymousUserID] = userPrefItemIDs; }
private static long setBits(FastIDSet modelSet, IPreferenceArray prefs, int max) { long maxItem = -1; for (int i = 0; i < prefs.Length() && i < max; i++) { long itemID = prefs.GetItemID(i); modelSet.Add(itemID); if (itemID > maxItem) { maxItem = itemID; } } return(maxItem); }
public void testPreferencesForItem() { IPreferenceArray prefs = model.GetPreferencesForItem(456); Assert.NotNull(prefs); IPreference pref1 = prefs.Get(0); Assert.AreEqual(123, pref1.GetUserID()); Assert.AreEqual(456, pref1.GetItemID()); IPreference pref2 = prefs.Get(1); Assert.AreEqual(456, pref2.GetUserID()); Assert.AreEqual(456, pref2.GetItemID()); Assert.AreEqual(2, prefs.Length()); }
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); }
public override float?GetPreferenceValue(long userID, long itemID) { if (isAnonymousUser(userID)) { IPreferenceArray singleUserTempPrefs = tempPrefs[userID]; for (int i = 0; i < singleUserTempPrefs.Length(); i++) { if (singleUserTempPrefs.GetItemID(i) == itemID) { return(singleUserTempPrefs.GetValue(i)); } } return(null); } return(getDelegate().GetPreferenceValue(userID, itemID)); }
protected override FastIDSet doGetCandidateItems(long[] preferredItemIDs, IDataModel dataModel) { FastIDSet possibleItemsIDs = new FastIDSet(); foreach (long itemID in preferredItemIDs) { IPreferenceArray itemPreferences = dataModel.GetPreferencesForItem(itemID); int numUsersPreferringItem = itemPreferences.Length(); for (int index = 0; index < numUsersPreferringItem; index++) { possibleItemsIDs.AddAll(dataModel.GetItemIDsFromUser(itemPreferences.GetUserID(index))); } } possibleItemsIDs.RemoveAll(preferredItemIDs); return(possibleItemsIDs); }
/// This computation is in a technical sense, wrong, since in the domain of "bool preference users" where /// all preference values are 1, this method should only ever return 1.0 or NaN. This isn't terribly useful /// however since it means results can't be ranked by preference value (all are 1). So instead this returns a /// sum of similarities. protected override float doEstimatePreference(long userID, IPreferenceArray preferencesFromUser, long itemID) { double[] similarities = getSimilarity().ItemSimilarities(itemID, preferencesFromUser.GetIDs()); bool foundAPref = false; double totalSimilarity = 0.0; foreach (double theSimilarity in similarities) { if (!Double.IsNaN(theSimilarity)) { foundAPref = true; totalSimilarity += theSimilarity; } } return(foundAPref ? (float)totalSimilarity : float.NaN); }
private static double computeThreshold(IPreferenceArray prefs) { if (prefs.Length() < 2) { // Not enough data points -- return a threshold that allows everything return(Double.NegativeInfinity); } IRunningAverageAndStdDev stdDev = new FullRunningAverageAndStdDev(); int size = prefs.Length(); for (int i = 0; i < size; i++) { stdDev.AddDatum(prefs.GetValue(i)); } return(stdDev.GetAverage() + stdDev.GetStandardDeviation()); }
private static double computeThreshold(IPreferenceArray prefs) { if (prefs.Length() < 2) { // Not enough data points -- return a threshold that allows everything return Double.NegativeInfinity; } IRunningAverageAndStdDev stdDev = new FullRunningAverageAndStdDev(); int size = prefs.Length(); for (int i = 0; i < size; i++) { stdDev.AddDatum(prefs.GetValue(i)); } return stdDev.GetAverage() + stdDev.GetStandardDeviation(); }
protected IList<Tuple<int,double>> sparseUserRatingVector(IPreferenceArray prefs) { var ratings = new List<Tuple<int, double>>(prefs.Length()); foreach (IPreference preference in prefs) { ratings.Add(new Tuple<int, double>((int)preference.GetItemID(), preference.GetValue())); } return ratings; }
public static double[] ratingVector(IPreferenceArray prefs) { double[] ratings = new double[prefs.Length()]; for (int n = 0; n < prefs.Length(); n++) { ratings[n] = prefs.Get(n).GetValue(); } return ratings; //, true); new DenseVector( }
private static long[] getCommonItems(FastIDSet commonSet, IPreferenceArray prefs1, int max) { long[] commonItems = new long[max]; int index = 0; for (int i = 0; i < prefs1.Length(); i++) { long item = prefs1.GetItemID(i); if (commonSet.Contains(item)) { commonItems[index++] = item; } if (index == max) { break; } } return commonItems; }
/// @param userID /// ID of user being evaluated /// @param preferencesFromUser /// the preferences from the user /// @return all items in the {@link DataModel} for which the user has not expressed a preference and could /// possibly be recommended to the user /// @throws TasteException /// if an error occurs while listing items protected virtual FastIDSet GetAllOtherItems(long userID, IPreferenceArray preferencesFromUser) { return candidateItemsStrategy.GetCandidateItems(userID, preferencesFromUser, dataModel); }
private static IPreferenceArray cloneAndMergeInto(IPreferenceArray delegatePrefs, long itemID, long newUserID, float value) { int length = delegatePrefs == null ? 0 : delegatePrefs.Length(); int newLength = length + 1; IPreferenceArray newPreferenceArray = new GenericItemPreferenceArray(newLength); // Set item ID once newPreferenceArray.SetItemID(0, itemID); int positionToInsert = 0; while (positionToInsert < length && newUserID > delegatePrefs.GetUserID(positionToInsert)) { positionToInsert++; } for (int i = 0; i < positionToInsert; i++) { newPreferenceArray.SetUserID(i, delegatePrefs.GetUserID(i)); newPreferenceArray.SetValue(i, delegatePrefs.GetValue(i)); } newPreferenceArray.SetUserID(positionToInsert, newUserID); newPreferenceArray.SetValue(positionToInsert, value); for (int i = positionToInsert + 1; i < newLength; i++) { newPreferenceArray.SetUserID(i, delegatePrefs.GetUserID(i - 1)); newPreferenceArray.SetValue(i, delegatePrefs.GetValue(i - 1)); } return newPreferenceArray; }
public void clearTempPrefs() { tempPrefs = null; prefItemIDs.Clear(); }
public FastIDSet GetCandidateItems(long userID, IPreferenceArray preferencesFromUser, IDataModel dataModel) { return doGetCandidateItems(preferencesFromUser.GetIDs(), dataModel); }
private static long setBits(FastIDSet modelSet, IPreferenceArray prefs, int max) { long maxItem = -1; for (int i = 0; i < prefs.Length() && i < max; i++) { long itemID = prefs.GetItemID(i); modelSet.Add(itemID); if (itemID > maxItem) { maxItem = itemID; } } return maxItem; }