2 推荐系统介绍

原创文章,转载请注明: 转载自慢慢的回味

本文链接地址: 2 推荐系统介绍

本章包括
Mahout里面的推荐引擎
实践第一个推荐引擎
评估推荐引擎的准确性和质量
使用GroupLens真实数据评估推荐引擎

  每天我们都对事物表达喜好,不喜欢和不关心。它无意识的发生了。你从电台听到一首歌并注意到它了,因为它吸人,或者难听或者你根本没有注意到它。同样的事发生在衬衫,沙拉,发型,面孔等。虽然人们爱好不一样,但都遵循这个模式。人们喜好和他们所喜好的类似的东西。比如某人喜欢牛肉拉面,你可以猜到他同样喜欢羊肉泡馍,因为都是清真食品。同样的,人们喜欢和他相似的人喜欢的东西。这个可以用来判定喜欢和不喜欢。推荐系统就是用来判定这些模式的爱好,被用来发现你不知道但想要的东西。在这个观点更深入的研究后,你将运行一个简单的推荐引擎并明白它怎么工作的。

2.1 定义一个推荐系统

  比如你去书架找这本书,你可以看到挨着它放的书你可能也喜欢。因为人们喜欢把相关的书放在一块儿。如果要发现你可能喜欢的东西,可以从和你有类似喜好的人喜欢的东西里面找,也可以从类似你已经拥有的东西里面去找。实际上有两类推荐算法引擎:基于用户的和基于物品的,这两者Mahout都含有。严格的讲,上述就是采用协同过滤来推荐的。这种技术不需要项的属性。也就是说,这个推荐引擎框架不关心项是书,花还是其他人,即不需要输入数据的属性。
  当然也有其它依赖与属性的算法即基于内容的推荐引擎技术。比如,你朋友推荐这本书给你是因为它是Manning的书,而你的朋友喜欢其它的Manning的书,所以你朋友喜欢什么东西更像基于内容的推荐。这种推荐就是基于书的属性:出版商。如果要实现基于内容的推荐引擎,你必须决定使用项的什么属性以及每个属性的权值,而且换个领域,算法就不行了。
基于这个原因,Mahout不想多关心基于内容的推荐引擎。Mahout提供的就是协调过滤框架。具体参见第5章关于dating网站的例子。现在我们来看一个简单的例子。

2.2 运行第一个推荐引擎

  Mahout含有多种类型的推荐引擎,我们以一个简单的基于用户的推荐引擎开始吧。

创建输入
  数据输入采用参考数据的形式,每条参考数据包含用户ID,物品ID和对应的参考值,因为我们是要把物品推荐给用户,这样表达输入数据比较合理。用户ID和物品ID是一个整形的ID,参考值是一个范围的数值,比如可以是1-5,其中数值越大表示越喜欢。
  按照这个逻辑先创建一个如下形式的输入文件intro.csv。依次为用户ID,物品ID,参考值。

1,101,5.0
1,102,3.0
1,103,2.5
2,101,2.0
2,102,2.5
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和5具有相似的喜欢,他们都喜欢101>102>103。用户1和用户4也类似,他们都喜欢101和103。用户1和用户2好像就相反了,用户1喜欢102但是用户2不喜欢。用户1和用户3就看不出来了,因为他们重复喜欢的就只有101。

创建推荐系统
  如果要给用户1推荐,该推荐什么呢?不能是101,102和103,因为用户已经有了。推荐系统是要发现新的东西给用户1。用户4和用户5喜欢类似用户1,看来可以从他们喜欢的东西中去找到可能推荐的东西。剩下的104,105,106中,104更有可能。
  现在,运行下面的代码:

class RecommenderIntro {
	public static void main(String[] args) throws Exception {
		DataModel model = new FileDataModel(new File("intro.csv"));
		UserSimilarity similarity = new PearsonCorrelationSimilarity(model);
		UserNeighborhood neighborhood = new NearestNUserNeighborhood(2, similarity, model);
		Recommender recommender = new GenericUserBasedRecommender(model, neighborhood, similarity);
		List<RecommendedItem> recommendations = recommender.recommend(1, 1);
		for (RecommendedItem recommendation : recommendations) {
			System.out.println(recommendation);
		}
	}
}

  在接下来2章中将详细介绍,现在稍微解释下。DataModelimplementation存储和提供怎么去获取参考数据,UserSimilarityimplementation用来计算2个用户的相似度,UserNeighborhoodimplementation用来定义用户相似的邻居关系,最后Recommenderimplementation计算并推荐结果。

