@Test public void testEmptySummary() { DataAccessObject dao = EntityCollectionDAO.create(); RatingSummary sum = RatingSummary.create(dao); assertThat(sum.getGlobalMean(), equalTo(0.0)); assertThat(sum.getItemMean(42), notANumber()); assertThat(sum.getItemOffset(42), equalTo(0.0)); assertThat(sum.getItemRatingCount(42), equalTo(0)); }
@Override public ItemBiasModel get() { Long2DoubleMap offsets; if (damping > 0) { offsets = new Long2DoubleOpenHashMap(); LongIterator iter = summary.getItems().iterator(); while (iter.hasNext()) { long item = iter.nextLong(); double off = summary.getItemOffset(item); int count = summary.getItemRatingCount(item); offsets.put(item, count * off / (count + damping)); } } else { offsets = summary.getItemOffets(); } return new ItemBiasModel(summary.getGlobalMean(), offsets); } }
@Nonnull @Override public ResultMap scoreWithDetails(long user, @Nonnull Collection<Long> items) { final double gmean = summary.getGlobalMean(); List<Result> results = new ArrayList<>(); LongIterator iter = LongIterators.asLongIterator(items.iterator()); while (iter.hasNext()) { final long item = iter.nextLong(); double offset = summary.getItemOffset(item); if (!Scalars.isZero(damping)) { int count = summary.getItemRatingCount(item); offset = offset * count / (count + damping); } results.add(Results.create(item, gmean + offset)); } return Results.newResultMap(results); }
@Nonnull @Override public MetricResult measureUserRecList(Recommender rec, TestUser user, int targetLength, List<Long> recs, Context context) { RatingSummary summary = null; if (rec instanceof LenskitRecommender) { summary = ((LenskitRecommender) rec).get(RatingSummary.class); } if (recs == null || recs.isEmpty() || summary == null) { return MetricResult.empty(); } double pop = 0; for (long item: recs) { pop += summary.getItemRatingCount(item); } pop = pop / recs.size(); context.addUser(pop); return new PopResult(pop); }
@Override public String toString() { String cls = getClass().getSimpleName(); return String.format("%s(µ=%.3f, γ=%.2f)", cls, summary.getGlobalMean(), damping); } }
public ItemScorer makeGlobalMean() { return new GlobalMeanRatingItemScorer(RatingSummary.create(dao)); }
return new RatingSummary(mean, items, offsets, countArray);
@Nonnull @Override public ResultMap scoreWithDetails(long user, @Nonnull Collection<Long> items) { final double gmean = summary.getGlobalMean(); List<Result> results = new ArrayList<>(); LongIterator iter = LongIterators.asLongIterator(items.iterator()); while (iter.hasNext()) { final long item = iter.nextLong(); double offset = summary.getItemOffset(item); if (!Scalars.isZero(damping)) { int count = summary.getItemRatingCount(item); offset = offset * count / (count + damping); } results.add(Results.create(item, gmean + offset)); } return Results.newResultMap(results); }
@Nonnull @Override public MetricResult measureUser(TestUser user, ResultList recs, Context context) { if (recs == null || recs.isEmpty()) { return MetricResult.empty(); } double pop = 0; for (Result r: recs) { pop += context.summary.getItemRatingCount(r.getId()); } pop = pop / recs.size(); context.mean.add(pop); return new PopResult(pop); }
@Inject public GlobalMeanRatingItemScorer(@Transient RatingSummary summary) { super(summary.getGlobalMean()); } }
public ItemScorer makeGlobalMean() { return new GlobalMeanRatingItemScorer(RatingSummary.create(dao)); }
return new RatingSummary(mean, items, offsets, countArray);
@Test public void testSummaryItem() { EntityFactory efac = new EntityFactory(); EntityCollectionDAOBuilder daoB = new EntityCollectionDAOBuilder(); // add ratings at 3.9 and 3.1, to make 3.5 average for (int i = 0; i < 100; i++) { daoB.addEntities(efac.rating(i, 37L, 3.9 + (i - 49.5) * 0.01)); daoB.addEntities(efac.rating(i, 82L, 3.1 + (i - 49.5) * 0.01)); } RatingSummary sum = RatingSummary.create(daoB.build()); assertThat(sum.getGlobalMean(), equalTo(3.5)); assertThat(sum.getItemMean(42), notANumber()); assertThat(sum.getItemOffset(42), equalTo(0.0)); assertThat(sum.getItemRatingCount(42), equalTo(0)); assertThat(sum.getItemMean(37), equalTo(3.9)); assertThat(sum.getItemOffset(37), closeTo(0.4, 1.0e-6)); assertThat(sum.getItemRatingCount(37), equalTo(100)); assertThat(sum.getItemMean(82), equalTo(3.1)); assertThat(sum.getItemOffset(82), closeTo(-0.4, 1.0e-6)); assertThat(sum.getItemRatingCount(82), equalTo(100)); } }
@Override public ItemBiasModel get() { Long2DoubleMap offsets; if (damping > 0) { offsets = new Long2DoubleOpenHashMap(); LongIterator iter = summary.getItems().iterator(); while (iter.hasNext()) { long item = iter.nextLong(); double off = summary.getItemOffset(item); int count = summary.getItemRatingCount(item); offsets.put(item, count * off / (count + damping)); } } else { offsets = summary.getItemOffets(); } return new ItemBiasModel(summary.getGlobalMean(), offsets); } }
@Override public String toString() { String cls = getClass().getSimpleName(); return String.format("%s(µ=%.3f, γ=%.2f)", cls, summary.getGlobalMean(), damping); } }
@Test public void testItemMeanBaseline() { ItemScorer pred = new ItemMeanRatingItemScorer(RatingSummary.create(dao), 0.0); // unseen item, should be global mean assertThat(pred.score(10, 2).getScore(), closeTo(RATINGS_DAT_MEAN, 0.001)); // seen item - should be item average assertThat(pred.score(10, 5).getScore(), closeTo(3.0, 0.001)); }
@Inject public GlobalMeanRatingItemScorer(@Transient RatingSummary summary) { super(summary.getGlobalMean()); } }
@Test public void testUserItemMeanBaseline() { ItemScorer base = new ItemMeanRatingItemScorer(RatingSummary.create(dao), 0.0); ItemScorer pred = new UserMeanItemScorer(new StandardRatingVectorPDAO(dao), base, 0); // we use user 8 - their average offset is 0.5 // unseen item, should be global mean + user offset assertThat(pred.score(8, 10).getScore(), closeTo(RATINGS_DAT_MEAN + 0.5, 0.001)); // seen item - should be item average + user offset assertThat(pred.score(8, 5).getScore(), closeTo(3.5, 0.001)); } }