Skip to content
This repository has been archived by the owner on Mar 20, 2024. It is now read-only.

DetailedResults

Michael Ekstrand edited this page Feb 27, 2015 · 4 revisions

Right now, scorers and recommenders and such report their results through sparse vectors or scored IDs, with details being handled through 'side channels'.

Side channels are complicated and confusing.

This page is to work on ideas for a new design for recommendation details.

The Problem

In the common case, we want to just get scores and/or rankings from a recommender.

However, sometimes, particularly in experiments, we want to get some additional details from the recommender; things like an estimate of the certainty of the recommendation.

We want the common case — get a score — to be easy. Also, if the additional details are expensive to compute, we do not want to incur the computational or memory overhead if they are not going to be used.

Right now we're doing this through a complicated mess.

Proposed Solution

Introduce new types, ScoreResults and RecommendResults, to provide access to scores and recommendations (using custom interfaces, rather than e.g. maps and lists, so we can provide unboxed access). For the rest of this draft, we will focus on score results, but recommend results can be considered similarly.

public interface ScoreResults extends Iterable<ScoredId> {
    double getScore(long key);
    // details on this interface TBD
}

And now we can have a scorer:

public interface ItemScorer {
    ScoreResults predict(long user, Collection<Long> items);
    ScoreResults predictWithDetails(long user, Collection<Long> items);
}

As it is, the details provide nothing new. However, individual scorer implementations will return a different subclass of ScoreResults that contains relevant details:

public class ItemItemScorer implements ItemScorer<ItemItemDetails> {
    ScoreResults predict(long user, Collection<Long> items);
    ItemItemScoreResults predictWithDetails(long user, Collection<Long> items);
}

Now, rather than having a very complicated thing with side channels, and mystically knowing what channels to use, you can instead know that you're working with an ItemItemScorer, and from there have statically compiled and type-safe access to the details. Otherwise, you can use instanceof checks to see if it is a particular kind of details.

If details are inexpensive to compute, then predict and predictWithDetails can both return the details.