Example usage for org.apache.mahout.cf.taste.eval RecommenderBuilder buildRecommender

List of usage examples for org.apache.mahout.cf.taste.eval RecommenderBuilder buildRecommender

Introduction

In this page you can find the example usage for org.apache.mahout.cf.taste.eval RecommenderBuilder buildRecommender.

Prototype

Recommender buildRecommender(DataModel dataModel) throws TasteException;

Source Link

Document

Builds a Recommender implementation to be evaluated, using the given DataModel .

Usage

From source file:com.msiiplab.recsys.rwr.GLRecommenderIRStatsEvaluator.java

License:Apache License

public void predict(RecommenderBuilder recommenderBuilder, List<DataModel> trainingDataModels,
        List<DataModel> testingDataModels, List<File> outputFileList) throws TasteException {

    // num of train/test pair: num of cross validation folds
    int numFolds = trainingDataModels.size();

    for (int i_folds = 0; i_folds < numFolds; i_folds++) {
        DataModel trainDataModel = trainingDataModels.get(i_folds);
        DataModel testDataModel = testingDataModels.get(i_folds);

        // Build recommender
        Recommender recommender = recommenderBuilder.buildRecommender(trainDataModel);

        LongPrimitiveIterator it_item;//from  w w w .  ja va  2 s . c o  m
        FastIDSet allItems = new FastIDSet();
        it_item = trainDataModel.getItemIDs();
        while (it_item.hasNext()) {
            allItems.add(it_item.nextLong());
        }
        it_item = testDataModel.getItemIDs();
        while (it_item.hasNext()) {
            allItems.add(it_item.nextLong());
        }

        if (outputFileList != null) {
            File file = outputFileList.get(i_folds);
            log.info("Writing recommender output to file: " + file.getPath());
            try {
                FileOutputStream out = new FileOutputStream(file);
                LongPrimitiveIterator it_user = testDataModel.getUserIDs();
                while (it_user.hasNext()) {
                    long userID = it_user.nextLong();
                    FastIDSet ratedItems = trainDataModel.getItemIDsFromUser(userID);
                    StringBuilder sb = new StringBuilder();
                    Iterator<Long> it = allItems.iterator();
                    while (it.hasNext()) {
                        long itemID = it.next();
                        if (!ratedItems.contains(itemID)) {
                            float pref = 0;
                            try {
                                pref = recommender.estimatePreference(userID, itemID);
                            } catch (NoSuchItemException e) {
                                pref = Float.NaN;
                            }
                            sb.append(userID + "," + itemID + "," + pref + "\n");
                        }
                    }
                    out.write(sb.toString().getBytes());
                    out.flush();
                }
                out.close();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }
}

From source file:com.msiiplab.recsys.rwr.GLRecommenderIRStatsEvaluator.java

License:Apache License

public GLIRStatisticsImpl evaluate(RecommenderBuilder recommenderBuilder, List<DataModel> trainingDataModels,
        List<DataModel> testingDataModels, IDRescorer rescorer, int at, double relevanceThreshold,
        double evaluationPercentage) throws TasteException {

    Preconditions.checkArgument(recommenderBuilder != null, "recommenderBuilder is null");
    Preconditions.checkArgument(trainingDataModels != null, "trainingDataModels is null");
    Preconditions.checkArgument(testingDataModels != null, "testingDataModels is null");
    Preconditions.checkArgument(testingDataModels.size() == trainingDataModels.size(),
            "trainingDataModels.size must equals testingDataModels.size");
    Preconditions.checkArgument(at >= 1, "at must be at least 1");
    Preconditions.checkArgument(evaluationPercentage > 0.0 && evaluationPercentage <= 1.0,
            "Invalid evaluationPercentage: %s", evaluationPercentage);

    // num of train/test pair: num of cross validation folds
    int numFolds = trainingDataModels.size();

    RunningAverage CrossValidationPrecision = new GLRunningAverage();
    RunningAverage CrossValidationRPrecision = new GLRunningAverage();
    RunningAverage CrossValidationRecall = new GLRunningAverage();
    RunningAverage CrossValidationFallOut = new GLRunningAverage();
    RunningAverage CrossValidationNDCG = new GLRunningAverage();
    RunningAverage CrossValidationRNDCG = new GLRunningAverage();//rating-nDCG
    RunningAverage CrossValidationReach = new GLRunningAverage();
    RunningAverage CrossValidationMacroDOA = new GLRunningAverage();
    RunningAverage CrossValidationMicroDOA = new GLRunningAverage();
    RunningAverage CrossValidationMacroInnerDOA = new GLRunningAverage();
    RunningAverage CrossValidationMicroInnerDOA = new GLRunningAverage();

    for (int i_folds = 0; i_folds < numFolds; i_folds++) {
        log.info("fold {}", i_folds);
        DataModel trainDataModel = trainingDataModels.get(i_folds);
        DataModel testDataModel = testingDataModels.get(i_folds);

        FastIDSet MovieIDs = new FastIDSet();
        LongPrimitiveIterator it_train_temp = trainDataModel.getItemIDs();
        LongPrimitiveIterator it_test_temp = testDataModel.getItemIDs();
        while (it_train_temp.hasNext()) {
            MovieIDs.add(it_train_temp.nextLong());
        }/* ww  w. j  av a  2s . c  o  m*/
        while (it_test_temp.hasNext()) {
            MovieIDs.add(it_test_temp.nextLong());
        }

        int numTrainItems = trainDataModel.getNumItems();
        int numTestItems = testDataModel.getNumItems();
        int numItems = numTestItems + numTrainItems;

        RunningAverage precision = new GLRunningAverage();
        RunningAverage rPrecision = new GLRunningAverage();
        RunningAverage recall = new GLRunningAverage();
        RunningAverage fallOut = new GLRunningAverage();
        RunningAverage nDCG = new GLRunningAverage();
        RunningAverage rNDCG = new GLRunningAverage();
        RunningAverage macroDOA = new GLRunningAverage();
        RunningAverage microDOA1 = new GLRunningAverage();
        RunningAverage microDOA2 = new GLRunningAverage();
        RunningAverage macroInnerDOA = new GLRunningAverage();
        RunningAverage microInnerDOA1 = new GLRunningAverage();
        RunningAverage microInnerDOA2 = new GLRunningAverage();

        int numUsersRecommendedFor = 0;
        int numUsersWithRecommendations = 0;

        long start = System.currentTimeMillis();

        // Build recommender
        Recommender recommender = recommenderBuilder.buildRecommender(trainDataModel);

        LongPrimitiveIterator it_user = testDataModel.getUserIDs();
        while (it_user.hasNext()) {
            long userID = it_user.nextLong();
            log.info("user {}", userID);
            // Use all in testDataModel as relevant
            FastIDSet learnedItemIDs;
            FastIDSet relevantItemIDs;

            try {
                learnedItemIDs = trainDataModel.getItemIDsFromUser(userID);
                relevantItemIDs = testDataModel.getItemIDsFromUser(userID);
            } catch (NoSuchUserException e1) {
                continue;
            }

            // We excluded zero relevant items situation
            int numRelevantItems = relevantItemIDs.size();
            if (numRelevantItems <= 0) {
                continue;
            }

            // We excluded all prefs for the user that has no pref record in
            // training set
            try {
                trainDataModel.getPreferencesFromUser(userID);
            } catch (NoSuchUserException nsee) {
                continue; // Oops we excluded all prefs for the user -- just
                          // move on
            }

            // Recommend items
            List<RecommendedItem> recommendedItems = recommender.recommend(userID, at, rescorer);
            List<RecommendedItem> recommendedItemsAtRelNum = recommender.recommend(userID, numRelevantItems,
                    rescorer);

            PreferenceArray userPreferences = testDataModel.getPreferencesFromUser(userID);
            FastByIDMap<Preference> userPreferenceMap = getPrefereceMap(userPreferences);
            userPreferences.sortByValueReversed();

            // relevantItemIDsAtN only consider top N items as relevant items
            FastIDSet relevantItemIDsAtN = new FastIDSet();
            Iterator<Preference> it_pref = userPreferences.iterator();
            int num_pref = 0;
            while (it_pref.hasNext()) {
                relevantItemIDsAtN.add(it_pref.next().getItemID());
                num_pref++;
                if (num_pref >= at) {
                    break;
                }
            }

            // Compute intersection between recommended items and relevant
            // items
            int intersectionSize = 0;
            int numRecommendedItems = recommendedItems.size();
            for (RecommendedItem recommendedItem : recommendedItems) {
                if (relevantItemIDs.contains(recommendedItem.getItemID())) {
                    intersectionSize++;
                }
            }

            // Precision
            double prec = 0;
            if (numRecommendedItems > 0) {
                prec = (double) intersectionSize / (double) numRecommendedItems;
            }
            precision.addDatum(prec);
            log.info("Precision for user {} is {}", userID, prec);

            // Recall
            double rec = (double) intersectionSize / (double) numRelevantItems;
            recall.addDatum(rec);
            log.info("Recall for user {} is {}", userID, rec);

            // R-precision
            double rprec = 0;
            int intersectionSizeAtRelNum = 0;
            int numRecommendedItemsAtRelNum = recommendedItemsAtRelNum.size();
            for (RecommendedItem recommendedItem : recommendedItemsAtRelNum) {
                if (relevantItemIDs.contains(recommendedItem.getItemID())) {
                    intersectionSizeAtRelNum++;
                }
            }
            if (numRecommendedItemsAtRelNum > 0) {
                rprec = (double) intersectionSizeAtRelNum / (double) numRelevantItems;
            }
            rPrecision.addDatum(rprec);
            log.info("RPrecision for user {} is {}", userID, rprec);

            double F1 = 0;
            if (prec + rec > 0) {
                F1 = 2 * prec * rec / (prec + rec);
            }
            log.info("F1 for user {} is {}", userID, F1);

            // Fall-out
            double fall = 0;
            int size = numRelevantItems + trainDataModel.getItemIDsFromUser(userID).size();
            if (numRelevantItems < size) {
                fall = (double) (numRecommendedItems - intersectionSize)
                        / (double) (numItems - numRelevantItems);
            }
            fallOut.addDatum(fall);
            log.info("Fallout for user {} is {}", userID, fall);

            // nDCG
            // In computing, assume relevant IDs have relevance ${rating} and others
            // 0
            PreferenceArray userPredictions = getPreferenceArray(recommendedItems, userID);
            double userNDCG = computeNDCG(userPreferences, userPredictions, relevantItemIDs, userPreferenceMap,
                    at);
            double userRNDCG = computeRNDCG(userPreferences, userPredictions, relevantItemIDs,
                    userPreferenceMap, at);
            nDCG.addDatum(userNDCG);
            rNDCG.addDatum(userRNDCG);
            log.info("NDCG for user {} is {}", userID, userNDCG);
            log.info("RNDCG for user {} is {}", userID, userRNDCG);

            // Reach
            numUsersRecommendedFor++;
            if (numRecommendedItems > 0) {
                numUsersWithRecommendations++;
            }

            // DOA
            // [Siegel and Castellan, 1988] and [Gori and Pucci, 2007]
            // LongPrimitiveIterator it_movies = MovieIDs.iterator();
            LongPrimitiveIterator it_movies = trainDataModel.getItemIDs();
            long numNW = 0;
            long sumCheckOrder = 0;
            while (it_movies.hasNext()) {
                long itemID = it_movies.nextLong();
                if (!learnedItemIDs.contains(itemID) && !relevantItemIDs.contains(itemID)) {
                    // itemID is in NW_{u_i}
                    numNW++;

                    LongPrimitiveIterator it_test = relevantItemIDs.iterator();
                    while (it_test.hasNext()) {
                        long testItemID = it_test.nextLong();
                        float itemPref = 0;
                        float testItemPref = 0;
                        try {
                            itemPref = recommender.estimatePreference(userID, itemID);
                        } catch (NoSuchItemException e) {
                        }
                        try {
                            testItemPref = recommender.estimatePreference(userID, testItemID);
                        } catch (NoSuchItemException e) {
                        }
                        if (itemPref <= testItemPref) {
                            sumCheckOrder++;
                        }
                    }
                }
            }
            if (numNW > 0 && relevantItemIDs.size() > 0) {
                macroDOA.addDatum((double) sumCheckOrder / (double) (relevantItemIDs.size() * numNW));
                microDOA1.addDatum((double) sumCheckOrder);
                microDOA2.addDatum((double) (relevantItemIDs.size() * numNW));
            }
            //            log.info(
            //                  "sumCheckOrder / (numNW * numRelevant) = {} / ({} * {})",
            //                  sumCheckOrder, numNW, relevantItemIDs.size());

            // InnerDOA: only check the agreement of order in test set
            LongPrimitiveIterator it_test1 = relevantItemIDs.iterator();
            long sumCheckInnerOrder = 0;
            long sumAll = 0;
            while (it_test1.hasNext()) {
                long itemID1 = it_test1.nextLong();
                LongPrimitiveIterator it_test2 = relevantItemIDs.iterator();
                while (it_test2.hasNext()) {
                    long itemID2 = it_test2.nextLong();
                    if (itemID1 != itemID2) {
                        try {
                            float pref_v1 = testDataModel.getPreferenceValue(userID, itemID1);
                            float pref_v2 = testDataModel.getPreferenceValue(userID, itemID2);
                            float predict_v1 = recommender.estimatePreference(userID, itemID1);
                            float predict_v2 = recommender.estimatePreference(userID, itemID2);
                            if ((pref_v1 >= pref_v2 && predict_v1 >= predict_v2)
                                    || (pref_v1 <= pref_v2 && predict_v1 <= predict_v2)) {
                                sumCheckInnerOrder++;
                            }
                            sumAll++;
                        } catch (NoSuchItemException e) {
                            // do nothing, just ignore
                        }
                    }
                }
            }
            if (relevantItemIDs.size() > 1) {
                macroInnerDOA.addDatum((double) sumCheckInnerOrder / (double) sumAll);
                microInnerDOA1.addDatum((double) sumCheckInnerOrder);
                microInnerDOA2.addDatum((double) sumAll);
            }
            //            log.info(
            //                  "sumCheckInnerOrder / (|T| * (|T|-1) ) = {} / ({} * {}) = ",
            //                  sumCheckInnerOrder, relevantItemIDs.size(), relevantItemIDs.size()-1);
        }

        long end = System.currentTimeMillis();

        CrossValidationPrecision.addDatum(precision.getAverage());
        CrossValidationRPrecision.addDatum(rPrecision.getAverage());
        CrossValidationRecall.addDatum(recall.getAverage());
        CrossValidationFallOut.addDatum(fallOut.getAverage());
        CrossValidationNDCG.addDatum(nDCG.getAverage());
        CrossValidationRNDCG.addDatum(rNDCG.getAverage());
        CrossValidationReach.addDatum((double) numUsersWithRecommendations / (double) numUsersRecommendedFor);
        CrossValidationMacroDOA.addDatum(macroDOA.getAverage());
        CrossValidationMicroDOA.addDatum(microDOA1.getAverage() / microDOA2.getAverage());
        CrossValidationMacroInnerDOA.addDatum(macroInnerDOA.getAverage());
        CrossValidationMicroInnerDOA.addDatum(microInnerDOA1.getAverage() / microInnerDOA2.getAverage());

        log.info("Evaluated with training/testing set # {} in {}ms", i_folds, end - start);
        System.out.printf("Evaluated with training/testing set # %d in %d ms \n", i_folds, end - start);

        log.info(
                "Precision/R-Precision/recall/fall-out/nDCG/rNDCG/reach/macroDOA/microDOA/macroInnerDOA/microInnerDOA: {} / {} / {} / {} / {} / {} / {} / {} / {} / {} / {}",
                precision.getAverage(), rPrecision.getAverage(), recall.getAverage(), fallOut.getAverage(),
                nDCG.getAverage(), rNDCG.getAverage(),
                (double) numUsersWithRecommendations / (double) numUsersRecommendedFor, macroDOA.getAverage(),
                microDOA1.getAverage() / microDOA2.getAverage(), macroInnerDOA.getAverage(),
                microInnerDOA1.getAverage() / microInnerDOA2.getAverage());
        System.out.printf(
                "Precision/R-Precision/recall/fall-out/nDCG/rNDCG/reach/macroDOA/microDOA/macroInnerDOA/microInnerDOA: %f / %f / %f / %f / %f / %f / %f / %f / %f / %f / %f \n",
                precision.getAverage(), rPrecision.getAverage(), recall.getAverage(), fallOut.getAverage(),
                nDCG.getAverage(), rNDCG.getAverage(),
                (double) numUsersWithRecommendations / (double) numUsersRecommendedFor, macroDOA.getAverage(),
                microDOA1.getAverage() / microDOA2.getAverage(), macroInnerDOA.getAverage(),
                microInnerDOA1.getAverage() / microInnerDOA2.getAverage());

    }

    log.info(
            "Cross Validation Precision/R-Precision/recall/fall-out/nDCG/rNDCG/reach/macroDOA/microDOA: {} / {} / {} / {} / {} / {} / {} / {} / {} / {} / {}",
            CrossValidationPrecision.getAverage(), CrossValidationRPrecision.getAverage(),
            CrossValidationRecall.getAverage(), CrossValidationFallOut.getAverage(),
            CrossValidationNDCG.getAverage(), CrossValidationRNDCG.getAverage(),
            CrossValidationReach.getAverage(), CrossValidationMacroDOA.getAverage(),
            CrossValidationMicroDOA.getAverage(), CrossValidationMacroInnerDOA.getAverage(),
            CrossValidationMicroInnerDOA.getAverage());
    System.out.printf(
            "Cross Validation: \nPrecision/R-Precision/recall/fall-out/nDCG/rNDCG/reach/macroDOA/microDOA: %f / %f / %f / %f / %f / %f / %f / %f / %f / %f / %f\n",
            CrossValidationPrecision.getAverage(), CrossValidationRPrecision.getAverage(),
            CrossValidationRecall.getAverage(), CrossValidationFallOut.getAverage(),
            CrossValidationNDCG.getAverage(), CrossValidationRNDCG.getAverage(),
            CrossValidationReach.getAverage(), CrossValidationMacroDOA.getAverage(),
            CrossValidationMicroDOA.getAverage(), CrossValidationMacroInnerDOA.getAverage(),
            CrossValidationMicroInnerDOA.getAverage());

    return new GLIRStatisticsImpl(CrossValidationPrecision.getAverage(), CrossValidationRPrecision.getAverage(),
            CrossValidationRecall.getAverage(), CrossValidationFallOut.getAverage(),
            CrossValidationNDCG.getAverage(), CrossValidationRNDCG.getAverage(),
            CrossValidationReach.getAverage(), CrossValidationMacroDOA.getAverage(),
            CrossValidationMicroDOA.getAverage(), CrossValidationMacroInnerDOA.getAverage(),
            CrossValidationMicroInnerDOA.getAverage());
}

From source file:com.msiiplab.recsys.rwr.ParallelGLRecommenderIRStatsEvaluator.java

License:Apache License

@Override
public GLIRStatisticsImpl evaluate(RecommenderBuilder recommenderBuilder, List<DataModel> trainingDataModels,
        List<DataModel> testingDataModels, IDRescorer rescorer, int at, double relevanceThreshold,
        double evaluationPercentage) throws TasteException {

    Preconditions.checkArgument(recommenderBuilder != null, "recommenderBuilder is null");
    Preconditions.checkArgument(trainingDataModels != null, "trainingDataModels is null");
    Preconditions.checkArgument(testingDataModels != null, "testingDataModels is null");
    Preconditions.checkArgument(testingDataModels.size() == trainingDataModels.size(),
            "trainingDataModels.size must equals testingDataModels.size");
    Preconditions.checkArgument(at >= 1, "at must be at least 1");
    Preconditions.checkArgument(evaluationPercentage > 0.0 && evaluationPercentage <= 1.0,
            "Invalid evaluationPercentage: %s", evaluationPercentage);

    // num of train/test pair: num of cross validation folds
    int numFolds = trainingDataModels.size();

    RunningAverage CrossValidationPrecision = new GLRunningAverage();
    RunningAverage CrossValidationRPrecision = new GLRunningAverage();
    RunningAverage CrossValidationRecall = new GLRunningAverage();
    RunningAverage CrossValidationFallOut = new GLRunningAverage();
    RunningAverage CrossValidationNDCG = new GLRunningAverage();
    RunningAverage CrossValidationRNDCG = new GLRunningAverage();//rating-nDCG
    RunningAverage CrossValidationReach = new GLRunningAverage();
    RunningAverage CrossValidationMacroDOA = new GLRunningAverage();
    RunningAverage CrossValidationMicroDOA = new GLRunningAverage();
    RunningAverage CrossValidationMacroInnerDOA = new GLRunningAverage();
    RunningAverage CrossValidationMicroInnerDOA = new GLRunningAverage();

    for (int i_folds = 0; i_folds < numFolds; i_folds++) {

        log.info("fold {}", i_folds);
        DataModel trainDataModel = trainingDataModels.get(i_folds);
        DataModel testDataModel = testingDataModels.get(i_folds);

        FastIDSet MovieIDs = new FastIDSet();
        LongPrimitiveIterator it_train_temp = trainDataModel.getItemIDs();
        LongPrimitiveIterator it_test_temp = testDataModel.getItemIDs();
        while (it_train_temp.hasNext()) {
            MovieIDs.add(it_train_temp.nextLong());
        }//from w w w .j a  v a  2 s.  co  m
        while (it_test_temp.hasNext()) {
            MovieIDs.add(it_test_temp.nextLong());
        }

        int numTrainItems = trainDataModel.getNumItems();
        int numTestItems = testDataModel.getNumItems();
        int numItems = numTestItems + numTrainItems;

        RunningAverage precision = new GLRunningAverage();
        RunningAverage rPrecision = new GLRunningAverage();
        RunningAverage recall = new GLRunningAverage();
        RunningAverage fallOut = new GLRunningAverage();
        RunningAverage nDCG = new GLRunningAverage();
        RunningAverage rNDCG = new GLRunningAverage();
        RunningAverage macroDOA = new GLRunningAverage();
        RunningAverage microDOA1 = new GLRunningAverage();
        RunningAverage microDOA2 = new GLRunningAverage();
        RunningAverage macroInnerDOA = new GLRunningAverage();
        RunningAverage microInnerDOA1 = new GLRunningAverage();
        RunningAverage microInnerDOA2 = new GLRunningAverage();

        int numUsersRecommendedFor = 0;
        int numUsersWithRecommendations = 0;

        long start = System.currentTimeMillis();

        // Build recommender
        Recommender recommender = recommenderBuilder.buildRecommender(trainDataModel);

        // Futures
        ArrayList<Future<Integer>> futureList = new ArrayList<Future<Integer>>();

        int N_CPUS = Runtime.getRuntime().availableProcessors();
        ExecutorService pool = Executors.newFixedThreadPool(N_CPUS - 1);
        // ExecutorService pool = Executors.newFixedThreadPool(1);

        LongPrimitiveIterator it_user = testDataModel.getUserIDs();
        while (it_user.hasNext()) {
            long userID = it_user.nextLong();

            Future<Integer> future = pool.submit(new Eval(precision, rPrecision, recall, fallOut, nDCG, rNDCG,
                    macroDOA, microDOA1, microDOA2, macroInnerDOA, microInnerDOA1, microInnerDOA2,
                    trainDataModel, testDataModel, userID, recommender, at, rescorer, numItems));
            futureList.add(future);
        }

        for (Future<Integer> future : futureList) {
            numUsersRecommendedFor++;
            try {
                if (future.get() == 1) {
                    numUsersWithRecommendations++;
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (ExecutionException e) {
                e.printStackTrace();
                e.getCause().printStackTrace();
                System.exit(1);
            }
        }

        pool.shutdown();

        long end = System.currentTimeMillis();

        CrossValidationPrecision.addDatum(precision.getAverage());
        CrossValidationRPrecision.addDatum(rPrecision.getAverage());
        CrossValidationRecall.addDatum(recall.getAverage());
        CrossValidationFallOut.addDatum(fallOut.getAverage());
        CrossValidationNDCG.addDatum(nDCG.getAverage());
        CrossValidationRNDCG.addDatum(rNDCG.getAverage());
        CrossValidationReach.addDatum((double) numUsersWithRecommendations / (double) numUsersRecommendedFor);
        CrossValidationMacroDOA.addDatum(macroDOA.getAverage());
        CrossValidationMicroDOA.addDatum(microDOA1.getAverage() / microDOA2.getAverage());
        CrossValidationMacroInnerDOA.addDatum(macroInnerDOA.getAverage());
        CrossValidationMicroInnerDOA.addDatum(microInnerDOA1.getAverage() / microInnerDOA2.getAverage());

        log.info("Evaluated with training/testing set # {} in {}ms", i_folds, end - start);
        System.out.printf("Evaluated with training/testing set # %d in %d ms \n", i_folds, end - start);

        log.info(
                "Precision/R-Precision/recall/fall-out/nDCG/rNDCG/reach/macroDOA/microDOA/macroInnerDOA/microInnerDOA: {} / {} / {} / {} / {} / {} / {} / {} / {} / {} / {}",
                precision.getAverage(), rPrecision.getAverage(), recall.getAverage(), fallOut.getAverage(),
                nDCG.getAverage(), rNDCG.getAverage(),
                (double) numUsersWithRecommendations / (double) numUsersRecommendedFor, macroDOA.getAverage(),
                microDOA1.getAverage() / microDOA2.getAverage(), macroInnerDOA.getAverage(),
                microInnerDOA1.getAverage() / microInnerDOA2.getAverage());
        System.out.printf(
                "Precision/R-Precision/recall/fall-out/nDCG/rNDCG/reach/macroDOA/microDOA/macroInnerDOA/microInnerDOA: %f / %f / %f / %f / %f / %f / %f / %f / %f / %f / %f \n",
                precision.getAverage(), rPrecision.getAverage(), recall.getAverage(), fallOut.getAverage(),
                nDCG.getAverage(), rNDCG.getAverage(),
                (double) numUsersWithRecommendations / (double) numUsersRecommendedFor, macroDOA.getAverage(),
                microDOA1.getAverage() / microDOA2.getAverage(), macroInnerDOA.getAverage(),
                microInnerDOA1.getAverage() / microInnerDOA2.getAverage());

    }

    log.info(
            "Cross Validation Precision/R-Precision/recall/fall-out/nDCG/rNDCG/reach/macroDOA/microDOA: {} / {} / {} / {} / {} / {} / {} / {} / {} / {} / {}",
            CrossValidationPrecision.getAverage(), CrossValidationRPrecision.getAverage(),
            CrossValidationRecall.getAverage(), CrossValidationFallOut.getAverage(),
            CrossValidationNDCG.getAverage(), CrossValidationRNDCG.getAverage(),
            CrossValidationReach.getAverage(), CrossValidationMacroDOA.getAverage(),
            CrossValidationMicroDOA.getAverage(), CrossValidationMacroInnerDOA.getAverage(),
            CrossValidationMicroInnerDOA.getAverage());
    System.out.printf(
            "Cross Validation: \nPrecision/R-Precision/recall/fall-out/nDCG/rNDCG/reach/macroDOA/microDOA: %f / %f / %f / %f / %f / %f / %f / %f / %f / %f / %f\n",
            CrossValidationPrecision.getAverage(), CrossValidationRPrecision.getAverage(),
            CrossValidationRecall.getAverage(), CrossValidationFallOut.getAverage(),
            CrossValidationNDCG.getAverage(), CrossValidationRNDCG.getAverage(),
            CrossValidationReach.getAverage(), CrossValidationMacroDOA.getAverage(),
            CrossValidationMicroDOA.getAverage(), CrossValidationMacroInnerDOA.getAverage(),
            CrossValidationMicroInnerDOA.getAverage());

    return new GLIRStatisticsImpl(CrossValidationPrecision.getAverage(), CrossValidationRPrecision.getAverage(),
            CrossValidationRecall.getAverage(), CrossValidationFallOut.getAverage(),
            CrossValidationNDCG.getAverage(), CrossValidationRNDCG.getAverage(),
            CrossValidationReach.getAverage(), CrossValidationMacroDOA.getAverage(),
            CrossValidationMicroDOA.getAverage(), CrossValidationMacroInnerDOA.getAverage(),
            CrossValidationMicroInnerDOA.getAverage());
}

From source file:lib.eval.AbstractRecommenderEvaluator.java

License:Apache License

@Override
public double evaluate(RecommenderBuilder recommenderBuilder, DataModelBuilder dataModelBuilder,
        DataModel dataModel, double trainingPercentage, double evaluationPercentage) throws TasteException {
    Preconditions.checkArgument(recommenderBuilder != null, "recommenderBuilder is null");
    Preconditions.checkArgument(dataModel != null, "dataModel is null");
    Preconditions.checkArgument(trainingPercentage >= 0.0 && trainingPercentage <= 1.0,
            "Invalid trainingPercentage: " + trainingPercentage);
    Preconditions.checkArgument(evaluationPercentage >= 0.0 && evaluationPercentage <= 1.0,
            "Invalid evaluationPercentage: " + evaluationPercentage);

    log.info("Beginning evaluation using {} of {}", trainingPercentage, dataModel);

    int numUsers = dataModel.getNumUsers();
    FastByIDMap<PreferenceArray> trainingUsers = new FastByIDMap<PreferenceArray>(
            1 + (int) (evaluationPercentage * numUsers));
    FastByIDMap<PreferenceArray> testUserPrefs = new FastByIDMap<PreferenceArray>(
            1 + (int) (evaluationPercentage * numUsers));

    LongPrimitiveIterator it = dataModel.getUserIDs();
    while (it.hasNext()) {
        long userID = it.nextLong();
        if (random.nextDouble() < evaluationPercentage) {
            processOneUser(trainingPercentage, trainingUsers, testUserPrefs, userID, dataModel);
        } else { //this user will not be used for evaluation so use all its preferences in training
            PreferenceArray trainingPrefs = dataModel.getPreferencesFromUser(userID);
            trainingUsers.put(userID, trainingPrefs);
        }/*from   ww  w.  ja  v  a2  s. c  o  m*/
    }

    DataModel trainingModel = dataModelBuilder == null ? new GenericDataModel(trainingUsers)
            : dataModelBuilder.buildDataModel(trainingUsers);

    Recommender recommender = recommenderBuilder.buildRecommender(trainingModel);

    double result = getEvaluation(testUserPrefs, recommender);
    log.info("Evaluation result: {}", result);
    return result;
}

From source file:norbert.mynemo.core.evaluation.PersonnalRecommenderEvaluator.java

License:Apache License

/**
 * If the exhaustive evaluation is off, the training percentage behave normally. If the exhaustive
 * evaluation is on, then the training percentage have two different behaviors:
 * <ul>/*  w w w  .jav  a 2 s . c  o m*/
 * <li>percentage < 0.5: percentage behave normally, the evaluation is not exhaustive.</li>
 * <li>
 * <p>
 * 0.5 <= percentage: the preferences of the target user are split in several test sets. Each set
 * contains approximately the same number of user preferences. For example, if
 * <code>percentage=1</code>, then the number of set equals the number of preference of the target
 * user, each set containing one preference. If <code>percentage=0.5</code>, then two sets are
 * built, each set contains half of the preferences. If <code>percentage=0.9</code>, then ten sets
 * are built, each set contains one tenth of the preferences. Then, each set is tested as if the
 * evaluation is not exhaustive.
 * </p>
 * <p>
 * Thus, <code>1</code> provides the most precise result, but the computation may be intensive.
 * </p>
 * </li>
 * </ul>
 */
@Override
public double evaluate(RecommenderBuilder recommenderBuilder, DataModelBuilder dataModelBuilder,
        DataModel dataModel, double trainingPercentage, double evaluationPercentage) throws TasteException {

    Timer timer = Timer.createStartedTimer();

    // clear the previously computed errors
    errorStats.clear();
    squaredErrorStats.clear();
    predictionRequestNumber = 0;

    // all training preferences except the target user's one
    FastByIDMap<PreferenceArray> baseTrainingPreferences = buildBaseTrainingPreferences(dataModel,
            evaluationPercentage);

    List<List<Preference>> testSets = buildTestSets(dataModel, trainingPercentage);

    // the idea is to generate a recommendation for each preference of the
    // target user.
    for (List<Preference> currentTestSet : testSets) {
        // add the preferences of the target user
        FastByIDMap<PreferenceArray> currentTrainingPreferences = baseTrainingPreferences.clone();
        addUserPreferences(dataModel, currentTrainingPreferences, currentTestSet);

        DataModel currentTrainingModel = (dataModelBuilder == null)
                ? new GenericDataModel(currentTrainingPreferences)
                : dataModelBuilder.buildDataModel(currentTrainingPreferences);

        Recommender currentRecommender = recommenderBuilder.buildRecommender(currentTrainingModel);

        evaluate(currentTrainingModel, currentRecommender, currentTestSet);
    }

    duration = timer.stop().getDuration();

    return getEvaluationSummary(metric);
}

From source file:norbert.mynemo.ui.RecommendCommandParser.java

License:Apache License

private static void execute(RecommenderType algorithm, DataModel dataModel, Long user,
        Integer maximumRecommendations, Optional<Integer> features, Optional<Integer> iterations,
        Optional<Integer> neighbors) throws InterruptedException {

    RecommenderBuilder builder;
    switch (algorithm.getFamily()) {
    case BASIC:/*from  w  w  w .j  a  v a 2  s  .  co  m*/
        builder = new BasicRecommender(new BasicRecommenderConfiguration(algorithm));
        break;

    case ITEM_SIMILARITY_BASED:
        builder = new ItemSimilarityRecommender(new ItemBasedRecommenderConfiguration(algorithm));
        break;

    case SVD_BASED:
        builder = new SvdBasedRecommender(new SvdBasedRecommenderConfiguration(algorithm, features.get(),
                iterations.get(), dataModel, false));
        break;

    case USER_SIMILARITY_BASED:
        builder = new UserSimilarityRecommender(
                new UserBasedRecommenderConfiguration(algorithm, neighbors.get(), dataModel, true));
        break;

    default:
        throw new UnsupportedOperationException("Error: unable to handle the given algorithm."
                + " The recommend command parser must be updated.");
    }

    try {
        for (RecommendedItem recommendation : builder.buildRecommender(dataModel).recommend(user,
                maximumRecommendations)) {

            String incompleteId = Long.toString(recommendation.getItemID());
            String completeId = "tt" + ("0000000" + incompleteId).substring(incompleteId.length());
            Movie movie = new Movie(completeId);
            try {
                System.out.print(movie.getTitle() + " (" + movie.getYear() + ")");
            } catch (IOException e) {
                // can't access to the online service
            }
            System.out.print(" " + Math.round(recommendation.getValue()));
            System.out.println(" " + movie.getImdbUrl());

            Thread.sleep(DELAY_BETWEEN_REQUESTS);

        }
    } catch (TasteException e) {
        throw new IllegalStateException(
                "Error: an unknown error occurs while the recommendation" + " is computed.", e);
    }
}

From source file:recommender.GenericRecommenderIRStatsEvaluatorCustom.java

License:Apache License

@Override
public IRStatistics evaluate(RecommenderBuilder recommenderBuilder, DataModelBuilder dataModelBuilder,
        DataModel dataModel, IDRescorer rescorer, int at, double relevanceThreshold,
        double evaluationPercentage) throws TasteException {

    prop = new Properties();
    try {/*from ww  w  .j  av  a 2s.  co  m*/
        prop.load(GenericRecommenderIRStatsEvaluatorCustom.class.getResourceAsStream("settings.properties"));
    } catch (IOException ex) {
        java.util.logging.Logger.getLogger(GenericRecommenderIRStatsEvaluatorCustom.class.getName())
                .log(Level.SEVERE, null, ex);
    }

    // load settings from MySQL database
    loadSettings();

    Preconditions.checkArgument(recommenderBuilder != null, "recommenderBuilder is null");
    Preconditions.checkArgument(dataModel != null, "dataModel is null");
    Preconditions.checkArgument(at >= 1, "at must be at least 1");
    Preconditions.checkArgument(evaluationPercentage > 0.0 && evaluationPercentage <= 1.0,
            "Invalid evaluationPercentage: " + evaluationPercentage
                    + ". Must be: 0.0 < evaluationPercentage <= 1.0");

    int numItems = dataModel.getNumItems();
    System.out.println("Data model numItems: " + numItems);
    RunningAverage precision = new FullRunningAverage();
    RunningAverage recall = new FullRunningAverage();
    RunningAverage fallOut = new FullRunningAverage();
    RunningAverage nDCG = new FullRunningAverage();
    int numUsersRecommendedFor = 0;
    int numUsersWithRecommendations = 0;

    // map to store diversity ranges => number of users
    HashMap<String, String> map = new HashMap<>();

    LongPrimitiveIterator it = dataModel.getUserIDs();
    while (it.hasNext()) {

        long userID = it.nextLong();

        if (userID == 0) {
            continue;
        }

        // get the top users
        if (!list.contains(userID + "")) {
            continue;
        }

        if (random.nextDouble() >= evaluationPercentage) {
            // Skipped
            continue;
        }

        long start = System.currentTimeMillis();

        PreferenceArray prefs = dataModel.getPreferencesFromUser(userID);
        System.out.println("User preferences: " + prefs);

        // List some most-preferred items that would count as (most) "relevant" results
        double theRelevanceThreshold = 0;//Double.isNaN(relevanceThreshold) ? computeThreshold(prefs) : relevanceThreshold;
        FastIDSet relevantItemIDs = dataSplitter.getRelevantItemsIDs(userID, at, theRelevanceThreshold,
                dataModel);
        System.out.println("Relevant items: " + relevantItemIDs);
        System.out.println("Relevance threshold: " + theRelevanceThreshold);

        int numRelevantItems = relevantItemIDs.size();
        if (numRelevantItems <= 0) {
            continue;
        }

        FastByIDMap<PreferenceArray> trainingUsers = new FastByIDMap<>(dataModel.getNumUsers());
        LongPrimitiveIterator it2 = dataModel.getUserIDs();
        while (it2.hasNext()) {
            dataSplitter.processOtherUser(userID, relevantItemIDs, trainingUsers, it2.nextLong(), dataModel);
        }

        DataModel trainingModel = dataModelBuilder == null ? new GenericDataModel(trainingUsers)
                : dataModelBuilder.buildDataModel(trainingUsers);
        try {
            trainingModel.getPreferencesFromUser(userID);
        } catch (NoSuchUserException nsee) {
            continue; // Oops we excluded all prefs for the user -- just move on
        }

        int size = numRelevantItems + trainingModel.getItemIDsFromUser(userID).size();
        if (size < 2 * at) {
            // Really not enough prefs to meaningfully evaluate this user
            System.out
                    .println("Really not enough prefs (" + size + ") to meaningfully evaluate user: " + userID);
            continue;
        }

        Recommender recommender = recommenderBuilder.buildRecommender(trainingModel);

        int intersectionSize = 0;
        List<RecommendedItem> recommendedItems = recommender.recommend(userID, at, rescorer);
        HashMap<Long, Double> user_preferences = getUserPreferencesList(userID);
        for (RecommendedItem recommendedItem : recommendedItems) {
            double preference = isRelevant(user_preferences, recommendedItem);
            System.out.println("Preference: " + preference);
            if (relevantItemIDs.contains(recommendedItem.getItemID()) || preference != 0) {
                intersectionSize++;
            }
        }

        int numRecommendedItems = recommendedItems.size();

        // Precision
        if (numRecommendedItems > 0) {
            precision.addDatum((double) intersectionSize / (double) numRecommendedItems);
            System.out.println(
                    "intersectionSize: " + intersectionSize + " numRecommendedItems: " + numRecommendedItems);
        }

        // Recall
        recall.addDatum((double) intersectionSize / (double) numRelevantItems);

        // Fall-out
        if (numRelevantItems < size) {
            fallOut.addDatum(
                    (double) (numRecommendedItems - intersectionSize) / (double) (numItems - numRelevantItems));
        }

        // nDCG
        // In computing, assume relevant IDs have relevance 1 and others 0
        double cumulativeGain = 0.0;
        double idealizedGain = 0.0;
        for (int i = 0; i < numRecommendedItems; i++) {
            RecommendedItem item = recommendedItems.get(i);
            double discount = 1.0 / log2(i + 2.0); // Classical formulation says log(i+1), but i is 0-based here
            if (relevantItemIDs.contains(item.getItemID())) {
                cumulativeGain += discount;
            }
            // otherwise we're multiplying discount by relevance 0 so it doesn't do anything

            // Ideally results would be ordered with all relevant ones first, so this theoretical
            // ideal list starts with number of relevant items equal to the total number of relevant items
            if (i < numRelevantItems) {
                idealizedGain += discount;
            }
        }
        if (idealizedGain > 0.0) {
            nDCG.addDatum(cumulativeGain / idealizedGain);
        }

        // Reach
        numUsersRecommendedFor++;
        if (numRecommendedItems > 0) {
            numUsersWithRecommendations++;
        }

        long end = System.currentTimeMillis();

        log.info("Evaluated with user {} in {}ms", userID, end - start);
        log.info("Precision/recall/fall-out/nDCG/reach: {} / {} / {} / {} / {}", precision.getAverage(),
                recall.getAverage(), fallOut.getAverage(), nDCG.getAverage(),
                (double) numUsersWithRecommendations / (double) numUsersRecommendedFor);
        System.out.println("Relevant items: " + numRelevantItems);
        System.out.println("Precision: " + precision.getAverage());
        System.out.println("Recall: " + recall.getAverage());
        System.out.println("Fall-out: " + fallOut.getAverage());
        System.out.println("nDCG: " + nDCG.getAverage());
        System.out.println("Reach: " + (double) numUsersWithRecommendations / (double) numUsersRecommendedFor);
        double diversity = getDiversity(recommendedItems);
        System.out.println("Diversity: " + diversity);
        if (diversity >= 0 && diversity < 0.1) {
            int count = map.get("0-0.1") != null ? Integer.parseInt(map.get("0-0.1")) + 1 : 1;
            map.put("0-0.1", count + "");
        } else if (diversity >= 0.1 && diversity < 0.2) {
            int count = map.get("0.1-0.2") != null ? Integer.parseInt(map.get("0.1-0.2")) + 1 : 1;
            map.put("0.1-0.2", count + "");
        } else if (diversity >= 0.2 && diversity < 0.3) {
            int count = map.get("0.2-0.3") != null ? Integer.parseInt(map.get("0.2-0.3")) + 1 : 1;
            map.put("0.2-0.3", count + "");
        } else if (diversity >= 0.3 && diversity < 0.4) {
            int count = map.get("0.3-0.4") != null ? Integer.parseInt(map.get("0.3-0.4")) + 1 : 1;
            map.put("0.3-0.4", count + "");
        } else if (diversity >= 0.4 && diversity < 0.5) {
            int count = map.get("0.4-0.5") != null ? Integer.parseInt(map.get("0.4-0.5")) + 1 : 1;
            map.put("0.4-0.5", count + "");
        } else if (diversity >= 0.5 && diversity < 0.6) {
            int count = map.get("0.5-0.6") != null ? Integer.parseInt(map.get("0.5-0.6")) + 1 : 1;
            map.put("0.5-0.6", count + "");
        } else if (diversity >= 0.6 && diversity < 0.7) {
            int count = map.get("0.6-0.7") != null ? Integer.parseInt(map.get("0.6-0.7")) + 1 : 1;
            map.put("0.6-0.7", count + "");
        } else if (diversity >= 0.7 && diversity < 0.8) {
            int count = map.get("0.7-0.8") != null ? Integer.parseInt(map.get("0.7-0.8")) + 1 : 1;
            map.put("0.7-0.8", count + "");
        } else if (diversity >= 0.8 && diversity < 0.9) {
            int count = map.get("0.8-0.9") != null ? Integer.parseInt(map.get("0.8-0.9")) + 1 : 1;
            map.put("0.8-0.9", count + "");
        } else if (diversity >= 0.9) {
            int count = map.get("0.9-1") != null ? Integer.parseInt(map.get("0.9-1")) + 1 : 1;
            map.put("0.9-1", count + "");
        }
    }

    JSONObject json = new JSONObject(map);

    writeFile(prop.getProperty("metrics_file"), json.toJSONString());

    return new IRStatisticsImplCustom(precision.getAverage(), recall.getAverage(), fallOut.getAverage(),
            nDCG.getAverage(), (double) numUsersWithRecommendations / (double) numUsersRecommendedFor);
}

From source file:recsys.evaluator.TopKRecommenderEvaluator.java

License:Apache License

@Override
public Double evaluate(RecommenderBuilder recommenderBuilder, DataModelBuilder dataModelBuilder,
        DataModel dataModel, Double trainingPercentage, Double evaluationPercentage) throws TasteException {
    Preconditions.checkNotNull(recommenderBuilder);
    Preconditions.checkNotNull(dataModel);
    Preconditions.checkArgument(trainingPercentage >= 0.0 && trainingPercentage <= 1.0,
            "Invalid trainingPercentage: " + trainingPercentage
                    + ". Must be: 0.0 <= trainingPercentage <= 1.0");
    Preconditions.checkArgument(evaluationPercentage >= 0.0 && evaluationPercentage <= 1.0,
            "Invalid evaluationPercentage: " + evaluationPercentage
                    + ". Must be: 0.0 <= evaluationPercentage <= 1.0");

    log.info("Beginning evaluation using {} of {}", trainingPercentage, dataModel);

    int numUsers = dataModel.getNumUsers();
    FastByIDMap<PreferenceArray> trainingPrefs = new FastByIDMap<PreferenceArray>(
            1 + (int) (evaluationPercentage * numUsers));
    FastByIDMap<PreferenceArray> testPrefs = new FastByIDMap<PreferenceArray>(
            1 + (int) (evaluationPercentage * numUsers));

    IntPrimitiveIterator it = dataModel.getUserIDs();
    while (it.hasNext()) {
        Integer userID = it.nextInt();
        if (random.nextDouble() < evaluationPercentage) {
            splitOneUsersPrefs(trainingPercentage, trainingPrefs, testPrefs, userID, dataModel);
        }/*from w  ww  .  j a  v a 2s  . c om*/
    }

    DataModel trainingModel = dataModelBuilder == null ? new GenericDataModel(trainingPrefs)
            : dataModelBuilder.buildDataModel(trainingPrefs);

    Recommender recommender = recommenderBuilder.buildRecommender(trainingModel);

    Double result = getEvaluation(testPrefs, recommender);
    log.info("Evaluation result: {}", result);
    return result;
}