您的位置:首页 > 运维架构 > Apache

Mahout协同过滤

2017-01-20 11:23 393 查看

Mahout协同过滤

1.Mahout是什么

Mahout是一个算法库,集成了很多算法
Apache Mahout是Apache Software Foundation(ASF)旗下的一个开源项目,提供一些可拓展的机器学习领域经典算法的实现,
旨在帮助开发人员更加方便快捷地创建智能应用程序
Mahout项目目前已经有了多个公共发行版本。Mahout包含许多实现,包括聚类、分类、推荐过滤、频繁子项目挖掘
通过使用Apache Hadoop库,Mahout可以有效地拓展到Hadoop集群。
Mahout的创始人Grant Ingersoll介绍了机器学习的基本概念,并演示了如何使用Mahout来实现文档集群、提出建议和组织内容


2.Mahout能做什么

2.1.推荐引擎

在目前采用的机器学习技术中,推荐引擎是最容易被一眼认出来的,也是应用范围最广的。
服务商或网站会根据你过去的行为为你推荐书籍、电影或文章。
在部署了推荐系统的电子商务中,亚马逊大概是最有名的。亚马逊基于用户的交易行为和网站记录为你推荐你可能喜欢的商品
而facebook这样的社交网络则利用推荐技术为你找到最可能尚未关联的朋友
同时,这一技术也被各大知名国内网站所使用,如腾讯、人人、京东、淘宝


2.2.聚类

顾名思义,物以类聚,人以群为。聚类是把具有共同属性的物品进行归类
Google news使用聚类技术通过标题把新闻文章进行分组,从而按照逻辑线索来显示新闻,而并非给出所有新闻的原始列表


2.3.分类

分类技术决定了一个事物多大程度上从属于某种类别或类型,或者多大程度上具有或者不具有某些属性。
与聚类一样,分类无处不在,但更多隐身于幕后。通常这些系统会考察类别中的大量实例,来学习推导分类的规则
雅虎邮箱基于用户以前对正常邮件和垃圾邮件的报告,以及电子邮件自身的特征,来判别到来的消息是否是垃圾邮件


3.Mahout协同过滤算法

Mahout使用了Taste来提高协同过滤算法的实现,它是一个基于Java实现的可扩展的,高效的推荐引擎。
Taste既实现了最基本的基于用户的和基于内容的推荐算法,同时也提供了扩展接口,使用户可以方便的定义和实现自己的推荐算法。
同时,Taste不仅仅只适用于Java应用程序,它可以作为内部服务器的一个组件以HTTP和Web Service的形式向外界提供推荐的逻辑。
Taste的设计使它能满足企业对推荐引擎在性能、灵活性和可扩展性等方面的要求。

Taste主要包括以下几个接口:
DataModel 是用户喜好信息的抽象接口,它的具体实现支持从任意类型的数据源抽取用户喜好信息。
Taste 默认提供 JDBCDataModel 和 FileDataModel,分别支持从数据库和文件中读取用户的喜好信息。

UserSimilarity 和 ItemSimilarity 。
UserSimilarity 用于定义两个用户间的相似度,它是基于协同过滤的推荐引擎的核心部分,可以用来计算用户的“邻居”,
这里我们将与当前用户口味相似的用户称为他的邻居。ItemSimilarity 类似的,计算Item之间的相似度。

UserNeighborhood 用于基于用户相似度的推荐方法中,推荐的内容是基于找到与当前用户喜好相似的邻居用户的方式产生的。
UserNeighborhood 定义了确定邻居用户的方法,具体实现一般是基于 UserSimilarity 计算得到的。

Recommender 是推荐引擎的抽象接口,Taste 中的核心组件。程序中,为它提供一个 DataModel,它可以计算出对不同用户的推荐内容。
实际应用中,主要使用它的实现类 GenericUserBasedRecommender 或者 GenericItemBasedRecommender,
分别实现基于用户相似度的推荐引擎或者基于内容的推荐引擎。

RecommenderEvaluator :评分器。

RecommenderIRStatsEvaluator :搜集推荐性能相关的指标,包括准确率、召回率等等。


3.1.DataModel

