2

What is wrong with the following code and why it produces no recommendations for anonymous user?
I cannot figure out what's going wrong, but I can't get recommendations for anonymous user with PlusAnonymousUserDataModel. This is the example code, which shows no recommendations for anonymous user, but gives recommendation for user in the model with exactly similar preferences:

public static void main(String[] args) throws Exception {
    DataModel model = new GenericBooleanPrefDataModel(
            GenericBooleanPrefDataModel.toDataMap(new FileDataModel(
                    new File(args[0]))));
    PlusAnonymousUserDataModel plusAnonymousModel = new PlusAnonymousUserDataModel(model);

    UserSimilarity similarity = new LogLikelihoodSimilarity(model);
    UserNeighborhood neighborhood =
            new NearestNUserNeighborhood(
                    Integer.parseInt(args[1]), similarity, model);
    //new ThresholdUserNeighborhood(Float.parseFloat(args[1]), similarity, model);


    System.out.println("Neighborhood=" + args[1]);
    System.out.println("");




    Recommender recommender = new GenericBooleanPrefUserBasedRecommender(model,
            neighborhood, similarity);


    PreferenceArray anonymousPrefs =
            new BooleanUserPreferenceArray(12);
    anonymousPrefs.setUserID(0,
            PlusAnonymousUserDataModel.TEMP_USER_ID);
    anonymousPrefs.setItemID(0, 1105L);
    anonymousPrefs.setItemID(1, 1201L);
    anonymousPrefs.setItemID(2, 1301L);
    anonymousPrefs.setItemID(3, 1401L);
    anonymousPrefs.setItemID(4, 1502L);
    anonymousPrefs.setItemID(5, 1602L);
    anonymousPrefs.setItemID(6, 1713L);
    anonymousPrefs.setItemID(7, 1801L);
    anonymousPrefs.setItemID(8, 1901L);
    anonymousPrefs.setItemID(9, 2002L);
    anonymousPrefs.setItemID(10, 9101L);
    anonymousPrefs.setItemID(11, 9301L);

    synchronized(anonymousPrefs){
        plusAnonymousModel.setTempPrefs(anonymousPrefs);
        List<RecommendedItem> recommendations1 = recommender.recommend(PlusAnonymousUserDataModel.TEMP_USER_ID, 20);
        plusAnonymousModel.clearTempPrefs();

        System.out.println("Recm for anonymous:");

        for (RecommendedItem recommendation : recommendations1) {
            System.out.println(recommendation);
        }
        System.out.println("");
    }


    List<RecommendedItem> recommendations = recommender.recommend(
            Integer.parseInt(args[2]), 20);

    System.out.println("Recomedation for user_id="
            + Integer.parseInt(args[2]) + ":");

    for (RecommendedItem recommendation : recommendations) {
        System.out.println(recommendation);
    }
    System.out.println("");

The output produced by this code is as follows: Neighborhood=100

Recm for anonymous:

Recomedation for user_id=1680604: RecommendedItem[item:1701, value:24.363672] ... and so on. So there's no recommendations for anonymous user! :(

It turns out that to get recommendations you must construct similarity, neighbourhood and recommender using not "real" (file-based in my case), persistent DataModel model, but with PlusAnonymousUserDataModel plusAnonymousModel instead!
So, basical documentation on Mahout ( https://builds.apache.org/job/Mahout-Quality/javadoc/org/apache/mahout/cf/taste/impl/model/PlusAnonymousUserDataModel.html ) is wrong stating ItemSimilarity similarity = new LogLikelihoodSimilarity(realModel); // not plusModel

Earlier, other person on SO had the same problem and didn't get any answer here: Model creation for User User collanborative filtering So I think I should go there and answer to him. Sean Owen, thank you for your interest, can you approve that the solution I found is the correct one?

Community
  • 1
  • 1
  • Can you be more specific about what's not working, and what libraries you're using? – Noah Oct 23 '12 at 13:57
  • Knowing the name of the framework would be great. And the description of what you exactly wait. – Gábor Lipták Oct 23 '12 at 13:58
  • Not enough information... what is your data set? are there any items left to recommend to this anonymous user? – Sean Owen Oct 23 '12 at 14:01
  • the question is why I cannot get recommendation for anonymous user. the output of that code is as follows: "Neighborhood=100 Recm for anonymous: Recomedation for user_id=1680604: RecommendedItem[item:1701, value:24.363672] (and so on)" but I supplied to anonymousPrefs exactly the same preference as they are for user 1680604 in file model. – Nikita Kuznetsov Oct 23 '12 at 14:49
  • framework is standard Mahout 0.7 installation and the libraries are as they are in MiA book – Nikita Kuznetsov Oct 23 '12 at 14:51
  • my dataset is real-life/production and without PlusAnonymous... I tested the recommendation Mahout produced and found them satisfactory. But now I need to use PlusAnonymousUserDataModel and for many hours I cannot find a way to implement it. – Nikita Kuznetsov Oct 23 '12 at 14:57
  • I would use a debugger to get a little more info on why no recommendations are coming back. The code looks correct to my eyes. If you have a deeper lead, maybe I can guess the issue. – Sean Owen Oct 24 '12 at 12:23
  • 1
    it turns out that similarity and neighborhood constructors must be called NOT with 'model', but with 'plusAnonymousModel'! It is directly opposite to what is said in documentation (https://builds.apache.org/job/Mahout-Quality/javadoc/org/apache/mahout/cf/taste/impl/model/PlusAnonymousUserDataModel.html) But when I replaced `UserSimilarity similarity = new LogLikelihoodSimilarity(model)` with `UserSimilarity similarity = new LogLikelihoodSimilarity(plusAnonymousModel)` (and the same for neighbourhood), the code finally worked! – Nikita Kuznetsov Oct 24 '12 at 13:39

0 Answers0