//Copyright (C) 2011, 2012 Zeno Gantner, Chris Newell
//
//This file is part of MyMediaLite.
//
//MyMediaLite is free software: you can redistribute it and/or modify
//it under the terms of the GNU General Public License as published by
//the Free Software Foundation, either version 3 of the License, or
//(at your option) any later version.
//
//MyMediaLite is distributed in the hope that it will be useful,
//but WITHOUT ANY WARRANTY; without even the implied warranty of
//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
//GNU General Public License for more details.
//
//You should have received a copy of the GNU General Public License
//along with MyMediaLite. If not, see <http://www.gnu.org/licenses/>.
//
package org.mymedialite.eval;
import org.mymedialite.data.IRatings;
import org.mymedialite.ratingprediction.IIncrementalRatingPredictor;
import org.mymedialite.ratingprediction.IRatingPredictor;
/**
* Online evaluation for rating prediction.
* @version 2.03
*/
public class RatingsOnline {
// Prevent instantiation.
private RatingsOnline() {}
/**
* Online evaluation for rating prediction.
*
* Every rating that is tested is added to the training set afterwards.
*
* @param recommender rating predictor
* @param ratings Test cases
* @return a Dictionary containing the evaluation results
*/
public static RatingPredictionEvaluationResults evaluateOnline(IRatingPredictor recommender, IRatings ratings) {
if (recommender == null)
throw new IllegalArgumentException("recommender is null!");
if (ratings == null)
throw new IllegalArgumentException("ratings is null!");
if (!(recommender instanceof IIncrementalRatingPredictor))
throw new IllegalArgumentException("recommender must be of type IIncrementalRatingPredictor");
IIncrementalRatingPredictor incremental_recommender = (IIncrementalRatingPredictor)recommender;
double rmse = 0;
double mae = 0;
double cbd = 0;
// Iterate in random order
for (int index : ratings.randomIndex()) {
double prediction = recommender.predict(ratings.users().get(index), ratings.items().get(index));
double error = prediction - ratings.get(index);
rmse += error * error;
mae += Math.abs(error);
cbd += Ratings.computeCBD(ratings.get(index), prediction, ratings.minRating(), ratings.maxRating());
incremental_recommender.addRating(ratings.users().get(index), ratings.items().get(index), ratings.get(index));
}
mae = mae / ratings.size();
rmse = Math.sqrt(rmse / ratings.size());
cbd = cbd / ratings.size();
RatingPredictionEvaluationResults result = new RatingPredictionEvaluationResults();
result.put("RMSE", rmse);
result.put("MAE", mae);
result.put("NMAE", mae / (recommender.getMaxRating() - recommender.getMinRating()));
result.put("CBD", cbd);
return result;
}
}