2.2 运行第一个推荐引擎

Mahout包含一个推荐引擎的几种类型,事实上包含传统的基于用户(user-based),基于项目(item-based)推荐算法,也包括基于“slope-one”技术的实现(这一个新的有效的方法)。

你将根据实验,基于单机版的(SVD)初步实现。在下面的章节里,我们将会在Mahout的背景下和一些现实生活中的例子,来回顾上面的观察结果。我们将会考虑如何代表数据,如何进行有效的推荐算法,如何评估推荐器的效果,如何为一个特殊的问题调研和定制推荐器,最后考虑如何分布计算。


2.2.1 创建输入


我们将会以一个简单的例子,开始对Mahout中的推荐器认识。首先,我们需要给出推荐器的输入数据。在Mahout中称为“偏好(preferences)”的表单。因为最流行的推荐引擎,把需要推荐的项目推荐给用户,从用户到上面提到的关联items,作为一个关联最方便选择讨论。这些用户和项目可以成为任何东西。包含一个userID和一个itemID,通常用一个数字来表达用户和选项的喜好强度(preference)。在Mahout中的ID通常是数字,事实上总是int。这一项的值可以代表任意值,preference值越大,代表关联度越强。例如,这个值可能是从1到5的范围内的等级。在这里,用户分配“1”,则表示他不能忍受这个项目,分配“5”表示他很喜欢这个项目。


创建一个文本文件,包含相关用户,简单的命名“1”到“5”。为四本书的偏好,我们将会称它们为“101”到“104”。在现实生活中,这些可能是用户ID和产品ID列表,它们来自于一个公司的数据库;Mahout仅仅需要数字命名的用户和项目!我们将会简单的用逗号分割数值的格式,来记他们。把下面的复制到一个文件里,并把它作为intro.csv保留下来:


列表2.1 推荐器的输入文件intro.csv



通过上面的学习,我们可能已经注意到。用户1和5看起来有相似的品味。他们都喜欢book101,其次喜欢book102,然后都喜欢book103。同样的问题存在于用户1和4,因为它们看起来都喜欢101和103(虽然没有说用户4喜欢102).换句话说,通过运行计数,发现用户1和用户2喜欢的看起来相似:1喜欢101,而用户2不喜欢,用户1喜欢103,而用户2刚好相反。用户1和用户3没有很多重叠。双方同时喜欢书101的就很难。看图2.1,可能会想象用户和项目之间的关系,既有肯定的又有否定的。



图2.1 用户1到用户5,与项目101到项目107的关系。

虚划线代表否定的关联,用户看起来很不喜欢这个项目,但也表达了与这个项目的关系。


2.2.2创建一个推荐器


之所以选择这本书,我们推荐给用户1?而不是101,102,也不是103。是因为他明显的已经知道了这些书,推荐器是着力与发现新事物。感觉建议,因为用户4和用户5与用户1看起来相似,我们应该推荐一些用户4或用户5喜欢的东西。把104,105和106当作可能的推荐器。总体来说,根据为项目104的喜好值4.5和4.0的判断来看,104看起来可能性最大。现在,运行下面的代码:


列表2.2 Mahout上简单的user-based推荐算法程序

package mia.recommender.ch02;    
import org.apache.mahout.cf.taste.impl.model.file.*;    
import org.apache.mahout.cf.taste.impl.neighborhood.*;    
import org.apache.mahout.cf.taste.impl.recommender.*;    
import org.apache.mahout.cf.taste.impl.similarity.*;    
import org.apache.mahout.cf.taste.model.*;    
import org.apache.mahout.cf.taste.neighborhood.*;    
import org.apache.mahout.cf.taste.recommender.*;    
import org.apache.mahout.cf.taste.similarity.*;    
import java.io.*;    
import java.util.*;    
class RecommenderIntro {    
public static void main(String[] args) throws Exception {    
DataModel model = new FileDataModel(new File("intro.csv")); //A    
UserSimilarity similarity = new PearsonCorrelationSimilarity(model);    
UserNeighborhood neighborhood =    
new NearestNUserNeighborhood(2, similarity, model);    
Recommender recommender = new GenericUserBasedRecommender(    
model, neighborhood, similarity); //B    
List<RecommendedItem> recommendations =    
recommender.recommend(1, 1); //C    
for (RecommendedItem recommendation : recommendations) {    
System.out.println(recommendation);    
}    
}    
}  

 




A 加载数据文件

B 创建数据引擎

C 为用户1推荐1个项目


为了更清楚,可以通过下面章节更多的例子。这里我们将会缺省导入,类声明和类函数声明,而不只是重复程序声明本身。为了帮助认识,基础组件之间的关系,看图2.2。并不是所有的基于Mahout的推荐器,看起来都像这个样子。某些将会采用不同的组件,有不同的关系。但这可以给我们一个初步的认识,在我们这个例子中表现出来的组件。



图2.2 简单的说明在Mahout中基于用户(user-based)推荐器各个组件的相互关系


因为在下面的两节里,我们将会更详细的讨论这个内容中的每一项,并总结每一个组件的作用。一个DataModel的实现是计算中需要的首个因素,提供用户和项目数据储存的入口。一个UserSimiliarity的实现提供了两个用户如何表示相似的概念;这将会以所有可能的度量或计算中的一个为依据。一个UserSimiliarity的实施定义了一组用户的概念,这些用户与一个已知的用户很相似。最后,一个Recommender的实现把所有的内容拉在一起,把项目推荐给用户,和相关的功能。


2.2.3 分析输出数据


通过你喜欢的IDE,编译和运行。在终端或IDE上运行的程序,输出数据应该是:

RecommendedItem[item:104, value:4.257081]


我们曾经希望寻找并使用一个优秀的推荐器。这个推荐引擎把book104推荐给了user1.进一步说,推荐引擎也是这么做的,因为它估计到user1对book104的分值大约是4.3,而且它是所有对推荐器筛选的项目中分值最高的。


那不算太坏。我们没有得到107,它也是值得推荐的,但只与不同品味的user有关联。我们从106中挑选出104,当你注意到104是所有book中的选择比例非常高的,这是有意义的。进一步的说,对于user1有多喜欢项目104,我们已经得到了一个合理的估计:user4和user5所表达的介于4.0和4.5之间的比值。


从数据上来看,这个正确答案并不明显。但是推荐引擎对它做了一些适当的调整,并得到了一个更有说服力的答案。通过看到这个简单的程序,这个程序就是从一小堆数据中得到一个有用的并且不明显的答案,如果你从中得到了一次令人愉快的兴奋,那么这个机器学习的世界正是为你而存在的。


简单的说,像上面的构建在小型数据集合上推荐器并不重要。在现实生活中,数据量是巨大的,并且它们是很杂乱的。例如,想象一下,把一个新闻文章推荐给读者的一个畅销的新闻点,分值从文章的点击得到的。但是,许多分值可能是假的,也可能一个读者点击了他并不喜欢的一篇文章,或者说点击了一个错误的故事。可能许多点击已经出现了,但并没有生效,所以与user没有关联。在试想一下这样规模的数据量:可能在一个月内就有数以亿计的点击量。


从这些数据中快速产生一个正确的推荐数据,这是相当重要的。稍后,我们将会介绍一个Mahout工具,通过案例的方法研究,我们可以用Mahout工具攻克这一系列问题。它们将会显示出标准的方法,如何生产差劲的推荐数据或者消耗得大量的内存和CPU时间,并且如何安装和配置Mahout来改进。

阅读更多
上一篇2 推荐器
下一篇2.3 推荐器的评估
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

关闭
关闭
关闭