org.apache.mahout.cf.taste.impl.model.GenericDataModel
org.apache.mahout.cf.taste.impl.model.GenericBooleanPrefDataModel
org.apache.mahout.cf.taste.impl.model.PlusAnonymousUserDataModel
org.apache.mahout.cf.taste.impl.model.file.FileDataModel
org.apache.mahout.cf.taste.impl.model.hbase.HBaseDataModel
org.apache.mahout.cf.taste.impl.model.cassandra.CassandraDataModel
org.apache.mahout.cf.taste.impl.model.mongodb.MongoDBDataModel
org.apache.mahout.cf.taste.impl.model.jdbc.SQL92JDBCDataModel
org.apache.mahout.cf.taste.impl.model.jdbc.MySQLJDBCDataModel
org.apache.mahout.cf.taste.impl.model.jdbc.PostgreSQLJDBCDataModel
org.apache.mahout.cf.taste.impl.model.jdbc.GenericJDBCDataModel
org.apache.mahout.cf.taste.impl.model.jdbc.SQL92BooleanPrefJDBCDataModel
org.apache.mahout.cf.taste.impl.model.jdbc.MySQLBooleanPrefJDBCDataModel
org.apache.mahout.cf.taste.impl.model.jdbc.PostgreBooleanPrefSQLJDBCDataModel
org.apache.mahout.cf.taste.impl.model.jdbc.ReloadFromJDBCDataModel
从类名上就可以大概猜出来每个DataModel的用途,奇怪的是竟然没有HDFS的DataModel,有人实现了一个,请参考 MAHOUT-1579


3.2.相似度

UserSimilarity 和 ItemSimilarity 相似度实现有以下几种:
CityBlockSimilarity :基于Manhattan距离相似度
EuclideanDistanceSimilarity :基于欧几里德距离计算相似度
LogLikelihoodSimilarity :基于对数似然比的相似度
PearsonCorrelationSimilarity :基于皮尔逊相关系数计算相似度
SpearmanCorrelationSimilarity :基于皮尔斯曼相关系数相似度
TanimotoCoefficientSimilarity :基于谷本系数计算相似度
UncenteredCosineSimilarity :计算 Cosine 相似度


3.3.最近邻域

UserNeighborhood 主要实现有两种:
NearestNUserNeighborhood:对每个用户取固定数量N个最近邻居
ThresholdUserNeighborhood:对每个用户基于一定的限制,取落在相似度限制以内的所有用户为邻居


3.4.推荐引擎

Recommender分为以下几种实现:
GenericUserBasedRecommender:基于用户的推荐引擎
GenericBooleanPrefUserBasedRecommender:基于用户的无偏好值推荐引擎
GenericItemBasedRecommender:基于物品的推荐引擎
GenericBooleanPrefItemBasedRecommender:基于物品的无偏好值推荐引擎


3.5.推荐系统评测

RecommenderEvaluator有以下几种实现:
AverageAbsoluteDifferenceRecommenderEvaluator :计算平均差值
RMSRecommenderEvaluator :计算均方根差


4.Mahout协同过滤算法编程

4.1.创建Maven项目











4.2.导入Mahout依赖

pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion>

<groupId>com.matrix</groupId>
<artifactId>Mahout</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>

<name>Mahout</name>

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>

<dependencies>
<dependency>
<groupId>jdk.tools</groupId>
<artifactId>jdk.tools</artifactId>
<version>1.7</version>
<scope>system</scope>
<systemPath>${JAVA_HOME}/lib/tools.jar</systemPath>
</dependency>
<dependency>
<groupId>org.apache.mahout</groupId>
<artifactId>mahout-examples</artifactId>
<version>0.11.2</version>
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
</dependency>
</dependencies>
</project>


4.3.下载电影评分数据

下载地址:http://grouplens.org/datasets/movielens/
数据类别:7.2万用户对1万部电影的百万级评价和10万个标签数据










4.4.编写基于用户的推荐

BaseUserRecommender.java

package com.matrix.Mahout;

import java.io.File;
import java.util.List;

import org.apache.mahout.cf.taste.impl.neighborhood.NearestNUserNeighborhood;
import org.apache.mahout.cf.taste.impl.recommender.GenericUserBasedRecommender;
import org.apache.mahout.cf.taste.impl.similarity.PearsonCorrelationSimilarity;
import org.apache.mahout.cf.taste.model.DataModel;
import org.apache.mahout.cf.taste.neighborhood.UserNeighborhood;
import org.apache.mahout.cf.taste.recommender.RecommendedItem;
import org.apache.mahout.cf.taste.recommender.Recommender;
import org.apache.mahout.cf.taste.similarity.UserSimilarity;
import org.apache.mahout.cf.taste.similarity.precompute.example.GroupLensDataModel;

