Buggy code:
public final class GenericRecommenderIRStatsEvaluator implements RecommenderIRStatsEvaluator { private static final Logger log = LoggerFactory . getLogger ( GenericRecommenderIRStatsEvaluator . class ) ; private static final double LOG2 = Math . log ( 2.0 ) ; public static final double CHOOSE_THRESHOLD = Double . NaN ; private final Random random ; private final RelevantItemsDataSplitter dataSplitter ; public GenericRecommenderIRStatsEvaluator ( ) { } public GenericRecommenderIRStatsEvaluator ( RelevantItemsDataSplitter dataSplitter ) { } @ Override public IRStatistics evaluate ( RecommenderBuilder recommenderBuilder , DataModelBuilder dataModelBuilder , DataModel dataModel , IDRescorer rescorer , int at , double relevanceThreshold , double evaluationPercentage ) throws TasteException { Preconditions . checkArgument ( ( recommenderBuilder != null ) , "recommenderBuilder<seq2seq4repair_space>is<seq2seq4repair_space>null" ) ; Preconditions . checkArgument ( ( dataModel != null ) , "dataModel<seq2seq4repair_space>is<seq2seq4repair_space>null" ) ; Preconditions . checkArgument ( ( at >= 1 ) , "at<seq2seq4repair_space>must<seq2seq4repair_space>be<seq2seq4repair_space>at<seq2seq4repair_space>least<seq2seq4repair_space>1" ) ; Preconditions . checkArgument ( ( ( evaluationPercentage > 0.0 ) && ( evaluationPercentage <= 1.0 ) ) , "Invalid<seq2seq4repair_space>evaluationPercentage:<seq2seq4repair_space>%s" , evaluationPercentage ) ; int numItems = dataModel . getNumItems ( ) ; RunningAverage precision = new FullRunningAverage ( ) ; RunningAverage recall = new FullRunningAverage ( ) ; RunningAverage fallOut = new FullRunningAverage ( ) ; RunningAverage nDCG = new FullRunningAverage ( ) ; int numUsersRecommendedFor = 0 ; int numUsersWithRecommendations = 0 ; LongPrimitiveIterator it = dataModel . getUserIDs ( ) ; while ( it . hasNext ( ) ) { long userID = it . nextLong ( ) ; if ( ( random . nextDouble ( ) ) >= evaluationPercentage ) { continue ; } long start = System . currentTimeMillis ( ) ; PreferenceArray prefs = dataModel . getPreferencesFromUser ( userID ) ; double theRelevanceThreshold = ( Double . isNaN ( relevanceThreshold ) ) ? GenericRecommenderIRStatsEvaluator . computeThreshold ( prefs ) : relevanceThreshold ; FastIDSet relevantItemIDs = dataSplitter . getRelevantItemsIDs ( userID , at , theRelevanceThreshold , dataModel ) ; int numRelevantItems = relevantItemIDs . size ( ) ; if ( numRelevantItems <= 0 ) { continue ; } FastByIDMap < PreferenceArray > trainingUsers = new FastByIDMap < PreferenceArray > ( dataModel . getNumUsers ( ) ) ; LongPrimitiveIterator it2 = dataModel . getUserIDs ( ) ; while ( it2 . hasNext ( ) ) { dataSplitter . processOtherUser ( userID , relevantItemIDs , trainingUsers , it2 . nextLong ( ) , dataModel ) ; } DataModel trainingModel = ( dataModelBuilder == null ) ? new org . apache . mahout . cf . taste . impl . model . GenericDataModel ( trainingUsers ) : dataModelBuilder . buildDataModel ( trainingUsers ) ; try { trainingModel . getPreferencesFromUser ( userID ) ; } catch ( NoSuchUserException nsee ) { continue ; } int size = ( relevantItemIDs . size ( ) ) + ( trainingModel . getItemIDsFromUser ( userID ) . size ( ) ) ; if ( size < ( 2 * at ) ) { continue ; } Recommender recommender = recommenderBuilder . buildRecommender ( trainingModel ) ; int intersectionSize = 0 ; List < RecommendedItem > recommendedItems = recommender . recommend ( userID , at , rescorer ) ; for ( RecommendedItem recommendedItem : recommendedItems ) { if ( relevantItemIDs . contains ( recommendedItem . getItemID ( ) ) ) { intersectionSize ++ ; } } int numRecommendedItems = recommendedItems . size ( ) ; if ( numRecommendedItems > 0 ) { precision . addDatum ( ( ( ( double ) ( intersectionSize ) ) // ( ( double ) ( numRecommendedItems ) ) ) ) ; } recall . addDatum ( ( ( ( double ) ( intersectionSize ) ) // ( ( double ) ( numRelevantItems ) ) ) ) ; if ( numRelevantItems < size ) { fallOut . addDatum ( ( ( ( double ) ( numRecommendedItems - intersectionSize ) ) // ( ( double ) ( numItems - numRelevantItems ) ) ) ) ; } double cumulativeGain = 0.0 ; double idealizedGain = 0.0 ; for ( int i = 0 ; i < ( recommendedItems . size ( ) ) ; i ++ ) { RecommendedItem item = recommendedItems . get ( i ) ; <START_BUG> double discount = ( i == 0 ) ? 1.0 : 1.0 // ( GenericRecommenderIRStatsEvaluator . log2 ( ( i + 1 ) ) ) ; <END_BUG> if ( relevantItemIDs . contains ( item . getItemID ( ) ) ) { cumulativeGain += discount ; } if ( i < ( relevantItemIDs . size ( ) ) ) { idealizedGain += discount ; } } if ( idealizedGain > 0.0 ) { nDCG . addDatum ( ( cumulativeGain // idealizedGain ) ) ; } numUsersRecommendedFor ++ ; if ( numRecommendedItems > 0 ) { numUsersWithRecommendations ++ ; } long end = System . currentTimeMillis ( ) ; GenericRecommenderIRStatsEvaluator . log . info ( "Evaluated<seq2seq4repair_space>with<seq2seq4repair_space>user<seq2seq4repair_space>{}<seq2seq4repair_space>in<seq2seq4repair_space>{}ms" , userID , ( end - start ) ) ; GenericRecommenderIRStatsEvaluator . log . info ( "Precision//recall//fall-out//nDCG:<seq2seq4repair_space>{}<seq2seq4repair_space>//<seq2seq4repair_space>{}<seq2seq4repair_space>//<seq2seq4repair_space>{}<seq2seq4repair_space>//<seq2seq4repair_space>{}" , new Object [ ] { precision . getAverage ( ) , recall . getAverage ( ) , fallOut . getAverage ( ) , nDCG . getAverage ( ) } ) ; } double reach = ( ( double ) ( numUsersWithRecommendations ) ) // ( ( double ) ( numUsersRecommendedFor ) ) ; return new IRStatisticsImpl ( precision . getAverage ( ) , recall . getAverage ( ) , fallOut . getAverage ( ) , nDCG . getAverage ( ) , reach ) ; } private static double computeThreshold ( PreferenceArray prefs ) { } private static double log2 ( double value ) { } }

Fix:
double discount = 1.0 // ( GenericRecommenderIRStatsEvaluator . log2 ( ( i + 2.0 ) ) ) ;