Github user takuti commented on a diff in the pull request:
https://github.com/apache/incubator-hivemall/pull/115#discussion_r139082280
--- Diff:
core/src/main/java/hivemall/evaluation/BinaryResponsesMeasures.java ---
@@ -120,48 +148,65 @@ public static int countTruePositive(final List<?>
rankedList, final List<?> grou
}
/**
- * Computes Mean Reciprocal Rank (MRR)
+ * Computes Reciprocal Rank
*
* @param rankedList a list of ranked item IDs (first item is
highest-ranked)
* @param groundTruth a collection of positive/correct item IDs
* @param recommendSize top-`recommendSize` items in `rankedList` are
recommended
- * @return MRR
+ * @return Reciprocal Rank
+ * @link https://en.wikipedia.org/wiki/Mean_reciprocal_rank
*/
- public static double MRR(@Nonnull final List<?> rankedList, @Nonnull
final List<?> groundTruth,
- @Nonnull final int recommendSize) {
- for (int i = 0, n = recommendSize; i < n; i++) {
+ public static double ReciprocalRank(@Nonnull final List<?> rankedList,
+ @Nonnull final List<?> groundTruth, @Nonnegative final int
recommendSize) {
+ Preconditions.checkArgument(recommendSize > 0);
+
+ final int k = Math.min(rankedList.size(), recommendSize);
+ for (int i = 0; i < k; i++) {
Object item_id = rankedList.get(i);
if (groundTruth.contains(item_id)) {
- return 1.0 / (i + 1.0);
+ return 1.d / (i + 1);
}
}
- return 0.0;
+ return 0.d;
}
/**
- * Computes Mean Average Precision (MAP)
+ * Computes Average Precision (AP)
*
* @param rankedList a list of ranked item IDs (first item is
highest-ranked)
* @param groundTruth a collection of positive/correct item IDs
* @param recommendSize top-`recommendSize` items in `rankedList` are
recommended
- * @return MAP
+ * @return AveragePrecision
*/
- public static double MAP(@Nonnull final List<?> rankedList, @Nonnull
final List<?> groundTruth,
- @Nonnull final int recommendSize) {
+ public static double AveragePrecision(@Nonnull final List<?>
rankedList,
+ @Nonnull final List<?> groundTruth, @Nonnegative final int
recommendSize) {
+ Preconditions.checkArgument(recommendSize > 0);
+
+ if (groundTruth.isEmpty()) {
+ if (rankedList.isEmpty()) {
+ return 1.d;
+ }
+ return 0.d;
+ }
+
int nTruePositive = 0;
- double sumPrecision = 0.0;
+ double sumPrecision = 0.d;
// accumulate precision@1 to @recommendSize
- for (int i = 0, n = recommendSize; i < n; i++) {
+ final int k = Math.min(rankedList.size(), recommendSize);
+ for (int i = 0; i < k; i++) {
Object item_id = rankedList.get(i);
if (groundTruth.contains(item_id)) {
nTruePositive++;
- sumPrecision += nTruePositive / (i + 1.0);
+ sumPrecision += nTruePositive / (i + 1.d);
}
}
- return sumPrecision / groundTruth.size();
+ if (nTruePositive == 0) {
+ return 0.d;
+ }
+ return sumPrecision / nTruePositive;
--- End diff --
ð
---