net.librec.eval.ranking.DiversityEvaluator Maven / Gradle / Ivy
/**
* Copyright (C) 2016 LibRec
*
* This file is part of LibRec.
* LibRec is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* LibRec is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with LibRec. If not, see .
*/
package net.librec.eval.ranking;
import net.librec.eval.AbstractRecommenderEvaluator;
import net.librec.math.structure.SparseMatrix;
import net.librec.math.structure.SymmMatrix;
import net.librec.recommender.item.ItemEntry;
import net.librec.recommender.item.RecommendedList;
import java.util.List;
/**
* DiversityEvaluator, average dissimilarity of all pairs of items in the
* recommended list at a specific cutoff position. Reference: Avoiding monotony:
* improving the diversity of recommendation lists, ReSys, 2008
*
* @author WangYuFeng
*/
public class DiversityEvaluator extends AbstractRecommenderEvaluator {
/**
* Evaluate on the test set with the the list of recommended items.
*
* @param testMatrix
* the given test set
* @param recommendedList
* the list of recommended items
* @return evaluate result
*/
public double evaluate(SparseMatrix testMatrix, RecommendedList recommendedList) {
double totalDiversity = 0.0;
int numUsers = testMatrix.numRows();
int nonZeroNumUsers = 0;
if (similarities.containsKey("item")) {
SymmMatrix itemSimilarity = similarities.get("item").getSimilarityMatrix();
for (int userID = 0; userID < numUsers; userID++) {
List> recommendArrayListByUser = recommendedList.getItemIdxListByUserIdx(userID);
if (recommendArrayListByUser.size() > 0) {
// calculate the sum of dissimilarities for each pair of items per user
double totalDisSimilarityPerUser = 0.0;
int topK = this.topN <= recommendArrayListByUser.size() ? this.topN : recommendArrayListByUser.size();
for (int i = 0; i < topK; i++) {
for (int j = 0; j < topK; j++) {
if (i == j) {
continue;
}
int item1 = recommendArrayListByUser.get(i).getKey();
int item2 = recommendArrayListByUser.get(j).getKey();
totalDisSimilarityPerUser += 1.0 - itemSimilarity.get(item1, item2);
}
}
totalDiversity += totalDisSimilarityPerUser * 2 / (topK * (topK - 1));
nonZeroNumUsers++;
}
}
}
return nonZeroNumUsers > 0 ? totalDiversity / nonZeroNumUsers : 0.0d;
}
}