本篇文章,理论为主,在理解本篇文章的基础上,可查看下一篇文章,即操作部分。(注,内容来自Mahout In Action和作者本人理解)
作者:Jack Zhang 来自开拓者部落 ,qq群:248087140,欢迎加入我们!
本文欢迎转载,转载请注明出处 http://my.oschina.net/dataRunner/blog/287907
a)Mahout是开源的机器学习软件库。它所实现的算法归属于机器学习或群体智慧这个广泛的领域。而现阶段的Mahout,主要关注与推荐引擎(协同过滤)、聚类和分类。
b)Mahout是可扩展的。Mahout系统中,机器学习实现是用java来写的,部分建立于Hadoop Mapreduce分布式计算之上
c)Mahout是一个Java类库,不提供用户接口,只为开发者提供一个可改可用的工具框架
Ø2008年Mahout作为lucene的子项目出现
Ø脱离lucene成为独立的子项目
Ø吸纳开源的协同过滤项目Taste
Ø顶级Apache项目,发布全新的驱象人徽标
Mahout早期3个明确的核心主题:推荐引擎(协同过滤)、聚类、分类。当然这些不是Mahout的全部。
a)推荐引擎
推测用户的品味和爱好,找到其可能感兴趣的物品,向其推荐。
1、亚马逊书籍和其他商品
2、Netfix推荐DVD,以及其1000000$的奖励
3、Libimseti 约会网站
4、Facebook等社交网络推荐朋友
b)聚类
i.聚类技术将大量的事务放在一起,试图发现其层次结构和顺序。以揭示一些有用的模式 或让数据集更易于理解
1.Google News使用聚类技术通过标题将新闻分组,未显示所有文章的原始列表
2.Clusty搜索引擎将其查询结果分组
3.根据收入、居住地和购买习惯,将消费者分为多段
c)分类由系统推导出分类的规则
i.用途
1.雅虎邮箱判定垃圾邮件
2.Picasa照片管理应用判断照片中是否包含了人脸
3.iTunes Genius特性使用分类来处理歌曲,为用户生成可能的播放列表
4.筛选异常的行为或模式,来检测可疑的网络活动或欺骗行为
5.筛选异常的行为或模式,或欺骗行为
6.察觉某个用户的消息是否存在失望或满意情绪
a)相关程序的安装
i.Java和IDE
ii.Maven
iii.Mahout
iv.Hadoop
a)创建输入
i.输入:基础数据
ii.偏好:数据以偏好形式表达。一个偏好包含一个用户ID、一个物品ID、偏好值。偏好值可任意设定,例如1~5,但需注意更大的值代表更强的正向偏好,1表示最不喜欢,5表示至爱
iii.输入文件数据
用户ID,物品ID,偏好值 1,101,5.0 1,102,3.0 1,103,2.5 2,101,2.0 2,102,3.0 2,103,5.0 2,104,2.0 3,101,2.5 3,104,4.0 3,105,4.5 3,107,5.0 4,101,5.0 4,103,3.0 4,104,4.5 4,106,4.0 5,101,4.0 5,102,3.0 5,103,2.0 5,104,4.0 5,105,3.5 5,106,4.0
1.数据分析
1和5的喜好相似
1和5的喜好看起来相似:他们都最喜欢101,102次之,103再次之
1和4的喜好基本相似
1和4都喜欢101、103(但4对102的偏好不明)
1和2的喜好基本对立
1最喜欢101,而2最对101的偏好值最低(似乎对其不感兴趣),1似乎对103不感兴趣,但2却最喜欢。
1和3的喜好迥异
仅仅同时喜欢101
总结:分析纬度1、喜好顺序2喜好值,综合
b)创建一个推荐引擎
i.Mahout相关API
1.DataModel
a)FileDataModel
2.UserSimilarity
a)PersonCorrelationSimilarity
3.Recommender
a)GenericUserBasedRecommender
4.RecommendedItem
ii.推荐程序代码
class RecommenderIntro { final static int NEIGHBORHOOD_NUM = 2; final static int USER_ID = 1; final static int RECOMMEND_NUM = 1; public static void main(String[] args) throws IOException, TasteException { /**构建文件对象*/ DataModel model = new FileDataModel(new File("intro.csv")); /**用户相识度*/ UserSimilarity user = new PearsonCorrelationSimilarity(model); /**近邻*/ UserNeighborhood neighborhood = new NearestNUserNeighborhood(NEIGHBORHOOD_NUM, user, model); /**生成推荐器*/ Recommender recommender = new GenericUserBasedRecommender(model, neighborhood, user); /**进行推荐*/ List<RecommendedItem> recommendations = recommender.recommend(USER_ID, RECOMMEND_NUM); for(RecommendedItem recommendation:recommendations){ System.out.println(recommendation); } } }
iii.组件之间的关系图示
c)分析输出
a)训练数据与评分
i.为了知道一个推荐结果是否趋于合理,我们需要知道一个推荐结果和真实喜好的差距
ii.做法是,提取一小段真实数据,作为测试数据来仿真,测试数据不会被导入被评估的推荐引擎,相反,推荐引擎需要为这块缺失的测试数据估计出偏好值,然后估计结果用于与真实值进行对比
我们精简一下语言,获取评分的步骤如下
1、获取真实值。提取一小段真实数据(说明:a、作为真实值,b、不会被导入被评估的推进引擎)
2、获取估计值。推荐引擎为1中未被导入推荐系统的数据估计出偏好值,
3、估计结果和真实值对比
4、计算评分
计算评分的方法
1、计算差值
2、计算平均差值或者均方根
b)运行RecommenderEvaluatour
class Test{ public void test() throws IOException, TasteException{ RandomUtils.useTestSeed(); DataModel model = new FileDataModel(new File("intro.csv")); RecommenderEvaluator evaluator = new AverageAbsoluteDifferenceRecommenderEvaluator(); /***RecommenderEvaluator * 1、将数据分为训练集和测试集 * 2、构建一个新训练的DataModel与Recommender用于测试 * 3、并将估计的偏好值与实际测试数据惊醒比较 */ RecommenderBuilder builder = new RecommenderBuilder(){ 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); } }; double score = evaluator.evaluate(builder, null, model, 0.7, 1.0); System.out.println(score); } }
c)评估结果
通过估计偏好值来生成推荐结果
给出一个从优到劣的推荐列表,不必包含估计的偏好值
有几个好的推荐结果
从3的角度来看,可以使用查准率和查全率来评估推荐程序
查准率:命中数/展示出的全部数
查全率:命中数/相关的总数
a)运行RecommenderIRStatsEvaluator
/*** * 计算查准率和查全率 * @author baby * */ class Test2{ public void test() throws IOException, TasteException{ RandomUtils.useTestSeed(); DataModel model = new FileDataModel(new File("intro.csv")); RecommenderIRStatsEvaluator evaluator = new GenericRecommenderIRStatsEvaluator(); RecommenderBuilder builder = new RecommenderBuilder(){ 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); } }; /** * @param recommenderBuilder object that can build a {@link org.apache.mahout.cf.taste.recommender.Recommender} to test * @param dataModelBuilder {@link DataModelBuilder} to use, or if null, a default {@link DataModel} implementation will be used * @param dataModel dataset to test on * @param rescorer if any, to use when computing recommendations * @param at as in, "precision at 5". The number of recommendations to consider when evaluating precision, etc. * "precision at 5":推荐5个结果的查准率 * @param relevanceThreshold items whose preference value is at least this value are considered "relevant" for the purposes of computations */ IRStatistics stats = evaluator.evaluate( builder, //用于构建用于测试的推荐器(Recommender)的对象 null, //DataModelBuilder的实现类,如果是null,会使用默认的(GenericDataModel) model, //出入文件 null, //可以是任何数字,计算偏好的时候使用 2, // GenericRecommenderIRStatsEvaluator.CHOOSE_THRESHOLD, 1.0); System.out.println(stats.getPrecision()); System.out.println(stats.getRecall()); } }
---待续