private void pruneInconsequentialDiffs() { // Go back and prune inconsequential diffs. "Inconsequential" means, here, only represented by one // data point, so possibly unreliable var it1 = averageDiffs.entrySet().ToList(); for (int i = 0; i < it1.Count; i++) { FastByIDMap <RunningAverage> map = it1[i].Value; var it2 = map.entrySet().ToList(); for (int j = 0; j < it2.Count; j++) { RunningAverage average = it2[j].Value; if (average.getCount() <= 1) { map.remove(it2[j].Key); } } if (map.isEmpty()) { averageDiffs.remove(it1[i].Key); } else { map.rehash(); } } averageDiffs.rehash(); }
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(); } }
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)); } }