private double idcg(NDCGRelevanceModel.UserNDCGRelevanceModel relModel) { double[] gains = relModel.getGainValues(); Arrays.sort(gains); double idcg = 0; int n = Math.min(cutoff, gains.length); int m = gains.length; for (int rank = 0; rank < n; rank++) { idcg += gains[m - rank - 1] * disc.disc(rank); } return idcg; }
@Override public void add(Recommendation<U, I> recommendation) { RelevanceModel.UserRelevanceModel<U, I> urm = rel.getModel(recommendation.getUser()); List<Tuple2od<I>> list = recommendation.getItems(); int rank = Math.min(cutoff, list.size()); double userNorm = IntStream.range(0, rank).mapToDouble(disc::disc).sum(); IntStream.range(0, rank).forEach(k -> { I i = list.get(k).v1; double d = disc.disc(k); double w = d * urm.gain(i) / userNorm; itemCount.addTo(i, d); itemWeight.addTo(i, w); }); freeNorm += userNorm; numUsers++; }
private double idcg(UserIdealRelevanceModel<U, I> urm) { double ideal = 0; Object2IntOpenHashMap<F> redundancy = new Object2IntOpenHashMap<>(); redundancy.defaultReturnValue(0); Set<I> candidates = new HashSet<>(urm.getRelevantItems()); int rank = 0; while (rank <= cutoff && !candidates.isEmpty()) { I bi = null; double bg = Double.NEGATIVE_INFINITY; for (I i : candidates) { double gain = featureData.getItemFeatures(i) .map(Tuple2::v1) .mapToDouble(f -> Math.pow(1 - alpha, redundancy.getInt(f))) .sum(); if (gain > bg) { bg = gain; bi = i; } } candidates.remove(bi); featureData.getItemFeatures(bi).sequential() .map(Tuple2::v1) .forEach(f -> redundancy.addTo(f, 1)); ideal += bg * disc.disc(rank); rank++; } return ideal; }
/** * Returns a score for the recommendation list. * * @param recommendation recommendation list * @return score of the metric to the recommendation */ @Override public double evaluate(Recommendation<U, I> recommendation) { NDCGRelevanceModel<U, I>.UserNDCGRelevanceModel userRelModel = (NDCGRelevanceModel<U, I>.UserNDCGRelevanceModel) relModel.getModel(recommendation.getUser()); double ndcg = 0.0; int rank = 0; for (Tuple2od<I> pair : recommendation.getItems()) { ndcg += userRelModel.gain(pair.v1) * disc.disc(rank); rank++; if (rank >= cutoff) { break; } } if (ndcg > 0) { ndcg /= idcg(userRelModel); } return ndcg; }
return Math.pow(1 - alpha, r); }).sum(); ndcg += gain * disc.disc(rank);