分析输出
  运行代码会有如下输出:
RecommendedItem [item:104, value:4.257081]

2.3 评估一个推荐系统

  现在我们要解决一个问题,即对一个用户来说,什么推荐系统是最好的。现在我们就要来评估推荐系统。
一个最好的推荐应该是它可以很好推荐你所没有表达喜好的物品,并对这些推荐进行评级。其实推荐系统就是估计这些参考值,所以评估这些推荐系统就可以计算它的参考值和实际值的吻合度。
训练数据和评分
  实际的参考值不存在,任何人都不可能知道,但是我们可以模通过把已有的输入数据分成真实数据和测试数据。通过推荐系统,处理分出来的真实数据,产生推荐值,然后和分出来的测试数据进行比较,差异越小的越好。这种差异的计算可以通过均值,也可以通过平方的均值。如下表所示:

Item 1 Item 2 Item 3
测试数据值 3.0 5.0 4.0
推荐数据值 3.5 2.0 5.0
差异 0.5 3.0 1.0
差异平均值 = (0.5 + 3.0 + 1.0) / 3 = 1.5
差异的平方开放值 = √((0.5^2+ 3.0^2+ 1.0^2) / 3) = 1.8484

运行推荐评估系统
参考如下代码:
代码2.3

		RandomUtils.useTestSeed();
		DataModel model = new FileDataModel(new File("intro.csv"));
		RecommenderEvaluator evaluator = new AverageAbsoluteDifferenceRecommenderEvaluator();
		RecommenderBuilder builder = new RecommenderBuilder() {
			@Override
			public Recommender buildRecommender(DataModel model) throws TasteException {
				UserSimilarity similarity = new PearsonCorrelationSimilarity(model);
				UserNeighborhood neighborhood = new NearestNUserNeighborhood(2, similarity, model);
				return new GenericUserBasedRecommender(model, neighborhood, similarity);
			}
		};
		double score = evaluator.evaluate(builder, null, model, 0.7, 1.0);
		System.out.println(score);

  RecommenderEvaluator把数据分成训练数据和测试数据,构建一个数据模型和推荐系统进行测试,最好比较推荐值和实际值。

获取结果
  运行测试,输出结果为1.0。因为RandomUtils.useTestSeed(),每次使用同样的随机数,所以多次运行都能得到同一个结果,这方便测试。这儿用的是AverageAbsoluteDifferenceRecommenderEvaluator,即产生的结果是推荐值和测试值差异的均值。你也可以用RMSRecommenderEvaluator替代AverageAbsoluteDifferenceRecommenderEvaluator而得到平方开方平均值。evaluator.evaluate方法中的1.0代表需要使用的输入数据即100%,0.7表示这些输入数据中多少用于推荐计算即70%。
  更一般的说,我们可以用经典的信息检索指标来评估推荐系统:精度和重现度。就像搜索引擎从查询到的很多可能的结果中返回最好的结果一样。搜素引擎不能返回相关度不高的结果到最上面,应该返回最相关的结果。比如精度10意味着前面的结果在相关里的比例为10%,重现度表示所有相关的结果在最前的比例。用在推荐引擎上就是:精度为最前的推荐引擎是好的推荐引擎的比例,重现度是好的推荐引擎在最前的比例。

2.4 评估精度和重现能力

  运行RecommenderIRStatsEvaluator。如下代码:

		RandomUtils.useTestSeed();
		DataModel model = new FileDataModel(new File("intro.csv"));
		RecommenderIRStatsEvaluator evaluator = new GenericRecommenderIRStatsEvaluator();
		RecommenderBuilder recommenderBuilder = new RecommenderBuilder() {
			@Override
			public Recommender buildRecommender(DataModel model) throws TasteException {
				UserSimilarity similarity = new PearsonCorrelationSimilarity(model);
				UserNeighborhood neighborhood = new NearestNUserNeighborhood(2, similarity, model);
				return new GenericUserBasedRecommender(model, neighborhood, similarity);
			}
		};
		IRStatistics stats = evaluator.evaluate(recommenderBuilder, null, model, null, 2,
				GenericRecommenderIRStatsEvaluator.CHOOSE_THRESHOLD, 1.0);
		System.out.println(stats.getPrecision());
		System.out.println(stats.getRecall());

  输出应为:
