In mahout you can define a CandidateItemsStrategy
for GenericItemBasedRecommender
such that specific items e.g. of a certain category are excluded.
When using a GenericUserBasedRecommender
this is not possible. How can I accomplish this with GenericUserBasedRecommender
? Is the only way to do this using a IDRescorer
? If possible I'd like to avoid using a IDRescorer
. Thank you for your help!
[Edit]
For the item based recommender I do it like this:
private final class OnlySpecificlItemsStrategy implements CandidateItemsStrategy {
private final JpaDataModel dataModel;
public OnlySpecificlItemsStrategy(JpaDataModel dataModel) {
this.dataModel = dataModel;
}
@Override
public FastIDSet getCandidateItems(long userID, PreferenceArray preferencesFromUser, DataModel dataModel) throws TasteException {
List<Long> specificlItemIDs = this.dataModel.getSpecificlItemIDs();
FastIDSet candidateItemIDs = new FastIDSet();
for (long itemID : specificlItemIDs)
candidateItemIDs.add(itemID);
for (int j = 0; j < preferencesFromUser.length(); j++)
candidateItemIDs.remove(preferencesFromUser.getItemID(j));
return candidateItemIDs;
}
}
For the user based recommender I do it with a Rescorer:
public class FilterIDsRescorer implements IDRescorer {
FastIDSet allowedIDs;
public FilterIDsRescorer(FastIDSet allowedIDs) {
this.allowedIDs = allowedIDs;
}
@Override
public double rescore(long id, double originalScore) {
return originalScore;
}
@Override
public boolean isFiltered(long id) {
return !this.allowedIDs.contains(id);
}
}
and then set it up like this:
List<Long> specificItemIDsList = dataModel.getOtherSpecificlItemIDs();
FastIDSet specificItemIDs = new FastIDSet(specificItemIDsList.size());
for (Long id : specificItemIDsList) {
specificItemIDs.add(id);
}
this.filterIDsRescorer = new FilterIDsRescorer(specificItemIDs );
userBasedRecommender.recommend(userID, howMany, this.filterIDsRescorer)
For the purpose of filtering/excluding certain items I could also subclass my data model for each type of recommender, but then I cannot share the same data model instance which would have an impact on performance.
There isn't a way to do this. The user-based and item-based algorithms are not quite symmetric, and it's mostly on purpose. The user-based system already has a notion of user neighborhood which is kind of like this idea. IDRescorer
is unrelated.
来源:https://stackoverflow.com/questions/8773861/candidate-strategy-for-genericuserbasedrecommender-in-mahout