/**
* 迄今为止在个性化推荐系统中,协同过滤(Collaborative Filtering)技术是应用最成功的技术。
* 目前国内外互联网上有许多大型网站已经应用这项技术为用户更加智能的推荐内容。
* 如果你想要研究协同过滤,一定不能错过MovieLens(http://movielens.umn.edu/)。它是协同过滤最著名的研究项目之一。
* 第一代协同过滤算法
*
* Recommender<BR>
* 创建人:Matrix <BR>
* 时间:2017年1月19日-下午6:34:46 <BR>
* @version 1.0.0
*
*/
public class BaseUserRecommender {

public static void main(String[] args) throws Exception {
//准备数据 这里是电影评分数据
File file = new File("F:\\software\\workstation\\Mahout\\ratings.dat");
//将数据加载到内存中,GroupLensDataModel是针对开放电影评论数据的
DataModel dataModel = new GroupLensDataModel(file);
//计算相似度,相似度算法有很多种,欧几里得、皮尔逊等等。
UserSimilarity similarity = new PearsonCorrelationSimilarity(dataModel);
//计算最近邻域,邻居有两种算法,基于固定数量的邻居和基于相似度的邻居,这里使用基于固定数量的邻居
UserNeighborhood userNeighborhood = new NearestNUserNeighborhood(100, similarity, dataModel);
//构建推荐器,协同过滤推荐有两种,分别是基于用户的和基于物品的,这里使用基于用户的协同过滤推荐
Recommender recommender = new GenericUserBasedRecommender(dataModel, userNeighborhood, similarity);
//推荐10部电影给id为5的用户
List<RecommendedItem> recommendedItemList = recommender.recommend(5, 10);
//打印推荐的结果
System.out.println("使用基于用户的协同过滤算法");
System.out.println("为用户5推荐10个商品");
for (RecommendedItem recommendedItem : recommendedItemList) {
System.out.println(recommendedItem);
}
}
}






4.5.编写基于物品的推荐

BaseItemRecommender.java

package com.matrix.Mahout;

import org.apache.mahout.cf.taste.impl.recommender.GenericItemBasedRecommender;
import org.apache.mahout.cf.taste.impl.similarity.PearsonCorrelationSimilarity;
import org.apache.mahout.cf.taste.model.DataModel;
import org.apache.mahout.cf.taste.recommender.RecommendedItem;
import org.apache.mahout.cf.taste.similarity.ItemSimilarity;
import org.apache.mahout.cf.taste.similarity.precompute.example.GroupLensDataModel;

import java.io.File;
import java.util.List;

/**
* Describe:
* 与基于用户的技术不同的是,这种方法比较的是内容项与内容项之间的相似度。
* Item-based 方法同样需要进行三个步骤获得推荐:
* 1)得到内容项(Item)的历史评分数据;
* 2)针对内容项进行内容项之间的相似度计算,找到目标内容项的“最近邻居”;
* 3)产生推荐。这里内容项之间的相似度是通过比较两个内容项上的用户行为选择矢量得到的。
* 第二代协同过滤算法
*
* BaseItemRecommender<BR>
* 创建人:Matrix <BR>
* 时间:2017年1月19日-下午7:19:33 <BR>
* @version 1.0.0
*
*/
public class BaseItemRecommender {

public static void main(String[] args) throws Exception {
//准备数据 这里是电影评分数据
File file = new File("F:\\software\\workstation\\Mahout\\ratings.dat");
//将数据加载到内存中,GroupLensDataModel是针对开放电影评论数据的
DataModel dataModel = new GroupLensDataModel(file);
//计算相似度,相似度算法有很多种,欧几里得、皮尔逊等等。
ItemSimilarity itemSimilarity = new PearsonCorrelationSimilarity(dataModel);
//构建推荐器,协同过滤推荐有两种,分别是基于用户的和基于物品的,这里使用基于物品的协同过滤推荐
GenericItemBasedRecommender recommender = new GenericItemBasedRecommender(dataModel, itemSimilarity);
//给用户ID等于5的用户推荐10个与2398相似的商品
List<RecommendedItem> recommendedItemList = recommender.recommendedBecause(5, 2398, 10);
//打印推荐的结果
System.out.println("使用基于物品的协同过滤算法");
System.out.println("根据用户5当前浏览的商品2398,推荐10个相似的商品");
for (RecommendedItem recommendedItem : recommendedItemList) {
System.out.println(recommendedItem);
}
long start = System.currentTimeMillis();
recommendedItemList = recommender.recommendedBecause(5, 34, 10);
//打印推荐的结果
System.out.println("使用基于物品的协同过滤算法");
System.out.println("根据用户5当前浏览的商品2398,推荐10个相似的商品");
for (RecommendedItem recommendedItem : recommendedItemList) {
System.out.println(recommendedItem);
}
System.out.println(System.currentTimeMillis() -start);
}
}






4.6.评估推荐模型

MyEvaluator.java

package com.matrix.Mahout;

