原文:http://blog.selfup.cn/1001.html
什么是协同过滤
协同过滤(Collaborative Filtering, 简称CF),wiki上的定义是:简单来说是利用某兴趣相投、拥有共同经验之群体的喜好来推荐使用者感兴趣的资讯,个人透过合作的机制给予资讯相当程度的回应(如评分)并记录下来以达到过滤的目的进而帮助别人筛选资讯,回应不一定局限于特别感兴趣的,特别不感兴趣资讯的纪录也相当重要。
以上定义太拗口,举个简单的例子:我现在多年不看日本anime的新番了,最近突然又想看几部新番,但又不知道这么多新番中看哪些比较好,于是我就找几个同样喜欢日本动漫的朋友来咨询。我第一个想咨询的朋友是和我口味最像的,我们都特别喜欢看《虫师》、《黑之契约者》、《寒蝉》这样的小众动画;我问的第二个朋友和我口味差不多,他特别喜欢看《钢炼》《无头骑士异闻录》这样的动画,我虽然喜欢,但不像他那么喜欢;由于身边喜欢日本动画的朋友不多,剩下第三个可以咨询的是一个宅女,平常经常看腐、宅、基的动漫,完全跟我不是一路人,于是问了下她推荐的片子,并将这些片子打上的黑名单的标签。然后我就开始看第一个朋友推荐的片子了,要是时间特别多又很无聊我可能会看第二个朋友推荐的,但打死我也不会看第三个朋友推荐的。这就是协同过滤的一个简化、小众版。
如何进行相似度度量
接着上面的例子,我可以通过我和其它朋友共同喜欢某个或某类动漫来确定我们的口味是否一样,那么如何以数学或者机器的形式来表示这个“口味一样”呢?通常,是通过“距离”来表示,例如:欧几里得距离、皮尔逊相关度、曼哈顿距离、Jaccard系数等等。
欧几里得距离
欧几里德距离(Euclidean Distance),最初用于计算欧几里得空间中两个点的距离,在二维空间中,就是我们熟悉的两点间的距离,x、y表示两点,维度为n:
相似度:
皮尔逊相关度
皮尔逊相关度(Pearson Correlation Coefficient),用于判断两组数据与某一直线拟合程度的一种度量,取值在[-1,1]之间。当数据不是很规范的时候(如偏差较大),皮尔逊相关度会给出较好的结果。
曼哈顿距离
曼哈顿距离(Manhattan distance),就是在欧几里得空间的固定直角坐标系上两点所形成的线段对轴产生的投影的距离总和。
Jaccard系数
Jaccard系数,也称为Tanimoto系数,是Cosine相似度的扩展,也多用于计算文档数据的相似度。通常应用于x为布尔向量,即各分量只取0或1的时候。此时,表示的是x,y的公共特征的占x,y所占有的特征的比例:
计算推荐
根据上述“距离”的算法,我们可以找出与自己“口味一样”的人了,但这并不是目的,目的是找出推荐的物品。一种常用的做法是选出与你兴趣相同的N个人,然后根据这N个人的记录来进行加权推荐。具体如下,假设已经计算出欧几里得相似度:
A | 0.95 | 10.0 | 9.5 | 9.0 | 8.55 | - | - |
B | 0.80 | 8.5 | 6.8 | 7.5 | 6 | 5.0 | 4 |
C | 0.25 | - | - | 6.5 | 1.625 | 9.0 | 2.25 |
总计 | 16.3 | 16.175 | 6.25 | ||||
Sim.Sum | 1.75 | 2 | 1.05 | ||||
总计/Sim.Sum | 9.31 | 8.09 | 5.95 |
其中,S.x开头的表示相似度与评分的乘积,Sim.Sum表示打过分的朋友的相似度之和。可以看出根据三位友人的推荐,我从这三部动漫中应该选择银魂来看。
Item CF与User CF
基于用户的协同过滤(User CF),其基本思想相当简单,基于用户对物品的偏好找到相邻邻居用户,然后将邻居用户喜欢的推荐给当前用户。上述过程就属于User CF。
基于物品的CF(Item CF)的原理和基于用户的CF类似,只是在计算邻居时采用物品本身,而不是从用户的角度,即基于用户对物品的偏好找到相似的物品,然后根据用户的历史偏好,推荐相似的物品给他。
两者的计算复杂度和适用场景皆不同,详细可参见参考资料。
Spark协同过滤实现
训练数据
1
2
3
4
5
6
7
|
196 242 3 881250949
186 302 3 891717742
22 377 1 878887116
244 51 2 880606923
166 346 1 886397596
298 474 4 884182806
... |
其中第一列为userid,第二列为movieid,第三列为评分,第四列为timestamp(未使用)。
完整版下载:MovieLens(解压后的u.data文件)。http://files.grouplens.org/datasets/movielens/ml-100k.zip
代码实现
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
|
public class UserSideCF implements Serializable {
private static final Pattern TAB = Pattern.compile( "\t" );
public MatrixFactorizationModel buildModel(RDD<Rating> rdd) { //训练模型
int rank = 10 ;
int numIterations = 20 ;
MatrixFactorizationModel model = ALS.train(rdd, rank, numIterations, 0.01 );
return model;
}
public RDD<Rating>[] splitData() { //分割数据,一部分用于训练,一部分用于测试
SparkConf sparkConf = new SparkConf().setAppName( "JavaALS" ).setMaster( "local[2]" );
JavaSparkContext sc = new JavaSparkContext(sparkConf);
JavaRDD<String> lines = sc.textFile( "/home/nodin/ml-100k/u.data" );
JavaRDD<Rating> ratings = lines.map(line -> {
String[] tok = TAB.split(line);
int x = Integer.parseInt(tok[ 0 ]);
int y = Integer.parseInt(tok[ 1 ]);
double rating = Double.parseDouble(tok[ 2 ]);
return new Rating(x, y, rating);
});
RDD<Rating>[] splits = ratings.rdd().randomSplit( new double []{ 0.6 , 0.4 }, 11L);
return splits;
}
public static void main(String[] args) {
UserSideCF cf = new UserSideCF();
RDD<Rating>[] splits = cf.splitData();
MatrixFactorizationModel model = cf.buildModel(splits[ 0 ]);
Double MSE = cf.getMSE(splits[ 0 ].toJavaRDD(), model);
System.out.println( "Mean Squared Error = " + MSE); //训练数据的MSE
Double MSE1 = cf.getMSE(splits[ 1 ].toJavaRDD(), model);
System.out.println( "Mean Squared Error1 = " + MSE1); //测试数据的MSE
}
public Double getMSE(JavaRDD<Rating> ratings, MatrixFactorizationModel model) { //计算MSE
JavaPairRDD usersProducts = ratings.mapToPair(rating -> new Tuple2<>(rating.user(), rating.product()));
JavaPairRDD<Tuple2<Integer, Integer>, Double> predictions = model.predict(usersProducts.rdd())
.toJavaRDD()
.mapToPair( new PairFunction<Rating, Tuple2<Integer, Integer>, Double>() {
@Override
public Tuple2<Tuple2<Integer, Integer>, Double> call(Rating rating) throws Exception {
return new Tuple2<>( new Tuple2<>(rating.user(), rating.product()), rating.rating());
}
});
JavaPairRDD<Tuple2<Integer, Integer>, Double> ratesAndPreds = ratings
.mapToPair( new PairFunction<Rating, Tuple2<Integer, Integer>, Double>() {
@Override
public Tuple2<Tuple2<Integer, Integer>, Double> call(Rating rating) throws Exception {
return new Tuple2<>( new Tuple2<>(rating.user(), rating.product()), rating.rating());
}
});
JavaPairRDD joins = ratesAndPreds.join(predictions);
return joins.mapToDouble( new DoubleFunction<Tuple2<Tuple2<Integer, Integer>, Tuple2<Double, Double>>>() {
@Override
public double call(Tuple2<Tuple2<Integer, Integer>, Tuple2<Double, Double>> o) throws Exception {
double err = o._2()._1() - o._2()._2();
return err * err;
}
}).mean();
}
} |
运行结果
1
2
3
4
|
0.6 , 0.4 (训练数据,测试数据) - 0.3706799281981904 , 2.4569381099423957 (训练数据,测试数据)
0.7 , 0.3 - 0.40358067085112936 , 2.4469113734667935
0.8 , 0.2 - 0.4335027003381571 , 2.0930908173274476
0.9 , 0.1 - 0.4587619714761296 , 1.7213014771993198
|
参考资料
- MLlib - Collaborative Filtering
- 探索推荐引擎内部的秘密,第 2 部分: 深入推荐引擎相关算法 - 协同过滤
- Movie Recommendation with MLlib
http://www.cnblogs.com/fillPv/p/5478090.html
相关推荐
spark Mllib 协同过滤测试数据
Spark MLlib 是 Apache Spark 的机器学习库,其中包含多种机器学习算法,如协同过滤(Collaborative Filtering, CF)。在本实例中,我们将探讨如何使用 PySpark(Python 接口)实现基于 MLlib 的协同过滤推荐算法...
项目概述:本Scala源码项目构建于Spark MLlib平台之上,实现了一套协同过滤的电影推荐系统。项目共包含208个文件,以Scala为主要编程语言,同时整合了JavaScript、CSS和HTML技术。 文件构成: - Scala源文件:9个,...
其中分类算法、回归算法、聚类算法、协同过滤是SparkMLlib中几个重要的算法类型。 分类算法在监督学习中应用广泛,主要目标是将输入数据分到不同的类别中。回归算法则是用于预测连续值,例如股价或气温。聚类算法,...
它提供了一系列的工具,使开发者能够实现常见的机器学习算法,例如分类、回归、聚类、协同过滤等。本知识点将重点介绍Spark MLlib机器学习入门的基础知识,包括Spark的介绍、Spark MLlib的介绍、课程基础环境配置...
Apache Spark MLlib是Spark生态系统中的一个机器学习库,提供了各种常用机器学习算法的实现,如分类、回归、聚类、协同过滤等,同时还包括了特征提取、转换、选择等工具。MLlib的设计目的是为了简化机器学习在大规模...
基于Spark MLlib平台,通过协同过滤算法实现电影推荐功能协同过滤算法(Collaborative Filtering)是一种经典的推荐算法,其基本原理是“协同大家的反馈、评价和意见,一起对海量的信息进行过滤,从中筛选出用户可能...
Spark MLlib平台通过支持分类、回归、聚类、协同过滤和降维等主要机器学习方法,实现了用户数据的高效处理和分析。在电子商务领域,这种能力特别重要,因为数据量大且更新速度快,需要快速准确地从海量数据中提取出...
《Spark专刊 SparkMLlib机器学习》是由作者李军编写的关于Spark机器学习库MLlib的专业文献,旨在为读者提供全面、清晰的Spark MLlib学习资料。这本书的内容涵盖了MLlib库的基础概念、核心功能以及实际应用,对于想要...
Spark MLlib是Apache Spark的核心库之一,专注于提供机器学习算法和工具。它是大数据处理和分析领域的一个重要组件,尤其在分布式环境下,Spark MLlib能够帮助用户高效地执行各种机器学习任务。下面将深入探讨Spark ...
Spark MLlib 是 Apache Spark 的机器学习库,其中的 ALS( Alternating Least Squares)算法是实现协同过滤推荐系统的重要工具。在Scala编程环境下,我们可以充分利用Spark的分布式计算能力,高效处理大规模数据集,...
这个"使用协同过滤和lfm(sparkmllibALS)的电影推荐演示_Python_下载.zip"包含了一个名为“pyspark-recommendation-demo-master”的代码示例,用于展示这些概念。 协同过滤是一种基于用户行为的推荐算法,它假设...
- 不懂运行,下载完可以私聊问,可远程教学 该资源内项目源码是个人的毕设,代码都测试ok,都是运行成功后才上传资源,答辩评审平均分达到96分,放心下载使用! <项目介绍> 1、该资源内项目代码都经过测试运行成功,...
电影推荐系统中运用的推荐算法是基于协同过滤算法(Collaborative Filtering Recommendation)。协同过滤是在信息过滤和信息系统中正迅速成为一项很受欢迎的技术。与传统的基于内容过滤直接分析内容进行推荐不同,...
协同过滤算法(Collaborative Filtering)是一种经典的推荐算法,其基本原理是“协同大家的反馈、评价和意见,一起对海量的信息进行过滤,从中筛选出用户可能感兴趣的信息”。它主要依赖于用户和物品之间的行为关系...
- 支持多种类型的机器学习任务,如分类、回归、聚类、协同过滤等。 - 提供了易于使用的API,简化了模型训练和评估过程。 - 高效利用Spark的分布式计算能力,支持大规模数据集的处理。 #### 1.2 Spark MLlib 主要...
4. Spark Mllib:Spark的机器学习库,提供了大量机器学习和统计方法,包括分类、回归、聚类、协同过滤和异常检测等。异常检测算法如Isolation Forest、Local Outlier Factor (LOF) 和 One-Class SVM 可以用于发现...
#### 九、Spark MLlib协同过滤推荐算法 协同过滤是一种常用的推荐系统算法,基于用户的行为和偏好进行推荐。 1. **模型训练**: - 使用`ALS`类来训练模型。 - 可以通过设置参数`rank`、`maxIter`和`regParam`来...
Spark MLlib 是Apache Spark项目中的机器学习库,它提供了一系列高效、易于使用的机器学习算法,包括分类、回归、聚类、协同过滤等。此外,MLlib还支持数据预处理、模型选择和评估等功能,使得大规模机器学习任务的...