首页 > 代码库 > Mahout--(五)mahout疑问解答

Mahout--(五)mahout疑问解答

来源:http://www.douban.com/note/245740667/

 提问1:

博涛前辈,您好!

打搅您了,我想请教您一些问题。我是一名在读研一学生。研究推荐系统方面的知识。 我一直非常困惑,在实际应用中,给定一个应用系统。比如淘宝,或者给定一个应用系统积累的数据集,怎样用推荐系统的思想着手分析,怎样为系统设计一个好的推荐方法,又是怎样一个流程去分析这类问题?我看了mahout in action书中recommendations章节chapter 5提到对于一个数据集的分析思路,先选择effective recommender,再结合领域知识过滤推荐。再继续分析解决新用户和新对象问题等。

我不确定现实应用中是不是也是这样分析的?还有对于推荐系统领域的一些疑难杂症,在现实应用中是不是都能通过一些办法解决?比方新用户问题,借助用户的注冊信息或者訪问cookie(您对还有一位读者的回答中提到)解决,对于新对象问题。则借助content-based方法解决? 最后对于我自己眼下的状况我非常疑惑,即作为一个学生。研究推荐系统知识,应该把重点放在算法改进研究上,还是对实际问题的分析解决上?我认为学术研究和实际应用还是有一定的差别的,并且我看了这块领域中的一些算法改进的论文,我认为拿到现实中未必实用。

不好意思,提了这么多问题,希望前辈能为我解惑!


回答:

我概括了下你的回复里面有三个问题。1. 怎样为一个有数据积累的应用系统设计和构建一个推荐系统?2. 怎样解决冷启动问题?3. 对于刚了解推荐系统的同学的一些建议?这三个问题假设展开叙述,都能够写好几篇博文了,所以在这里,我仅仅是简要的回答你,可能会有不全然的地方:) 

原 Google 研究员张栋(@张栋_机器学习)对于推荐系统影响因素概括了 5 点,即:产品设计:30%。数据:30%,领域知识:20%,算法:10%,project优化:10%。我认为张栋老师概括的很好。从中能够看到数据对于推荐系统的重要性。假设你有一个将要构建推荐系统的应用,数据仅仅是一个必备的前提,要真正实践一个推荐系统。首先还是得从用户的需求出发,依据用户的需求明白推荐系统提供哪一些服务,所提供的这些服务想达到什么样的目标,即:做什么?目标是什么?。

比方。新浪微博在 09 年刚上线的时候肯定也面临着怎样构建推荐系统的问题,能够肯定的是经过他们的一番思考后。他们抓住了用户的两点需求:(1)热门话题和新闻一般会得到大家的高度关注;(2)好友之间的互动。他们的目标也非常easy(1)提高用户的发微、转发、评论的频率,添加用户对微博的黏性;(2)构建新浪微博的好友生态圈。大家如今去看看新浪微博,他们的推荐形式差点儿就这两种,没怎么大变,可是效果确实越来越好。由于他们不断的再实践和优化。 

知道了做什么和目标,以下我们就讨论下怎么做。一般来说构建推荐系统基本流程是:用户行为、数据分析建模 -> 推荐算法设计和相关性计算 -> 生成推荐结果(含推荐解释) 

1. 用户行为、数据分析建模 
假设你的数据分布在訪问日志和数据库的多个表中(比如订单表、收藏记录表、评价表、订阅表),那么一般须要把这些数据提取出来。并转换成用户的行为数据 user_behavior(user_id, item_id, behavior_type, behavior_content, behavior_weight)。

用户的行为数据来源很广,对于一个电子商务站点而言,购买、浏览、收藏、评价、订阅等隐性行为,用户问卷调查等显性行为贡献了大量的数据。还有一方面,注冊信息也是用户的重要特征数据。

 

2. 推荐算法设计和相关性计算 
相关性计算(也就是相似性计算)和推荐算法是密切联系的。依据推荐算法的不同。我们须要计算用户之间的相似性和物品之间的相似性。而用户之间的相似性能够是行为的相似性。也能够是用户属性(年龄、性别、地域)的相似性。物品之间的相似性能够是基于用户反馈的相似性。也能够是物品内容的相似性。

 

