/** * Item filter that discard items for which no feature data is available. * * @param <U> type of the users * @param <I> type of the items * @param <F> type of the features * @param featureData feature data * @return item filters that return true when there is any feature information for the item */ public static <U, I, F> Function<U, Predicate<I>> withFeatures(FeatureData<I, F, ?> featureData) { Set<I> itemsWithFeatures = featureData.getItemsWithFeatures().collect(Collectors.toSet()); return user -> itemsWithFeatures::contains; }
/** * Returns a function that return the distance to the input item. * * @param i item * @return function that return the distance to the input item */ @Override public ToDoubleFunction<I> dist(I i) { Stream<Tuple2<F, V>> features1 = featureData.getItemFeatures(i); ToDoubleFunction<Stream<Tuple2<F, V>>> iDist = dist(features1); return j -> iDist.applyAsDouble(featureData.getItemFeatures(j)); }
private void init() { featureNorms = new Object2DoubleOpenHashMap<>(); featureData.getAllFeatures().forEach(f -> { int count = featureData.getFeatureItems(f) .map(Tuple2::v1) .mapToInt(totalData::numUsers) .sum(); featureNorms.put(f, count); }); }
/** * 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) { RelevanceModel.UserRelevanceModel<U, I> userRelModel = relModel.getModel(recommendation.getUser()); Set<F> subtopics = new HashSet<>(); int rank = 0; for (Tuple2od<I> iv : recommendation.getItems()) { if (userRelModel.isRelevant(iv.v1)) { subtopics.addAll(featureData.getItemFeatures(iv.v1) .map(Tuple2::v1) .collect(toList())); } rank++; if (rank >= cutoff) { break; } } return subtopics.size() / (double) featureData.numFeatures(); }
int cutoff = 100; PreferenceData<Long, Long> trainData = SimplePreferenceData.load(SimpleRatingPreferencesReader.get().read(trainDataPath, lp, lp)); FeatureData<Long, String, Double> featureData = SimpleFeatureData.load(SimpleFeaturesReader.get().read(featurePath, lp, sp));
/** * Loads an instance of the class from a stream of triples. * * @param <I> type of item * @param <F> type of feat * @param <V> type of value * @param tuples stream of item-feat-value triples * @return a feature data object */ public static <I, F, V> SimpleFeatureData<I, F, V> load(Stream<Tuple3<I, F, V>> tuples) { Map<I, List<Tuple2<F, V>>> itemMap = new HashMap<>(); Map<F, List<Tuple2<I, V>>> featMap = new HashMap<>(); tuples.forEach(t -> { itemMap.computeIfAbsent(t.v1, v1 -> new ArrayList<>()).add(tuple(t.v2, t.v3)); featMap.computeIfAbsent(t.v2, v2 -> new ArrayList<>()).add(tuple(t.v1, t.v3)); }); return new SimpleFeatureData<>(itemMap, featMap); } }
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; }
private Object2DoubleMap<F> getGlobalFeatureProbs() { Object2DoubleMap<F> probs = new Object2DoubleOpenHashMap<>(); probs.defaultReturnValue(0.0); int n = recommenderData.numPreferences(); featureData.getAllFeatures().sequential().forEach(f -> { int numPrefs = featureData.getFeatureItems(f) .map(Tuple2::v1) .mapToInt(recommenderData::numUsers) .sum(); probs.put(f, numPrefs / (double) n); }); return probs; }
FeatureData<Long, String, Double> featureData = SimpleFeatureData.load(SimpleFeaturesReader.get().read(featurePath, lp, sp));
double gain = featureData.getItemFeatures(pair.v1).sequential() .map(Tuple2::v1) .mapToDouble(f -> {
/** * 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) { RelevanceModel.UserRelevanceModel<U, I> userRelModel = relModel.getModel(recommendation.getUser()); BinomialModel<U, I, F>.UserBinomialModel prob = binomialModel.getModel(recommendation.getUser()); Object2IntOpenHashMap<F> count = new Object2IntOpenHashMap<>(); count.defaultReturnValue(0); int rank = 0; int nrel = 0; for (Tuple2od<I> iv : recommendation.getItems()) { if (userRelModel.isRelevant(iv.v1)) { featureData.getItemFeatures(iv.v1) .forEach(fv -> count.addTo(fv.v1, 1)); nrel++; } rank++; if (rank >= cutoff) { break; } } return getResultFromCount(prob, count, nrel, rank); }
for (Tuple2od<I> iv : recommendation.getItems()) { if (userRelModel.isRelevant(iv.v1)) { featureData.getItemFeatures(iv.v1) .forEach(fv -> count.addTo(fv.v1, 1)); } else {