3 推荐系统数据表示

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

本文链接地址: 3 推荐系统数据表示

本章包括
  Mahout怎么表示推荐系统数据
  DataModel实现和使用方法
  处理没有参考值的数据

  数据的质量很大的决定类推荐系统的质量。拥有高质量的数据是很好的,拥有大量的数据也好。推荐引擎需要从数据中获取大量信息,强烈受数据影响。因此运行性能大大地受数据质量和数据表示方式影响。聪明的选择数据结构可以影响性能的几个数量级,而且在大规模上,它影响更多。本章探索了Mahout表示和获取数据的几种关键类。你将知道为什么用Mahout中表示用户,项和参考值的方式将更加有效和可伸缩性。本章也详细的了解了Mahout的数据模型: DataModel。最终,我们将看看当数据没有评估值或参考值的情况,即布尔参考值。

3.1 参考数据表示

  推荐系统的输入是参考数据——谁喜欢什么,喜欢多少。即输入数据由用户ID,项ID 和参考值构成的元组表示,有些时候,甚至没有参考值。
参考数据对象
  一个参考数据对象由用户ID,项ID和参考值构成,表示用户ID对项ID的参考值是多少。Preference是接口,有多种实现。通常可以用GenericPreference。例如表示用户123对项456的参考值为3.0为new GenericPreference(123, 456, 3.0f)。可是参考数据集合怎么表示呢?使用Preference[]吗?如果你这么想,在Mahout里面就错了。通常GenericPreference由20字节的有用数据表示:8字节的用户ID(Java long),8字节的项ID(Java long)和4字节的参考值(float)。但每个对象有28字节的头信息:8字节的对象引用,另外的20字节用于描述对象自己,这样头信息就占了有用信息的140%。所以如果是Preference[]的化,就有很多冗余。

  参考数据数组和实现
PreferenceArray就是这种数组的实现。例如 GenericUser-PreferenceArray表示一个用户所关联的所以项以及每项的参考值。这种参考值的表示只需要12字节(8字节项ID和4字节参考值),只是原始的1/4。对比如下左右图可以看到是怎么实现的。

代码实现:

PreferenceArray user1Prefs = new GenericUserPreferenceArray(2);
user1Prefs.setUserID(0, 1L);
user1Prefs.setItemID(0, 101L);
user1Prefs.setValue(0, 2.0f);
user1Prefs.setItemID(1, 102L);
user1Prefs.setValue(1, 3.0f);
Preference pref = user1Prefs.get(1);

提高集合速度

FastByIDMap和FastIDSet
  Mahout大量的使用Map和Set,但是不使用Java提供的如TreeSet和HashMap,而使用自己定义的FastMap,FastByIDMap和FastIDSet。它们减少了内存占用,而不是显著提高性能。它们显著的几点不同:
就如HashMap,FastByIDMap也是基于hash的,它使用线性探测而不是使用分别的链来探测hash冲突,这避免了对每一项还有一个额外的Map.Entry对象。键值都是long型的而不是对象,这能提高不少性能。
  Set的实现不由Map实现。
  FastByIDMap就如一个缓存,它具有最大容量限制。当新项加入时,不常用的项将被删除。
  这些存储的区别是显著的:FastIDSet平均每项需要14字节,而HashSet需要84字节。FastByIDMap每项需要28字节,而HashMap需要84字节。

