推荐系统引擎是一个工具,一种回答问题的手段,“对用户来讲什么是最好的推荐?”。最好的推荐系统是心理学的范畴,有人在你做事情之前知道确切的知道你还没有看过的、或者没有任何现象说明你喜欢的一些item,以及你对这些item的喜欢程度。大部分的推荐引擎通过给item评价打分来实现。所以,评价推荐引擎的一种方式是评价它的评估偏好值的质量 — 评价评估偏好和实际偏好的匹配度。
推荐引擎可以通过设置一部分真实数据作为测试数据。这些测试数据偏好在训练集中并不展示偏好值 — 要求推荐系统对这些缺少偏好值的数据作出评估,并比较和实际值的差距。对于推荐系统产生一系列打分是很简单的。例如,计算评估值和实际值之间的平均距离,在这种方法下,分值越低越好。0.0表示非常好的评估 — 评估值和实际值根本没有差距。均方根(root-mean-square)也是一种方法,也是分值越低越好。
Tables | item1 | item2 | item3 |
---|---|---|---|
真实值 | 3.0 | 5.0 | 4.0 |
估计值 | 3.5 | 2.0 | 5.0 |
差值 | .05 | 3.0 | 1.0 |
平均差值 | = (0.5 + 3.0 + 1.0) / 3 = 1.5 | ||
均方差值 | = 根号((0.5 * 0.5 + 3.0 * 3.0 + 1.0 * 1.0)/3) = 18484 |
训练数据与评分示例代码:
package com.xh.recommender;import org.apache.mahout.cf.taste.common.TasteException;
import org.apache.mahout.cf.taste.eval.RecommenderBuilder;
import org.apache.mahout.cf.taste.eval.RecommenderEvaluator;
import org.apache.mahout.cf.taste.impl.eval.AverageAbsoluteDifferenceRecommenderEvaluator;
import org.apache.mahout.cf.taste.impl.eval.RMSRecommenderEvaluator;
import org.apache.mahout.cf.taste.impl.model.file.FileDataModel;
import org.apache.mahout.cf.taste.impl.neighborhood.NearestNUserNeighborhood;
import org.apache.mahout.cf.taste.impl.recommender.GenericUserBasedRecommender;
import org.apache.mahout.cf.taste.impl.similarity.PearsonCorrelationSimilarity;
import org.apache.mahout.cf.taste.model.DataModel;
import org.apache.mahout.cf.taste.neighborhood.UserNeighborhood;
import org.apache.mahout.cf.taste.recommender.Recommender;
import org.apache.mahout.cf.taste.similarity.UserSimilarity;
import org.apache.mahout.common.RandomUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;import java.io.File;
import java.net.URL;/*** @author xiaohe* @version V1.0.0* @Description: 训练数据与评分示例* @date: 2018-8-20 21:18* @Copyright:*/
public class EvaluatorIntro {private static Logger logger = LoggerFactory.getLogger(EvaluatorIntro.class);public static void main(String[] args) throws Exception {/**** 强制 每次选择相同的随机值* 只是为了获取可重复的结果* 可以用在demo和测试用例,不能用在实际代码中** 注掉 会出现不同的值**/RandomUtils.useTestSeed();final String filePath = "intro.csv";URL url = RecommenderIntro.class.getClassLoader().getResource(filePath);File modelFile = new File(url.getFile());if(!modelFile.exists()) {System.err.println("Please, specify name of file, or put file 'input.csv' into current directory!");System.exit(1);}DataModel model = new FileDataModel(modelFile);//创建评估器RecommenderEvaluator evaluator =// 平均差值方式new AverageAbsoluteDifferenceRecommenderEvaluator();// 均方根方式
// new RMSRecommenderEvaluator();// 构建 推荐 示例RecommenderBuilder recommenderBuilder = new RecommenderBuilder() {/**** Recommender 是由新的 DataModel 构建的**/@Overridepublic Recommender buildRecommender(DataModel model) throws TasteException {UserSimilarity similarity = new PearsonCorrelationSimilarity(model);UserNeighborhood neighborhood =new NearestNUserNeighborhood(2, similarity, model);return new GenericUserBasedRecommender(model, neighborhood, similarity);}};/**** 训练 90% 的数据 测试 10%** null 可以是 DataModelBuilder 的一个实例* 控制如何从训练数据中生成DataModel* 通常默认的传null就可以了** 最后一个1.0 控制总共是使用多少输入数据的* 1.0 = 100%* 也可以使用 1.0 ,忽略 90%的数据,快速测试Recommender中的一些小更改** 最后发现一个问题:当训练70%的数据是不行的,会score输出为NaN* 由日志可知:* 19:47:37.546 [pool-1-thread-1] INFO org.apache.mahout.cf.taste.impl.eval.StatsCallable - Unable to recommend in 11 cases* 有11个案例都无法进行推荐。* 原因可能是选取的训练比例不合理,增大训练比例的值,改为0.9 结果输出:1.0**/double score = evaluator.evaluate(recommenderBuilder, null, model, 0.9, 1.0);System.out.println(score);}}