I'm working on the implementation of a recommendation algorithm with a "special" feature and I would like to perform just this small customization on basic algorithms provided by Apache Mahout.
These are the steps I'm following (*=non-basic steps):
- create a DataModel:
DataModel userModel = new GenericDataModel(userItemPreference);
- compute similarity:
UserSimilarity euclideanDistanceUserSimilarity = new EuclideanDistanceSimilarity(userModel);
- get basic neighborhood
UserNeighborhood e_n_neighborhood = new NearestNUserNeighborhood(20, euclideanDistanceUserSimilarity, userModel);
- compute a "weight" value for any of these user (*)
- change the similarity of users inside neighorhood using weighted values (e.g.
similarity*=weight
) (*) - get a sub neighborhood containing only the 10 high-weighted-related users (*)
- get a recommendation using only this new neighborhood (*)
It should be very simple, but I don't understand why, to build a Recommender, Mahout need for userModel, neighborhood and distanceSimilarity again)... so I can't figure which object I need to modify and pass to the constructor (new neighborhood apart).
UserBasedRecommender t_recommender =
new GenericUserBasedRecommender(userModel, e_n_neighborhood,
euclideanDistanceUserSimilarity, null);
Do you have any suggestion to help me to implement steps 5 and 7 (considering the GenericUserBasedRecommender
concerns I just spoke about)?
Thank you
I think I was able to solve the problem, so I will explain here my solution... maybe it will be useful for someone else.
As I said I need to run
but, by modifying with a weight-list the similarity, and restricting the set of the users and in the neighborhood.
To achieve this, a way to proceed is to create your own implementation of the interfaces expected by
GenericUserBasedRecommender
constructor.These implementation don't need to compute any metric or value, they should just be able to return expected elements.
So, after applying the weight and filtering the user list, the main points are the following.
Create a new userModel (like the existing one) with just interested users, all items and all scores
Create a
UserNeighborhood
implementing justpublic long[] getUserNeighborhood(long userID) throws TasteException;
This class should implements a basic neighborhood container, and the methos should returni just the static list of neighborhood for any user (static, because you already have it, so you can simply pass it by the constructor and put it in memory).
Create a
UserSimilarity
implementing justpublic double userSimilarity(long userID1, long userID2) throws TasteException;
The behaviour should be the same of the previous class (so you can use values from the initial
UserSimilarity
, remembering to consider weight also).