推荐算法包含 UserCF、ItemCF、Content-based、Demographic-based 等,应该说这些算法都各有长处和缺点,在应用中也会依据实际情况选择当中的一种或多种方法。

通常。我们可以依据经验排除某几种或选择某几种。比如:微博的好友推荐主要使用的推荐算法是 UserCF 和 Hot-based。假设你已经使用微博一段时间,微博会依据你关注的用户生成你的好友圈子推荐给你。假设你关注的用户非常少,比方新用户,那么会推荐那些大 V 用户给你,比方姚晨啊、开复老师啊。

另外一个典型的样例,就是 Amazon。我们知道 ItemCF 是 Amazon 提出来的,在这之前 UserCF 已经用了好几年,可是 Amazon 的project师在推荐系统的实践中认为 UserCF 不适合他们,由于:(1)用户的数量远大于商品的数量,同一时候用户的增长规模也大于商品的增长规模,所以 UserCF 的计算量会越来越大;(2)用户的相似性是不稳定的。而商品的相似性却要稳定的多,《Thinking in Java》和《Effective Java》是相似的两本书。它们今天相似,过一个月后。过一年之后都是相似的,但两个用户 A 和 B,他们今天喜欢相同的书籍,我们觉得他们是相似的,但过了一天或一周后可能他们喜欢的书籍会发生非常大的变化导致他们不再相似,所这就要求 UserCF 要进行频繁的计算;(3)UserCF 难以生成让人信服的推荐理由,你买个东西告诉你是由于你和某某人相似,而你却连这某某人是谁都不知道。

正由于这些原因 Amazon 的project师提出了 ItemCF 算法。

 

相似性计算的方法有非常多,余弦相似性、欧氏距离、皮尔森相关系数、内容相似性 等等,能够參看我之前的 blog http://blog.csdn.net/bornhe/article/details/7425642。 

终于选取哪一种推荐算法和哪一种相似性。取决于评測的结果。通常,我们会实验每一种方法。然后选择最优的一种。这里使用了机器学习里面的监督学习方法。能够看我之前的回复http://www.douban.com/note/208193209/#30908428。 

说那么多。还了举微博和 Amazon 的样例,主要是为了说明推荐算法是一种领域性非常强的算法(你问题里也提到了领域)。别的系统用的非常好的推荐算法,放到你的系统里不一定会表现非常好,所以我们须要进行领域分析和推荐算法的评測,评測的方法有 RMSE(Netflix 用的离线评測指标)、precision、recall。这在 《Mahout in Action》Part 5 里面也有具体的介绍。 

3. 生成推荐结果(含推荐解释) 
前两步的计算量非常大,一般都是离线完毕。

而生成推荐结果却是实时的。用户请求来,我们就匹配和用户最相关的物品推荐给用户。这一步我会进行结果的过滤、排序和推荐结果的解释。

过滤处理非常easy,就是把用户已经产生过行为的物品、质量差的物品过滤掉。而排序则要复杂的多,须要考虑推荐物品的相关性、新颖性、多样性和时间上下文等多种因素,一个个性化的推荐系统。排序也要是个性化的,这意味着我们须要为每个用户(或每个群体)训练一个排序模型,训练的过程也是离线完毕的,关于推荐系统的排序能够參考我翻译的 Netflix 推荐系统的 blog:http://blog.csdn.net/bornhe/article/details/8222497。最后。推荐解释也是非常重要的。我们须要说清楚推荐结果是来源于用户的那些行为或属性,好的推荐解释可以添加用户对推荐结果的信任度。这样用户会更可能购买或评价。

 

补充一点:关于推荐算法的评測,离线评測是当中重要的一种,通常在实际场景中还会安排线上评測,也就是 A/B 測试。我们会把好几种通过离线评測的算法和模型放到线上去经受用户的考验。终于挑出最优的几种。关于 A/B 測试。也能够參看 http://blog.csdn.net/bornhe/article/details/8222497的后面部分。 