3.2 内存中的数据模型

  封装推荐引擎输入数据的是DataModel。不同的推荐引擎算法有各自的实现。例如,一个DataModel可以提供输入数据中用户ID的数量或列表,或提供每项的所有参考值,或提供对某个项集合有多少用户有过推荐值。这节只关注几个关键的,更多的请参考 (https://builds.apache.org/job/Mahout-Quality/javadoc/)。

通用数据模型
  GenericDataModel这是最简单的内存数据模型实现,当你要在内存中构建数据,而非使用文件或数据库时,它是合适的。它能简单的描述输入数据,通过如下代码的形式:

FastByIDMap preferences = new FastByIDMap();
PreferenceArray prefsForUser1 = new GenericUserPreferenceArray(10);
prefsForUser1.setUserID(0, 1L);
prefsForUser1.setItemID(0, 101L);
prefsForUser1.setValue(0, 3.0f);
prefsForUser1.setItemID(1, 102L);
prefsForUser1.setValue(1, 4.5f);
preferences.put(1L, prefsForUser1);
DataModel model = new GenericDataModel(preferences);

文件类型数据
  你可能不常直接用GenericDataModel,相反你需要FileDataModel,它从文件中读取数据把结果用GenericDataModel的形式存在内存中。任何可能的文件都可以,比如逗号分割文件,制表符分割文件,压缩文件。
可刷新组件
  当讨论加载数据时,很有必要说说重载数据,即刷新接口,Mahout的推荐系统相关类都有实现。它们通过一个刷新方法的暴露来完成数据的重载,重新计算。
需要注意的是,FileDataModel只有当你调用方法的时候才会去重载,而不算自动的。
  你可能不止要FileDataModel刷新,而且依赖它的对象也要刷新,所以为什么refresh方法需要在Recommender上了:

DataModel dataModel = new FileDataModel(new File("input.csv");
Recommender recommender = new SlopeOneRecommender(dataModel);
...
recommender.refresh(null);

更新文件

数据库类型数据
  有时数据太大以至于不能装配到内存中,这个时候就需要利用关系数据库来存取数据了。Mahout的几个推荐引擎就把计算结果存在类数据库中,但是请记住,利用数据库这种方式将减慢运行速度,即使合适的调优和索引,但是在过量的存取,序列化,反序列化时还是比内存方式慢好多。可有时没有办法,比如你的数据本来就存储在数据库中,需要集成时。
  JDBC和MySQL
  通过JDBC的实现为JDBCDataModel,如MySQL5.x: MySQLJDBCDataModel。
  配置JNDI
  这里请自己参考实现。
用程序配置
例如:

		MysqlDataSource dataSource = new MysqlDataSource();
		dataSource.setServerName("my_database_host");
		dataSource.setUser("my_user");
		dataSource.setPassword("my_password");
		dataSource.setDatabaseName("my_database_name");
		JDBCDataModel dataModel = new MySQLJDBCDataModel(dataSource, "my_prefs_table", "my_user_column",
				"my_item_column", "my_pref_value_column");

3.3 复制没有参考值的参考数据

  有时,参考数据是没有参考值的,只是证明用户和项由关系。比如新闻网站需要推荐文章给用户,但是要求用户去给文章打分好像不大现实,我们只知道用户看了这个文章而已。这种情况下就没有参考值。在Mahout中,这种参考数据就是布尔参考数据,即喜欢,不喜欢,或没关系。

什么时候忽略参考值
  什么时候忽略参考值?可能和上下文相关,如只关注喜欢或不喜欢。

使用内存表示没有参考值的参考数据
  Mahout中有专门用于存储没有参考值的数据模型GenericBooleanPrefDataModel。每条参考数据会少4字节。它仅仅存储用户和项的关联关系,使用FastIDSets。这种新的实现在某些方法调用上会快些,如getItemIDsForUser(),因为已经有实现;但有些方法会慢,如getPreferencesFromUser(),因为它没有PreferenceArrays,但必须实现这个方法。你会疑问getPreferenceValue()应该返回什么呢?它每次返回人为的值:1.0。
  关于GenericBooleanPrefDataModel,这儿有个例子:

		DataModel model = new GenericBooleanPrefDataModel(GenericBooleanPrefDataModel.toDataMap(new FileDataModel(
				new File("ua.base"))));
		RecommenderEvaluator evaluator = new AverageAbsoluteDifferenceRecommenderEvaluator();
		RecommenderBuilder recommenderBuilder = new RecommenderBuilder() {
			public Recommender buildRecommender(DataModel model) throws TasteException {
				UserSimilarity similarity = new PearsonCorrelationSimilarity(model);
				UserNeighborhood neighborhood = new NearestNUserNeighborhood(10, similarity, model);
				return new GenericUserBasedRecommender(model, neighborhood, similarity);
			}
		};
		DataModelBuilder modelBuilder = new DataModelBuilder() {
			public DataModel buildDataModel(FastByIDMap trainingData) {
				return new GenericBooleanPrefDataModel(GenericBooleanPrefDataModel.toDataMap(trainingData));
			}
		};
		double score = evaluator.evaluate(recommenderBuilder, modelBuilder, model, 0.9, 1.0);
		System.out.println(score);

选择兼容的实现方式
  你将发现使用上面的代码会有IllegalArgument-Exception产生,因为构造器是PearsonCorrelationSimilarity。为什么呢?GenericBooleanPrefDataModel也是数据模型啊?在计算相似性时,如EuclideanDistanceSimilarity拒绝工作当没有参考值时,因为即使计算,结果也是无意义的。为了解这个问题,必须选择合适的相似性计算维度,Log-LikelihoodSimilarity就是一个,因为它不依赖参考值。用它替换运行上面的代码,产生结果为0.0,即它能够合适的计算。它是正确的结果吗?是的。估计值和真实值的差异都是1,所以结果为0.测试本身是无效的,因为怎么都是结果0。但是精度和重现率还算有效的,看下面的代码:

		DataModel model = new GenericBooleanPrefDataModel(new FileDataModel(new File("ua.base")));
		RecommenderIRStatsEvaluator evaluator = new GenericRecommenderIRStatsEvaluator();
		RecommenderBuilder recommenderBuilder = new RecommenderBuilder() {
			@Override
			public Recommender buildRecommender(DataModel model) {
				UserSimilarity similarity = new LogLikelihoodSimilarity(model);
				UserNeighborhood neighborhood = new NearestNUserNeighborhood(10, similarity, model);
				return new GenericUserBasedRecommender(model, neighborhood, similarity);
			}
		};
		DataModelBuilder modelBuilder = new DataModelBuilder() {
			@Override
			public DataModel buildDataModel(FastByIDMap trainingData) {
				return new GenericBooleanPrefDataModel(GenericBooleanPrefDataModel.toDataMap(trainingData));
			}
		};
		IRStatistics stats = evaluator.evaluate(recommenderBuilder, modelBuilder, model, null, 10,
				GenericRecommenderIRStatsEvaluator.CHOOSE_THRESHOLD, 1.0);
		System.out.println(stats.getPrecision());
		System.out.println(stats.getRecall());

  结果如下,精度和重现率都是24.7。这不好,因为返回的推荐结果中大约1/4是好的,大约1/4的好推荐返回了。
我们来看看这个问题,在GenericUserBasedRecommender中,推荐引擎还是通过估计参考值来排序,但是这些参考值都是1.0,所以结果是无意义的。我们可以采用GenericBooleanPrefUserBasedRecommender,它将产生有意义的结果。它通过项的关联关系来度量相似用户,越相似的权重越大。替换后重新运行,结果为22.9,结果差不多,那是因为我们没有使用特别有效的推荐系统。

3.4 总结

略本作品采用知识共享署名 4.0 国际许可协议进行许可。

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 国际许可协议进行许可。

深入浅出Mahout(Mahout in Action)-目录

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

本文链接地址: 深入浅出Mahout(Mahout in Action)-目录

1 了解 Apache Mahout

1.1 Mahout的历史

1.2 Mahout机器学习主题

推荐引擎
集群
分类

1.3 Mahout和Hadoop的大型可伸缩

1.4 设置Mahout环境

Java和IDEs
安装Maven
安装Mahout
安装Hadoop

1.5 总结

第一部分 推荐

2 推荐系统介绍

2.1 定义一个推荐系统

2.2 运行第一个推荐引擎

创建输入
创建推荐系统
分析输出

2.3 评估一个推荐系统

训练数据和评分
运行推荐评估系统
获取结果

2.4 评估精度和重现能力

运行RecommenderIRStatsEvaluator
精度和重现能力问题

2.5 评估GroupLens数据集

分解输入
使用其它推荐系统试验

2.6 总结

3 推荐系统数据表示

3.1 参考数据表示

参考数据对象
参考数据数组和实现
提高集合速度
FastByIDMap和FastIDSet

3.2 内存中的数据模型

通用数据模型
文件类型数据
可刷新组件
更新文件
数据库类型数据
JDBC和MySQL
配置JNDI 33 用程序配置

3.3 复制没有参考值的参考数据

什么时候忽略参考值
使用内存表示没有参考值的参考数据
选择兼容的实现方式

3.4 总结

4 创建推荐系统

4.1 理解基于用户的推荐系统

什么时候推荐是错误的
什么时候推荐是正确的

4.2 探索基于用户的推荐系统

算法
用GenericUserBasedRecommender实现算法
使用GroupLens探索
探索用户的邻居数据
固定大小的邻居数据
基于阈值的邻居数据

4.3 探索相似性度量标准

基于皮尔逊相关性相似性度量
皮尔逊相似性问题
利用权值
使用欧几里得距离定义相似性
使用余弦定义相似性
用斯皮尔曼等级相关系数定义相似性
使用Tanimoto系数定义忽略参考值的相似性
使用对数似然函数测试比较得到更好的相似度量
推断参考值

4.4 基于商品的推荐系统

算法
探索基于商品的推荐系统

4.5 Slope-one推荐系统

算法
Slope-one实践
不同存储和内存考虑
预先计算

4.6 新的实验性推荐系统

基于奇异值分解的推荐系统
基于线性插值的推荐系统
基于集群的推荐系统

4.7 对比其它推荐系统

注入基于内容的计算到Mahout中
深入基于内容的推荐系统
和基于模型的推荐系统比较

4.8 总结

5 把推荐系统用于生产

5.1 分析一个来自dating网站的样例数据

5.2 找到一个有效的推荐系统

基于用户的推荐系统
基于商品的推荐系统
Slope-one推荐系统
评估精度和重现能力
评估性能

5.3 注入领域特性信息

利用定制的相似度量
推荐
基于内容
用IDRescorer修改推荐系统
合并性别信息到IDRescorer中
组建一个定制的推荐系统

5.4 向匿名用户推荐

使用PlusAnonymousUserDataModel添加临时用户
汇聚匿名用户

5.5 创建一个可以在网站上使用的推荐系统

打包一个WAR文件
测试部署

5.6 更新检测推荐系统

5.7 总结

6 分布式推荐系统

6.1 分析Wikipedia数据

规模化
评估分布计算的好处和坏处

6.2 设计一个分布的基于商品的算法

构建一个共现矩阵
计算出用户矢量
产生推荐结果
理解结果
分布实现

6.3 使用MapReduce实现分布式算法

介绍MapReduce
转换为MapReduce: 生成用户矢量
转换为MapReduce: 计算共现矩阵
转换为MapReduce: 考虑矩阵乘法
转换为MapReduce: 使用部分集做矩阵乘法
转换为MapReduce: 计算推荐

6.4 使用Hadoop运行MapReduces

部署Hadoop
使用Hadoop运行推荐算法
配置mappers和reducers

6.5 伪分布推荐系统

6.6 推荐系统的其他使用方式

在云端运算
推荐系统的非常规用法

6.7 总结

第二部分 集群

8 数据表示

8.1 可视化矢量

把数据转为矢量
准备Mahout使用的矢量

8.2 把文本文档转为矢量

使用TF-IDF改进权值
使用n-gram集合计算单词的依赖性

8.3 从文档生成矢量

8.4 使用归一化改进矢量

8.5 总结

9 Mahout中的集群算法

9.1 K均值集群

关于K均值
运行K均值集群
使用canopy集群找到合适的K
样例学习: 使用K均值集群新闻文章

9.2 超越K均值: 集群概览

技术163
不同种类的集群问题
不同的集群方法

9.3 模糊K均值集群

运行模糊K均值集群
怎样的模糊算好?
样例学习: 使用模糊K均值集群新闻文章

9.4 基于模型的集群

K均值的缺点
狄利克雷集群
运行一个基于模型的集群例子

9.5 使用隐含狄利克雷分布(LDA)的主题模型

理解隐含狄利克雷分析
TF-IDF与LDA
调优LDA的参数
样例学习: 找到新闻文章中的主题
主题模型的应用

9.6 总结

10 评估改进集群质量

10.1 检查集群输出

10.2 分析集群输出

距离度量与特征选择
集群之间和集群内部的距离
集群的混合和重叠

10.3 改进集群质量

改进文档矢量的生成
写一个自定义的距离度量

10.4 总结

11 把集群应用与生产上

11.1 运行集群到hadoop上的快速入门例子

在hadoop本地集群上运行
Hadoop参数的配置

11.2 调优集群性能

避免处理器受限操作的性能陷阱
避免I/O受限操作的性能陷阱

11.3 批量和在线集群

样例学习: 在线新闻集群
样例学习: 集群维基百科文章

11.4 总结

12 现实世界的集群程序

12.1 在Twitter上查找相似的用户

数据处理与特征权值化
在特征选择上避免常见的陷阱

12.2 Last.fm上的艺术家建议标签

标签建议的共现矩阵
创建Last.fm艺术家词典
把Last.fm标签转成以音乐家为特征的矢量
在Last.fm数据上运行K均值集群

12.3 分析Stack Overflow数据集

得到Stack Overflow数据集
在Stack Overflow数据上集群的问题

12.4 总结

第三部分 分类

13 分类介绍

13.1 为什么使用Mahout分类

13.2 分类系统的原理

分类,推荐和集群的不同
分类应用

13.3 分类是怎么工作的

模型
训练,测试与生产
预测变量与目标变量
记录,字段和值
预测变量值的四种类型
监督与非监督学习

13.4 典型的分类过程流程

第一步: 训练分类模型
第二步: 评估分类模型
第三步: 使用模型在生产上分类

13.5 手把手的简单分类例子

数据与挑战
训练一个模型来进行着色分类: 初步想法
选择一个算法来分类
提高着色分类器的性能

13.6 总结

14 训练分类器

14.1 提取特征来构建一个Mahout分类器

14.2 预处理元数据到分类数据

转换元数据
处理一个市场数据的例子

14.3 把分类数据转化为矢量

用矢量表示数据
使用Mahout APIs hash特征

14.4 使用SGD分类对20 newsgroups数据进行分类

预览数据
从 20 newsgroups数据中获取特征
20 newsgroups数据的训练代码

14.5 选择一个算法来训练分类器

非并行但功能强大: 使用SGD和SVM
功能强大的贝叶斯分类: 使用朴素贝叶斯和互补朴素贝叶斯
复杂结构上的优势: 使用随机森林

14.6 使用朴素贝叶斯对20 newsgroups数据进行分类

数据分解
训练朴素贝叶斯分类器
测试朴素贝叶斯分类器

14.7 总结

15 评估和调优分类器

15.1 Mahout中的分类器评估

获取快速的回应
决定什么是好的方法
认识不同的错误代价

15.2 分类器评估API

计算AUC
混淆矩阵和熵矩阵
计算平均log似然度
分析模型
使用SGD对20 newsgroups分类的性能

15.3 什么时候一个分类器不好

目标泄露
不好的特征提取

15.4 调优性能

调节问题
调节分类器

15.5 总结

16 部署分类器

16.1 在大型系统中部署

问题的范围
按需优化特征提取
按需优化矢量
部署一个可伸缩的分类服务

16.2 确定规模和速度的要求

多大就可以了?
平衡大和速度

16.3 在大系统上构建一个训练管道

获取与重新训练可伸缩的数据
反规范化和下采样
训练陷阱
高速的读取编码数据

16.4 集成Mahout分类器

集成的关节问题
模型序列化

16.5 例子: 基于Thrift的分类器

运行一个分类器服务器
获取分类服务

16.6 总结

17 样例学习: Shop It To Me

17.1 为什么Shop It To Me选择Mahout

Shop It To Me做什么342
为什么Shop It To Me需要一个分类系统
Mahout解决剩下的问题

17.2 Email销售系统的通常结构

17.3 训练模型

定义分类工程的目标
使用时间分区
避免目标泄露
学习算法调整
特征矢量编码

17.4 提速分类器

特征向量的线性组合
模型分数的线性膨胀

17.5 总结

本作品采用知识共享署名 4.0 国际许可协议进行许可。

Visualizing the Dirichlet | A Computer Scientist in a Business School

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

本文链接地址: Visualizing the Dirichlet | A Computer Scientist in a Business School

Visualizing the Dirichlet | A Computer Scientist in a Business School.

本作品采用知识共享署名 4.0 国际许可协议进行许可。