Apache Mahout: how to add weight to neighborhood and get a recommendation?

120 views Asked by At

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):

  1. create a DataModel: DataModel userModel = new GenericDataModel(userItemPreference);
  2. compute similarity: UserSimilarity euclideanDistanceUserSimilarity = new EuclideanDistanceSimilarity(userModel);
  3. get basic neighborhood UserNeighborhood e_n_neighborhood = new NearestNUserNeighborhood(20, euclideanDistanceUserSimilarity, userModel);
  4. compute a "weight" value for any of these user (*)
  5. change the similarity of users inside neighorhood using weighted values (e.g. similarity*=weight) (*)
  6. get a sub neighborhood containing only the 10 high-weighted-related users (*)
  7. 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

1

There are 1 answers

0
Pierpaolo Cira On

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

UserBasedRecommender t_recommender = 
      new GenericUserBasedRecommender(userModel, e_n_neighborhood,
                                  euclideanDistanceUserSimilarity, null);

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.

  1. Create a new userModel (like the existing one) with just interested users, all items and all scores

  2. Create a UserNeighborhood implementing just

    public 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).

  1. Create a UserSimilarity implementing just

    public 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).

  1. Now you can proceed with the recommendation, passing these new objects.