import org.apache.mahout.cf.taste.common.TasteException;
import org.apache.mahout.cf.taste.eval.RecommenderBuilder;
import org.apache.mahout.cf.taste.eval.RecommenderEvaluator;
import org.apache.mahout.cf.taste.impl.eval.AverageAbsoluteDifferenceRecommenderEvaluator;
import org.apache.mahout.cf.taste.impl.neighborhood.NearestNUserNeighborhood;
import org.apache.mahout.cf.taste.impl.recommender.GenericUserBasedRecommender;
import org.apache.mahout.cf.taste.impl.similarity.PearsonCorrelationSimilarity;
import org.apache.mahout.cf.taste.model.DataModel;
import org.apache.mahout.cf.taste.neighborhood.UserNeighborhood;
import org.apache.mahout.cf.taste.recommender.Recommender;
import org.apache.mahout.cf.taste.similarity.UserSimilarity;
import org.apache.mahout.cf.taste.similarity.precompute.example.GroupLensDataModel;
import java.io.File;

/**
* 获取推荐模型的评分
*
* MyEvaluator<BR>
* 创建人:Matrix <BR>
* 时间:2017年1月19日-下午10:03:56 <BR>
* @version 1.0.0
*
*/
public class MyEvaluator {

public static void main(String[] args) throws Exception {
//准备数据 这里是电影评分数据
File file = new File("F:\\software\\workstation\\Mahout\\ratings.dat");
//将数据加载到内存中,GroupLensDataModel是针对开放电影评论数据的
DataModel dataModel = new GroupLensDataModel(file);
//推荐评估,使用均方根
//RecommenderEvaluator evaluator = new RMSRecommenderEvaluator();
//推荐评估,使用平均差值
RecommenderEvaluator evaluator = new AverageAbsoluteDifferenceRecommenderEvaluator();
RecommenderBuilder builder = new RecommenderBuilder() {
public Recommender buildRecommender(DataModel dataModel) throws TasteException {
UserSimilarity similarity = new PearsonCorrelationSimilarity(dataModel);
UserNeighborhood neighborhood = new NearestNUserNeighborhood(2, similarity, dataModel);
return new GenericUserBasedRecommender(dataModel, neighborhood, similarity);
}
};
// 用70%的数据用作训练,剩下的30%用来测试
double score = evaluator.evaluate(builder, null, dataModel, 0.7, 1.0);
//最后得出的评估值越小,说明推荐结果越好
System.out.println(score);
}
}


4.7.获取推荐的查准率和查全率

MyIRStatistics.java

package com.matrix.Mahout;

import org.apache.mahout.cf.taste.common.TasteException;
import org.apache.mahout.cf.taste.eval.IRStatistics;
import org.apache.mahout.cf.taste.eval.RecommenderBuilder;
import org.apache.mahout.cf.taste.eval.RecommenderIRStatsEvaluator;
import org.apache.mahout.cf.taste.impl.eval.GenericRecommenderIRStatsEvaluator;
import org.apache.mahout.cf.taste.impl.neighborhood.NearestNUserNeighborhood;
import org.apache.mahout.cf.taste.impl.recommender.GenericUserBasedRecommender;
import org.apache.mahout.cf.taste.impl.similarity.PearsonCorrelationSimilarity;
import org.apache.mahout.cf.taste.model.DataModel;
import org.apache.mahout.cf.taste.neighborhood.UserNeighborhood;
import org.apache.mahout.cf.taste.recommender.Recommender;
import org.apache.mahout.cf.taste.similarity.UserSimilarity;
import org.apache.mahout.cf.taste.similarity.precompute.example.GroupLensDataModel;

import java.io.File;

/**
* 获取推荐结果的查准率和召回率
*
* MyIRStatistics<BR>
* 创建人:Matrix <BR>
* 时间:2017年1月19日-下午10:02:59 <BR>
* @version 1.0.0
*
*/
public class MyIRStatistics {

public static void main(String[] args) throws Exception {
//准备数据 这里是电影评分数据
File file = new File("F:\\software\\workstation\\Mahout\\ratings.dat");
//将数据加载到内存中,GroupLensDataModel是针对开放电影评论数据的
DataModel dataModel = new GroupLensDataModel(file);
RecommenderIRStatsEvaluator statsEvaluator = new GenericRecommenderIRStatsEvaluator();
RecommenderBuilder recommenderBuilder = new RecommenderBuilder() {
public Recommender buildRecommender(DataModel model) throws TasteException {
UserSimilarity similarity = new PearsonCorrelationSimilarity(model);
UserNeighborhood neighborhood = new NearestNUserNeighborhood(4, similarity, model);
return new GenericUserBasedRecommender(model, neighborhood, similarity);
}
};
// 计算推荐4个结果时的查准率和召回率
//使用评估器,并设定评估期的参数
//4表示"precision and recall at 4"即相当于推荐top4,然后在top-4的推荐上计算准确率和召回率
IRStatistics stats = statsEvaluator.evaluate(recommenderBuilder, null, dataModel, null, 4, GenericRecommenderIRStatsEvaluator.CHOOSE_THRESHOLD, 1.0);
System.out.println(stats.getPrecision());
System.out.println(stats.getRecall());
}
}


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息