@Nonnull @Override public MetricResult measureUserRecList(Recommender rec, TestUser user, int targetLength, List<Long> recommendations, Mean context) { if (recommendations == null) { return MetricResult.empty(); } Long2DoubleMap ratings = new Long2DoubleOpenHashMap(); for (Entity e: user.getTestHistory()) { long item = e.getLong(CommonAttributes.ITEM_ID); Object av = e.get(gainAttribute); if (av instanceof Number) { ratings.put(item, ((Number) av).doubleValue()); } else { throw new IllegalArgumentException("value " + av + " for attribute " + gainAttribute + " is not numeric"); } } List<Long> ideal = ratings.keySet() .stream() .sorted(LongUtils.keyValueComparator(ratings).reversed()) .limit(targetLength >= 0 ? targetLength : ratings.size()) .collect(Collectors.toList()); double idealGain = computeDCG(ideal, ratings); double gain = computeDCG(recommendations, ratings); double score = gain / idealGain; synchronized (context) { context.increment(score); } return MetricResult.singleton(columnName, score); }
@Nonnull @Override public MetricResult measureUser(TestUser user, ResultMap predictions, Mean context) { if (predictions == null || predictions.isEmpty()) { return MetricResult.empty(); } Long2DoubleMap ratings = user.getTestRatings(); long[] ideal = ratings.keySet().toLongArray(); LongArrays.quickSort(ideal, LongComparators.oppositeComparator(LongUtils.keyValueComparator(ratings))); long[] actual = LongUtils.asLongSet(predictions.keySet()).toLongArray(); LongArrays.quickSort(actual, LongComparators.oppositeComparator( LongUtils.keyValueComparator( LongUtils.asLong2DoubleMap(predictions.scoreMap())))); double idealGain = computeDCG(ideal, ratings); double gain = computeDCG(actual, ratings); logger.debug("user {} has gain of {} (ideal {})", user.getUserId(), gain, idealGain); double score = gain / idealGain; synchronized (context) { context.increment(score); } ImmutableMap.Builder<String,Double> results = ImmutableMap.builder(); return MetricResult.fromMap(results.put(columnName, score) .put(columnName + ".Raw", gain) .build()); }
@Nonnull @Override public MetricResult measureUser(TestUser user, ResultMap predictions, MeanAccumulator context) { if (predictions == null || predictions.isEmpty()) { return MetricResult.empty(); } Long2DoubleMap ratings = user.getTestRatings(); long[] ideal = ratings.keySet().toLongArray(); LongArrays.quickSort(ideal, LongComparators.oppositeComparator(LongUtils.keyValueComparator(ratings))); long[] actual = LongUtils.asLongSet(predictions.keySet()).toLongArray(); LongArrays.quickSort(actual, LongComparators.oppositeComparator( LongUtils.keyValueComparator( LongUtils.asLong2DoubleFunction(predictions.scoreMap())))); double idealGain = computeDCG(ideal, ratings); double gain = computeDCG(actual, ratings); logger.debug("user {} has gain of {} (ideal {})", user.getUserId(), gain, idealGain); double score = gain / idealGain; context.add(score); ImmutableMap.Builder<String,Double> results = ImmutableMap.builder(); return MetricResult.fromMap(results.put(columnName, score) .put(columnName + ".Raw", gain) .build()); }
@Nonnull @Override public MetricResult measureUser(TestUser user, ResultList recommendations, MeanAccumulator context) { if (recommendations == null) { return MetricResult.empty(); } Long2DoubleMap ratings = user.getTestRatings(); long[] ideal = ratings.keySet().toLongArray(); LongArrays.quickSort(ideal, LongComparators.oppositeComparator(LongUtils.keyValueComparator(ratings))); double idealGain = computeDCG(ideal, ratings); long[] actual = LongUtils.asLongCollection(recommendations.idList()).toLongArray(); double gain = computeDCG(actual, ratings); double score = gain / idealGain; context.add(score); return MetricResult.singleton(columnName, score); }