Mahout:
Apache Mahout 是 Apache Software Foundation(ASF)旗下的一个开源项目,提供一些可扩展的机器学习领域经典算法的实现,旨在帮助开发人员更加方便快捷地创建智能应用程序。Mahout项目目前已经有了多个公共发行版本。Mahout包含许多实现,包括聚类、分类、推荐过滤、频繁子项挖掘。通过使用 Apache Hadoop 库,Mahout 可以有效地扩展到Hadoop集群。
推荐系统的数学原理:
以最简单的基于协同过滤而言,其数学原理在最简化抽象形式而言就是比较两个对象之间的余弦相似度。其比较值越小说明两者相似度越小(三维空间中两对象非平行或近乎垂直状态,多维空间更为复杂)。下面就常见算法做出介绍。
关联分析:
本例不做介绍。
基于用户:
设存在User1、User2、User3三个用户,Goods A、Goods B、Goods C三个商品。其中User Background表描述了用户之间的信息背景相似度。可以明显看出User1与User2是比较相似的,那么就认为User1喜爱的Goods A同样也应该被User2所喜爱。
基于产品:
设存在User1、User2、User3三个用户,Goods A、Goods B、Goods C三个商品。其中Goods Background表描述了物品之间的信息背景相似度。可以明显看出Goods A与Goods B是比较相似的,那么就认为喜爱的Goods A的用户同样也喜爱Goods B。
协同过滤:
协同过滤简单来说是利用某兴趣相投、拥有共同经验之群体的喜好来推荐用户感兴趣的信息,个人通过合作的机制给予信息相当程度的回应(如评分)并记录下来以达到过滤的目的进而帮助别人筛选信息,回应不一定局限于特别感兴趣的,特别不感兴趣信息的纪录也相当重要。基于用户和产品属于协同过滤的算法,NNS与KNN也属于。
系统架构:
一个标准的IS架构(仅涉及推荐部分)如图所示。当然具体的系统实际上架构是不一样的。尤其是针对海量用户而言对其做出推荐喜好分析是一件特别耗费资源的事,再加上微服务大行其道的今天,单独为IS配备服务器也是常见的。小型的系统可能架构方面没有这么讲究,推荐接口配合用户数据库加上推荐规则和输出接口就构成了一个简单的IS架构。
常见接口/类:
Recommender类:
-
GenericUserBasedRecommender
:基于用户的推荐器,用户数量少时速度快; -
GenericItemBasedRecommender
:基于商品推荐器,商品数量少时速度快,尤其当外部提供了商品相似度数据后效率更好; -
SlopeOneRecommender
:基于slope-one算法的推荐器,在线推荐或更新较快,需要事先大量预处理运算,物品数量少时较好; -
SVDRecommender
:奇异值分解,推荐效果较好,但之前需要大量预处理运算; -
KnnRecommender
:基于k近邻算法(KNN),适合于物品数量较小时; -
TreeClusteringRecommender
:基于聚类的推荐器,在线推荐较快,之前需要大量预处理运算,用户数量较少时效果好
Similarity类:
-
CityBlockSimilarity
:基于Manhattan距离相似度 -
EuclideanDistanceSimilarity
:基于欧几里德距离计算相似度 -
LogLikelihoodSimilarity
:基于对数似然比的相似度 -
PearsonCorrelationSimilarity
:基于皮尔逊相关系数计算相似度 -
SpearmanCorrelationSimilarity
:基于皮尔斯曼相关系数相似度 -
TanimotoCoefficientSimilarity
:基于谷本系数计算相似度 -
UncenteredCosineSimilarity
:计算 Cosine 相似度
接口:
-
DataModel
是用户喜好信息的抽象接口,它的具体实现支持从任意类型的数据源抽取用户喜好信息。Taste 默认提供 * JDBCDataModel 和 FileDataModel,分别支持从数据库和文件中读取用户的喜好信息。 -
UserSimilarity
和ItemSimilarity
。UserSimilarity 用于定义两个用户间的相似度,它是基于协同过滤的推荐引擎的核心部分,可以用来计算用户的“邻居”,这里我们将与当前用户口味相似的用户称为他的邻居。ItemSimilarity 类似的,计算内容之间的相似度。 -
UserNeighborhood
用于基于用户相似度的推荐方法中,推荐的内容是基于找到与当前用户喜好相似的邻居用户的方式产生的。UserNeighborhood 定义了确定邻居用户的方法,具体实现一般是基于 UserSimilarity 计算得到的。 -
Recommender
是推荐引擎的抽象接口,Taste 中的核心组件。程序中,为它提供一个 DataModel,它可以计算出对不同用户的推荐内容。实际应用中,主要使用它的实现类 GenericUserBasedRecommender 或者 GenericItemBasedRecommender,分别实现基于用户相似度的推荐引擎或者基于内容的推荐引擎。 -
RecommenderEvaluator
:评分器。 -
RecommenderIRStatsEvaluator
:搜集推荐性能相关的指标,包括准确率、召回率等等
数据格式:
Mahout支持数据库、文本文件、csv文件等格式。
数据库要求格式:
- 用户ID列需要是BIGINT而且非空
- 物品ID列需要是BIGINT而且非空
- 用户喜好值列需要是FLOAT
- 建议在用户ID和物品ID上建索引
文本文件:
- 每一行包含一个用户id,物品id,用户喜好
- 逗号隔开或者Tab隔开
csv格式:
- 每一行包含一个用户id,物品id,用户喜好
- 逗号隔开或者Tab隔开
Java示例:
数据源:test.dat(为了方便记事本创建即可)
1,1,1.5
1,2,1.8
1,3,2.0
1,4,4.5
1,5,4.9
2,1,0.5
2,2,0.2
2,3,3.8
2,4,4.2
2,5,1.2
3,1,3.5
3,2,4.2
3,3,2.3
3,4,1.2
3,5,1.3
4,1,1.5
4,2,1.2
4,3,1.6
4,4,1.9
4,5,1,8
5,1,3.4
5,2,4.5
5,3,2.3
5,4,1.3
5,5,1.2
6,1,1.5
6,2,2.0
6,3,2.2
6,4,4.2
6,5,4.1
使用步骤:
- 创建DataModel模型,可以基于文件File的DataModel,也可基于数据库的JDBCDataModel;
- 计算相似度;
- 构建推荐器,基于用户或基于内容进行推荐;
- 传入基本参数用于计算用户的推荐(如用户id、商品id、待推荐的物品数目范围值)。
代码:
File file = new File("M:\\test.dat");
// 实例化DataModel并将数据传入其内
DataModel dataModel = null;
try {
dataModel = new FileDataModel(file);
} catch (IOException e) {
e.printStackTrace();
}
// 计算相似度
ItemSimilarity itemSimilarity = null;
try {
itemSimilarity = new PearsonCorrelationSimilarity(dataModel);
} catch (TasteException e) {
e.printStackTrace();
}
// 构建推荐器,使用基于物品的协同过滤推荐
GenericItemBasedRecommender recommender = new GenericItemBasedRecommender(dataModel, itemSimilarity);
List<RecommendedItem> recommendedItemList = null;
try {
// 计算用户2当前浏览的商品2,推荐2个相似的商品
recommendedItemList = recommender.recommendedBecause(2, 2, 2);
} catch (TasteException e) {
e.printStackTrace();
}
System.out.println("使用基于物品的协同过滤算法");
System.out.println("根据用户2当前浏览的商品2,推荐2个相似的商品");
for (RecommendedItem recommendedItem : recommendedItemList) {
System.out.println(recommendedItem);
}
long start = System.currentTimeMillis();
try {
recommendedItemList = recommender.recommendedBecause(5, 1, 3);
} catch (TasteException e) {
e.printStackTrace();
}
System.out.println("使用基于物品的协同过滤算法");
System.out.println("根据用户5当前浏览的商品1,推荐3个相似的商品");
for (RecommendedItem recommendedItem : recommendedItemList) {
System.out.println(recommendedItem);
}
System.out.println(System.currentTimeMillis() -start);
结果:
依赖:
<dependency>
<groupId>org.apache.mahout</groupId>
<artifactId>mahout-core</artifactId>
<version>0.9</version>
</dependency>
<dependency>
<groupId>org.apache.mahout</groupId>
<artifactId>mahout-integration</artifactId>
<version>0.9</version>
</dependency>
<dependency>
<groupId>org.apache.mahout</groupId>
<artifactId>mahout-math</artifactId>
<version>0.9</version>
</dependency>
<dependency>
<groupId>org.apache.mahout</groupId>
<artifactId>mahout-examples</artifactId>
<version>0.9</version>
</dependency>