PS:有非常多 blog 在讨论 #推荐系统构建# 这个话题的时候,都是环绕着怎么做開始的,从中你能够看到业界非常多公司使用的都不是单独的一种推荐算法,而是一种混合的推荐算法,可是细节一般都秘而不宣。

 

------------------------------------------------------------------------ 
对于你的第二个问题:怎样解决冷启动? 

事实上在你的问题里面已经有了答案。

也就是对于新用户,我们能够使用 Demographic-based 和 Hot-based(排行榜)来解决冷启动问题。对于新物品。能够用 Content-based 来解决冷启动问题。在这里 http://www.douban.com/note/204399134/#30943588 有我之前详细的回复。 

------------------------------------------------------------------------ 
对于你的第三个问题:对于刚了解推荐系统的同学的一些建议? 

事实上我也刚走出校园一年多,之前在学校的时候也有类似于你的困惑。

有一点,我认为要明白:无论是在学校,还是去企业里面实习,都非常难有“实际问题分析解决”的机会,所以在学校能够多利用自己的业余时间开阔自己的视野,能够多关注一些大牛和知名公司的技术博客 
Gren Linden(ItemCF 算法的提出者之中的一个) blog:http://glinden.blogspot.com/ 
项亮大牛的 blog:http://xlvector.net/blog/ 
谷文栋大牛的 blog:http://www.guwendong.com/archives 
阿稳大牛的 blog:http://www.wentrue.net/blog/ 
Netflix 技术 blog:http://techblog.netflix.com/ 
项亮和谷文栋一起发起了 Resys China http://www.resyschina.com/,项亮的《推荐系统实践一书》也相当推荐阅读,在第 7 章——推荐系统实例。相信能给你对于 #推荐系统构建# 很多其它的答案。 

另外也有非常多的实践机会,网上有非常多的真实可用数据能够供我们使用,《Mahout in Action》中介绍的 GroupLen 就是非常好的资源(并且这些数据都是经过提取和转化处理的),用这些数据,结合自己的学习,不断的实践。相信能够取得不小的进步。假设身边有同兴趣的同学。你们还能够一起组队參加 Netflix Prize 推荐系统大赛,项亮曾在 09 年參加过 Netflix Prize,并取得了第二名的好成绩,详见:http://www.netflixprize.com/leaderboard,这些都是非常好的实践的机会。

 

总之,多读论文多实践。眼光长远。相信你一定取得好成绩。



提问2:

博涛,真的非常感激你为我认真耐心地解答疑惑,解答不仅内容具体、调理非常清晰,更是切中了困惑我非常久的问题!我认真研究了你写的每个字,对链接也进行了深入的阅读,并做了笔记。似乎我之前脑海中的一片糊涂開始变得清晰了,非常多知识我可能也知道,可是我没有总体概念。对于细节和深入的本质更是模糊不清。有时候模糊的连自己的问题在哪里都不知道,更别提查找资料解决这个问题了。

看了你的回答,我思路更清晰了,同一时候我也更明白作为一个在校学生,应该做什么了!非常多时候我知道自己有非常多能够选择的路。可是由于没有过来人的指点,总操心自己会迂回绕远,这或许是非常多走在路上的人的困惑吧。另外。我还得打搅你一下,我整理知识过程中,发现我还有几点不是非常明白:(1)线下计算大概是如何实现的?是将各种相似性矩阵结果提前计算好。存储在文件系统或数据库系统中。然后线上推荐时对相关信息进行读取再计算推荐?(2)训练集和測试集问题。《mahout in action》书中进行评測时是通过一个比例參数决定百分之多少为训练集。剩余的百分之多少为測试集,groupLens的100k的数据集中有ua.base 和ua.test两个数据文件,ua.base应该是用作训练,ua.test应该是用作測试的(我看着应该是的),在评測时我怎么先用ua.base训练。再用ua.test測试呢?mahout支持这样的输入吗?(weka中分类方法实验时。分别载入训练集和測试集的)(3)我看了一些文章,多数文章核心的部分是结合应用特征和属性计算uesr对item的preference,而在你的还有一篇博文“Netflix 推荐系统:第二部分”中。提到Netflix不只使用预測评分。而是将热门程度和预測评分进行线性加权f(u, v) = w1*p(v) + w2*r(u, v) + b,然后根据f(u,v)值进行排序。我想知道这个f(u,v)与预測评分有什么本质的差别?是不是博文中的“预測评分”是单纯的根据相似用户或item的信息得出的评分预測,与其它应用相关的属性无关?我个人认为f(u,v)是一种广义上的评分预測。

