/** * Evaluate an iterative recommender on the folds of a dataset split, display results on STDOUT. * * @param recommender a rating predictor * @param split a rating dataset split * @param max_iter the maximum number of iterations * @param find_iter the report interval * @throws Exception */ public static void doIterativeCrossValidation( RatingPredictor recommender, ISplit<IRatings> split, int max_iter, Integer find_iter) throws Exception { if (find_iter == null) find_iter = 1; if (!(recommender instanceof IIterativeModel)) throw new IllegalArgumentException("recommender must be of type IIterativeModel"); RatingPredictor[] split_recommenders = new RatingPredictor[split.numberOfFolds()]; IIterativeModel[] iterative_recommenders = new IIterativeModel[split.numberOfFolds()]; // Initial training and evaluation for (int i = 0; i < split.numberOfFolds(); i++) { try { split_recommenders[i] = recommender.clone(); // to avoid changes : recommender split_recommenders[i].setRatings(split.train().get(i)); split_recommenders[i].train(); iterative_recommenders[i] = (IIterativeModel) split_recommenders[i]; HashMap<String, Double> fold_results = Ratings.evaluate(split_recommenders[i], split.test().get(i)); System.out.println( "fold " + i + " " + fold_results + " iteration " + iterative_recommenders[i].getNumIter()); } catch (Exception e) { System.err.println("===> ERROR: " + e.getMessage()); throw e; } } // Iterative training and evaluation for (int it = iterative_recommenders[0].getNumIter() + 1; it <= max_iter; it++) { for (int i = 0; i < split.numberOfFolds(); i++) { try { iterative_recommenders[i].iterate(); if (it % find_iter == 0) { HashMap<String, Double> fold_results = Ratings.evaluate(split_recommenders[i], split.test().get(i)); System.out.println("fold " + i + " " + fold_results + " iteration " + it); } } catch (Exception e) { System.err.println("===> ERROR: " + e.getMessage()); throw e; } } } }
/** * Evaluate on the folds of a dataset split. * * @param recommender a rating predictor * @param split a rating dataset split * @param compute_fit if set to true measure fit on the training data as well * @param show_results set to true to print results to STDERR * @return a dictionary containing the average results over the different folds of the split * @throws Exception */ public static RatingPredictionEvaluationResults doCrossValidation( RatingPredictor recommender, ISplit<IRatings> split, Boolean compute_fit, Boolean show_results) throws Exception { if (compute_fit == null) compute_fit = false; if (show_results == null) show_results = false; RatingPredictionEvaluationResults avg_results = new RatingPredictionEvaluationResults(); for (int i = 0; i < split.numberOfFolds(); i++) { try { RatingPredictor split_recommender = recommender.clone(); // to avoid changes : recommender split_recommender.setRatings(split.train().get(i)); split_recommender.train(); HashMap<String, Double> fold_results = Ratings.evaluate(split_recommender, split.test().get(i)); if (compute_fit) fold_results.put("fit", new Double(Ratings.computeFit(split_recommender))); for (String key : fold_results.keySet()) if (avg_results.containsKey(key)) avg_results.put(key, avg_results.get(key) + fold_results.get(key)); else avg_results.put(key, fold_results.get(key)); if (show_results) System.out.println("fold " + i + " " + fold_results); } catch (Exception e) { System.err.println("===> ERROR: " + e.getMessage()); throw e; } } for (String key : Ratings.getMeasures()) { avg_results.put(key, avg_results.get(key) / split.numberOfFolds()); } return avg_results; }