前言
昨天使用Mohout推荐引擎实现了用户的协同过滤算法,今天使用昨天实现的算法计算一下推荐的准确率以及查全率,查准率。
算法评判标准:召回率(recall)与查准率(precision)
A:检索到的,相关的 (搜到的也想要的)
B:未检索到的,但是相关的 (没搜到,然而实际上想要的)
C:检索到的,但是不相关的 (搜到的但没用的)
D:未检索到的,也不相关的 (没搜到也没用的)
被检索到的越多越好,这是追求“查全率”,即A/(A+B),越大越好。
被检索到的,越相关的越多越好,不相关的越少越好,这是追求“查准率”,即A/(A+C),越大越好。
在大规模数据集合中,这两个指标是相互制约的。当希望索引出更多的数据的时候,查准率就会下降,当希望索引更准确的时候,会索引更少的数据。
/**
*、获取推荐的准确率和召回率
* @param ModelFileName
* @throws IOException
* @throws TasteException
*/
public static void IRStatistics(String ModelFileName) throws IOException, TasteException {
//准备数据
DataModel dataModel = new FileDataModel(new File(ModelFileName));//构造数据模型
RecommenderIRStatsEvaluator statsEvaluator = new GenericRecommenderIRStatsEvaluator();
RecommenderBuilder recommenderBuilder = new RecommenderBuilder() {
@Override
public Recommender buildRecommender(DataModel model) throws TasteException {
UserSimilarity similarity = new PearsonCorrelationSimilarity(model);
UserNeighborhood neighborhood = new NearestNUserNeighborhood(4, similarity, model);
return new GenericUserBasedRecommender(model, neighborhood, similarity);
}
};
// 计算推荐4个结果时的查准率和召回率
//使用评估器,并设定评估期的参数
//4表示"precision and recall at 4"即相当于推荐top4,然后在top-4的推荐上计算准确率和召回率
IRStatistics stats = statsEvaluator.evaluate(recommenderBuilder, null, dataModel, null, 4, GenericRecommenderIRStatsEvaluator.CHOOSE_THRESHOLD, 1.0);
System.out.println(stats.getPrecision());
System.out.println(stats.getRecall());
}
评估准确率
/**
*评估推荐模型
* @param ModelFileName
* @throws IOException
* @throws TasteException
*/
public static void Evaluator(String ModelFileName) throws IOException, TasteException {
//准备数据
DataModel dataModel = new FileDataModel(new File(ModelFileName));//构造数据模型
//推荐评估,使用均方根
//RecommenderEvaluator evaluator = new RMSRecommenderEvaluator();
//推荐评估,使用平均差值
RecommenderEvaluator evaluator = new AverageAbsoluteDifferenceRecommenderEvaluator();
RecommenderBuilder builder = new RecommenderBuilder() {
@Override
public Recommender buildRecommender(DataModel dataModel) throws TasteException {
UserSimilarity similarity = new PearsonCorrelationSimilarity(dataModel);
UserNeighborhood neighborhood = new NearestNUserNeighborhood(2, similarity, dataModel);
return new GenericUserBasedRecommender(dataModel, neighborhood, similarity);
}
};
// 用70%的数据用作训练,剩下的30%用来测试
double score = evaluator.evaluate(builder, null, dataModel, 0.7, 1.0);
//最后得出的评估值越小,说明推荐结果越好
System.out.println(score);
}
看起来用户——标签数据集的推荐效果要好一些。