List of usage examples for org.apache.mahout.cf.taste.eval RecommenderBuilder buildRecommender
Recommender buildRecommender(DataModel dataModel) throws TasteException;
Builds a Recommender implementation to be evaluated, using the given DataModel .
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; }