不好意思,又写了这么多问题。再一次表达我的谢意*_*


回答:

关于你的第一个问题(1)线下计算大概是如何实现的?事实上你自己给的答案是正确的。我这里简单做下补充:这个问题能够说是推荐系统最核心的问题。非常多公司对这部分内容一般都仅仅是介绍个大概。细节都秘而不宣,所以这部分所涉及的内容是非常多的,不管是计算量,还是技术难度都非常大。

普通情况下。一个成熟的推荐系统,都会有两部分组成:离线部分和在线部分。

离线部分完毕的是相关性的计算,计算结果通常会持久化到 MySQL 或诸如 Redis 的 K-V 数据库中,也能够存储到 HBase 这类分布式存储系统中(据我了解到 facebook 推荐系统的相关性数据就是存储到 HBase 中的)。当然详细的存储方式要视你的数据规模(存储成本)和实际场景(如读写比例、系统结构等)而定。有了相关性数据,在线部分仅仅须要读取用户特征(如历史行为中的商品),然后到相关表找查找匹配相关结果就能够得到初始的推荐结果。另外要告诉你一点。业界各家公司的推荐系统,在线部分大部分是相似的,主要差别和创新主要都集中在离线部分。 

关于你的第二个问题(2)训练集和測试集问题?这主要是一个机器学习中的监督学习过程,这在我上面的回复中有具体的介绍。在 Mahout 中有一个 RecommenderEvaluator 的接口。通过接口中的 evaluate 方法。能够完毕对某一个推荐算法的评估,也能够依据这个接口进行自己定义的扩展。而在 grouplens 的 100k 的数据中,从 u1.base,u1.test 到 u5.base。u5.test 这 5 组数据集都是从 u.data 中依据 4:1 的比例抽取出来的,当中 .base 是训练集。.test 是測试集。grouplens 的原文介绍是“The data sets u1.base and u1.test through u5.base and u5.test are 80%/20% splits of the u data into training and test data.” 。在训练和測试过程中,第一步:使用 u1.base 进行训练,说详细一点就是基于 u1.base 构建一个 recommender。然后为 u1.base 中的全部 user 产生推荐结果,如果推荐结果集为 u1.result;第二步:比較 u1.result 和 u1.test 中的数据重合度。重合度越高说明算法的准确率越高。

如果是直接使用 Mahout 提供的 RecommenderEvaluator,那么仅须要使用一个文件—— u.base,把 u.base 作为 DataModel 的 file。并指定 trainingPercentage 为 0.8,指定 evaluationPercentage 为 1.0 就能够了。Mahout 会自己主动把 u.base split 成两个文件。train 文件和 test 文件。源代码为“splitOneUsersPrefs(trainingPercentage, trainingPrefs, testPrefs, userID, dataModel);”

关于你的第三个问题(3)推荐结果排序和预測评分的关系?在我的博文《Netflix 推荐系统:第二部分》中,f(u, v) 是一个排序分值函数(rank function)。而预測分值 p(v) 是函数 f 的一个维度,为什么会这样呢?由于在把推荐结果展现给用户之前,通常须要对推荐结果进行排序,把用户最有可能点击或购买的物品排列在前。计算物品的排序须要综合考虑评分预測值、物品的热门程度、物品的新颖度等等因素。每个因素能够看成是函数 f(u, v) 的一维。一般而言,会为每一个用户都计算一个 f(u, v) 函数,由于一个个性化的推荐系统,排序也要是个性化的。计算的过程是离线完毕的。具体你再具体看下博文的原文。

Mahout--(五)mahout疑问解答