0.75
1.0
  精度对用户2是0.75表示平均3/4的推荐是好的,即推荐的结果中占实际结果的75%,重现度是1.0,在他们推荐的结果中都是好的推荐,即推荐的结果中100%在实际结果中。

精度和重现能力问题

2.5 评估GroupLens数据集

  工具在手,我们不仅要讨论推荐系统的速度,而且还有质量。

分解输入
  GroupLens (http://grouplens.org/)是一个提供了不同大小数据的研究项目,每个数据集都是从真实用户的评分中获取的。到http://www.grouplens.org/node/73下载100K数据集吧,解压找到ua.base文件,它是用制表符Tab分割的数据文件。把ua.base应用与代码2.3中,通过几分钟后,你会得到结果在0.9左右。难道我们实现的推荐引擎不是最好的?
使用其它推荐系统试验
  我们用org.apache.mahout.cf.taste.impl.recommender.slopeone.SlopeOne-Recommender试试吧。

                RecommenderBuilder recommenderBuilder = new RecommenderBuilder() {
			@Override
			public Recommender buildRecommender(DataModel model) throws TasteException {
				return new SlopeOneRecommender(model);
			}
		};

  再次运行,结果在0.748左右,好像更好了。每个算法都有它的优势。比如,slope-one可以更快的计算推荐,但是它需要先去计算产生内部数据结构。

2.6 总结

  本章,我们介绍了推荐引擎的概率。我们可以创建一个小量数据集的Mahout推荐引擎,运行并解释结果。评估推荐系统并解释输出。最好用真实数据评估了推荐系统。本作品采用知识共享署名 4.0 国际许可协议进行许可。

1 了解 Apache Mahout

原创文章,转载请注明: 转载自慢慢的回味

本文链接地址: 1 了解 Apache Mahout

本章包括
Mahout是什么,它从哪儿来
一瞥现实世界的推荐系统,集群系统和分类系统
配置Mahout

  从标题可以猜到,这本书讲一个特殊的工具,Apache Mahout, 在现实中的有效使用,它包括3个定义的质量。首先,Mahout是Apache上一个开源的机器学习库。它实现了部分机器智能学习算法。Mahout主要包括推荐引擎(协调过滤),集群和分类。它同时是可伸缩的。当数据非常大,Mahout将作为一个集群学习工具的选择。当前情况,Mahout实现的可伸缩机器学习算法由Java书写,部分依赖Hadoop分布计算系统实现。最后,它是一个Java库,它不提供用户界面,或者预先打包的服务或者安装包。它是一个开发者使用和实现的框架工具。本章先简约的看看Mahout提供的机器学习算法。为亲手操作Mahout做准备,你需要一些必须的设置和安装。

1.1 Mahout的历史

  首先,Mahout的一些背景知识。你可能正在考虑Mahout怎么发音:这是个英化词,发音类似trout。一个关于赶象人的海地单词,这里有一个简短的历史。Mahout开始与2008年,作为Apache Lucene的一个子项目,Lucene是非常有名的开源搜索引擎。它提供了搜索,文本挖掘,信息提取技术。在大学的教程中,这些概念类似集群,分类。最终,一些Lucene贡献者关注在了机器学习方面。稍后,Mahout纳入了一个开源的协同过滤项目Taste。2010年4月,Mahout成为一个使用象为Logo的顶层Apache项目。
  Mahout的工作不仅是有效和可伸缩的转换这些算法,而且是把这些算法在Hadoop上实现。Mahout孵化了一系列技术和算法,许多还正在开发中或处于试验状态(https://cwiki.apache.org/confluence/display/
MAHOUT/Algorithms)。在项目的初始阶段,有3个核心的主题:推荐引擎(协调过滤),集群和分类。这不表示所有的都在Mahout中,但是大部分突出且成熟的已经写成。基于此,你现在已经在关注着3大家族技术。

1.2 Mahout机器学习主题

  虽然Mahout是一个开放的需要实现所有种类的机器学习技术,但是目前关注在3个关键方面。包括推荐引擎(协调过滤),集群和分类。

推荐引擎
  推荐引擎是目前最真知灼见的机器学习技术。你是否曾经看到过一下网站和服务提供推荐书籍,电影或文章。它们试着推断和识别你可能喜好的未知项:
     Amazon.com是可能最著名的部署了推荐系统的商业网站。基于订购和网站活跃度,Amazon推荐你可能喜好的书籍或其他项。
     Netflix相似的推荐你可能喜好的DVD,而且愿意支付$1,000,000给谁可以提高他们推荐引擎质量的研究者。
     Dating网站就像Líbímseti甚至可以推荐人给人。
     社交网站像Facebook使用带有变量的推荐技术去识别人们可能但是还没有联系上的朋友。
  就像Amazon和其它已经举例的,推荐引擎已经通过交叉销售机会创造了商业价值。有报道,推荐产品给用户可以提高8%到12%的销售增长。

集群
  集群就没那么明显了,但是他的出现却非常著名。名称都隐含着集群技术试图把相似的东西分到集群里去。它是一种发现大或者难懂数据的架构和顺序的方法,也是一种发现兴趣模式或是数据容易理解的方式。
     Google新闻使用集群技术按主题把新闻分类。
     搜索引擎像Clusty按相似理由把搜索结果分类。
     消费者也看按照收入,地区和购买习惯进行集群分类。集群可以帮助识别难以识别的大数据集的结构,甚至体系。企业可以使用技术去发现用户中隐藏的分组,或者有效的组织大量的文档,或者网站日志中常用的模式。

分类
  机器技术决定事物多少概览可以是或不是某个类。分类就像集群,它是无处不在的,但是它可能更不明显。这些系统常常靠检测已经所属某类实例来学习分类规则。这也有许多应用。
     Yahoo! Mail通过以前的邮件和用户的垃圾邮件规则决定收到的邮件是否垃圾邮件。
     Google的Picasa和其他照片管理程序能确定图片的一个区域是否包括人脸。
     光学字符识别软件通过分类把扫描到的区域识别成独立的字符。
  分类可以确定是输入的内容是否和以前识别到的模式是否匹配。它也可以用来检测可疑的网络活动。它也可以用来指出用户的消息是消极的还是积极的。这些技术当大量的良性输入时可以工作得很好。在某些情况下,这些技术不仅仅可以在大量的输入下工作,并且必须很快产生结果,这些因素是可伸缩的重大问题。如以前提到过的,Mahout其中的一个功能就是在大量的输入数据上实习这些技术。

1.3 Mahout和Hadoop的大型可伸缩

  在机器学习算法的尺度问题是真的吗?让我们考虑一下你部署Mahout需要考虑的几个问题。
  Picasa在3年以来,根据一些粗略的估计,收录了超过5亿的照片。这意味着每天有上百万的新图片需要分析。分析一张照片不是大问题,就算是重复上百万次。但是要同步从10亿张照片中获取信息,在单台集群上时不容易的。
  同样的相似处理,Google新闻每天要处理350万新文章。虽然看起来是大量的项,这些文章需要被及时集群。
  Netflix发布的NetflixPrize含有1亿评分。着仅仅是公布出来做测试用的,Netflix总的数据可能每天要处理的推荐数据比这大几倍。
机器学习技术部署的环境就如:大量的不容易在一台机器甚至超级机器上处理的数据。没有如Mahout这样的实现,这几乎不可能。这也是为什么Mahout把可伸缩作为首要优先级,这也是这本书所关注的有效处理大量的数据。近年来,把复杂的机器学习技术部署在可伸缩的环境上只有大的高级的技术公司考虑用过。但是今天,随着计算能力的便宜和更易得到开源的框架如Apache Hadoop,Mahout将尝试完成这个迷局,提供一个高质量,在hadoop上可伸缩开源实现给所有技术公司。
  Mahout用的Haddoop是一个开源的,基于Java实现的MapReduce分布式计算框架类似与谷歌广泛应用的(http://labs.google.com/papers/mapreduce.html)。MapReduce第一次听起来是一个奇怪的编程范式,太简单但很强大。MapReduce范式解决问题的输入时键值对集。一个Map函数把这些键值对转成中间键值对,一个Reduce函数则把这些中间键值对合并并产生输出。实际上,许多问题可以用MapReduce来解决。这种范式在并行处理上非常好:所有的处理都是独立的,意味着计算可以被分解到许多机器上。这儿就不详细的阐述MapReduce了,我们推荐一个Hadoop提供的资料(http://hadoop.apache.org/mapreduce/docs/current/mapred_tutorial.html)。
Hadoop实现了MapReduce范式,它不是一个小的功劳,也不是说MapReduce听起来好简单。它需要管理输入的存储,中间键值对和输出;这些大量的数据必须在很多工作机上可用,不仅仅存储在本地。它也同时要分割这些数据和在工作机之间传输它们,且检测和恢复单机故障。理解了这些你知道了Hadoop需要处理多么复杂的工作。它不仅仅是一个你加到项目中的库。它包含几个部分,可能作为单机服务,也可能是在多个机器上。
操作Hadoop并不简单,但是在可伸缩,分布实现上投资时值得的:你的数据会很快增长到一个大数量级,这种可伸缩的实现是一种面向未来处理。
  在第6章,这本书讲试着在Hadoop上快速的运行一些复杂的例子,然后你可以探索更详细的操作集群并调试这个框架。因为这个复杂的框架需要大量的计算资源,所有并不奇怪云计算提供商提供了Hadoop相关的服务。例如:Amazon提供了弹性MapReduce(http://aws.amazon.com/elasticmapreduce/),一个管理Hadoop集群,提供计算能力,并提供了友好的界面来替代复杂任务的操作和监视运行在Hadoop上的大规模任务。

1.4 设置Mahout环境

  如果你要跟随本书操作本书的代码,你还需要一些工具。我们假设你已经有合适的java开发能力。Mahout及它相关的框架是基于Java的,平台独立的,即你可以在任何运行现代JVM的平台上运行它。有时需要提供不同平台的内容,如命令行命令在Windows下和Free BSD下不一样,所以这儿我们用Bash,这个在Linux发行版上,Mac OS X和其他Unix变种的,和Cygwin(一个在Windows上运行Unix的环境)都可以用。

Java和IDEs
  如果你运行过Java开发,Java已经可能安装上了。Mahout需要Java 6。Windows和Linux用户请从http://www.oracle.com/technetwork/java/下载,Apple已经提供了,请从/Applications/Utilities目录查看,并设置为默认Java。
  你可以需要下IDE来方便编程。参考如下:
Eclipse (http://www.eclipse.org)
NetBeans (http://netbeans.org/)
IntelliJ IDEA(http://www.jetbrains.com/idea/index.html)

安装Maven
  和其它Apache项目一样,Mahout的编译和发布都需要Maven(http://maven.apache.org)。着怎么安装不翻译了。
  
安装Mahout
  Mahout还在开发中,这本书用的是0.5版本的,需要从https://cwiki.apache.org/confluence/display/MAHOUT/Downloads下载。
  下载安装好后,可以从Manning的网站(http://www.manning.com/MahoutinAction/)或GitHub(https://github.com/tdunning/MiA)下载样例代码设置工作环境。
安装Hadoop
  Hadoop请自行安装,可以从http://hadoop.apache.org/common/releases.html下载0.20.2版本的,然后设置一个伪分布的单节点(http://hadoop.apache.org/common/docs/current/single_node_setup.html).

1.5 总结

  Mahout是一个Apache上年轻的,开源的和可伸缩的机器学习库。这本书就是利用Mahout使用机器学习技术解决现实问题的训练导览。你马上讲探索推荐引擎,集群和分类技术。如果你是机器学习的理论研究者,这本书讲引导你怎么把算法用于实践。我们已经为推荐引擎,集群和分类提供了部署在真实环境上的著名例子:商业,邮件,视频,图片和更多的可伸缩机器学习。这些技术被用来解决真实的问题并通过Mahout为企业带来了加载。本作品采用知识共享署名 4.0 国际许可协议进行许可。