Example usage for org.apache.mahout.cf.taste.impl.recommender GenericItemBasedRecommender recommendedBecause

List of usage examples for org.apache.mahout.cf.taste.impl.recommender GenericItemBasedRecommender recommendedBecause

Introduction

In this page you can find the example usage for org.apache.mahout.cf.taste.impl.recommender GenericItemBasedRecommender recommendedBecause.

Prototype

@Override
    public List<RecommendedItem> recommendedBecause(long userID, long itemID, int howMany) throws TasteException 

Source Link

Usage

From source file:ContentBasedRecommender.java

License:Apache License

/**
 * Method the creates a list of recommendations.
 * Already rated stories are excluded, as are stories present in the front end array if add="true"
 * // w  w  w.ja v a2 s  .co m
 * @throws TasteException   thrown if there if something went wrong with Mahout
 */
public void runContentBasedRecommender() throws TasteException {
    /*Find out where this file is located*/
    try {
        fileLocation = new File(this.getClass().getProtectionDomain().getCodeSource().getLocation().toURI());
    } catch (URISyntaxException e) {
        e.printStackTrace();
    }
    /*"content"+userId is the name of the view we shall create*/
    conn.setConnection();

    /*Create a temporary view the includes all preferences values for this user*/
    conn.createView((int) userId);

    /*Sets the dataModel based on the data in the created view*/
    conn.setDataModel();

    DataModel model = conn.getDataModel();

    /*Gets all the info from the similarites.csv file into a list of objects accepted by Mahout*/
    Collection<ItemItemSimilarity> sim = getStorySimilarities();

    /*GenericItemBasedRecommender need an ItemSimilarity-object as input, so create an instance of this class.*/
    ItemSimilarity similarity = new GenericItemSimilarity(sim);

    /*Create a new Recommender-instance with our datamodel and story similarities*/
    GenericItemBasedRecommender recommender = new GenericItemBasedRecommender(model, similarity);

    /* Compute the recommendations. model.getNumItems() is the number of recommendations we want (we don't really want that many, 
     * but we don't know how many of the top items the user already have rated), don't worry about the null, 
     * and true tells the recommender that we want to include already known items*/
    List<RecommendedItem> recommendations = recommender.recommend(userId, model.getNumItems(), null, true);

    /*Find the stories that the user have rated*/
    HashMap<Integer, Integer> ratedStories = conn.getRated((int) userId);

    ArrayList<Integer> frontendStories = new ArrayList<>();

    /* Find the stories already present in the recommendations list at front end
     * These stories should not be recommended again*/
    if (add.equals("true")) {
        frontendStories = conn.getStoriesInFrontendArray((int) userId);
    }
    int ranking = 1;
    Random rand = new Random();
    int randomDislikedRanking = rand.nextInt(6) + 5;

    ArrayList<DatabaseInsertObject> itemsToBeInserted = new ArrayList<>();
    ArrayList<Long> idsToBeInserted = new ArrayList<>();
    for (RecommendedItem recommendation : recommendations) {
        /* To get a story outside of the users preferences, finds the least recommended story */
        if (randomDislikedRanking == ranking) {
            /*Make sure the false recommendation is not already in the front end array or already among the top ten recommendation (may happen if the user doesn't have many not seen/not rated stories left) */
            for (int i = 1; i < recommendations.size(); i++) {
                long dislikedStoryId = recommendations.get(recommendations.size() - i).getItemID();
                if (!frontendStories.contains((int) dislikedStoryId)
                        && !idsToBeInserted.contains(dislikedStoryId)
                        && ratedStories.get((int) dislikedStoryId) == null) {
                    itemsToBeInserted.add(new DatabaseInsertObject((int) userId, "DF." + dislikedStoryId,
                            "FalseRecommendation", 1, 0, ranking,
                            recommendations.get(recommendations.size() - i).getValue()));
                    idsToBeInserted.add(dislikedStoryId);
                    System.out.print("False recommend: ");
                    System.out.println(dislikedStoryId);
                    break;
                }
            }
            ranking++;
            if (ranking > 10) {
                break;
            }
            continue;
        }

        /*If the item has not been rated,is not already in the recommendation list at front end or already a false recommendation we insert it*/
        if ((ratedStories.get((int) recommendation.getItemID()) == null)
                && !frontendStories.contains((int) recommendation.getItemID())
                && !idsToBeInserted.contains(recommendation.getItemID())) {
            /*Get the 30 items that had most influence on the recommendation*/
            List<RecommendedItem> becauseItems = recommender.recommendedBecause(userId,
                    recommendation.getItemID(), 30);
            int counter = 1;
            ArrayList<RecommendedItem> explanationItems = new ArrayList<>();
            for (RecommendedItem because : becauseItems) {
                /*Add story to explanation if this story has been rated and the rating is good*/
                if (!explanationItems.contains(because) && ratedStories.get((int) because.getItemID()) != null
                        && ratedStories.get((int) because.getItemID()) > 2) {
                    explanationItems.add(because);
                    counter++;
                }
                if (counter > 3) {
                    break;
                }
            }
            /*Gets the titles of the explanation-stories and creates a string*/
            String explanation = conn.createExplanation(explanationItems);
            itemsToBeInserted.add(new DatabaseInsertObject((int) userId, "DF." + recommendation.getItemID(),
                    explanation, 0, 0, ranking, recommendation.getValue()));
            idsToBeInserted.add(recommendation.getItemID());
            System.out.println(recommendation);
            ranking++;
        }
        /*When we got 10 new recommendations, we're happy*/
        if (ranking > 10) {
            break;
        }
    }
    this.recommendations = recommendations;
    /*Delete the current recommendations stored in stored_story that has not been seen by the user*/
    conn.deleteRecommendations((int) userId);

    /*Insert the 10 items we found*/
    conn.insertUpdateRecommendValues(itemsToBeInserted);

    /*Drop our temporary view*/
    conn.dropView();
    conn.closeConnection();

}