原文: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个人的记录来进行加权推荐。具体如下,假设已经计算出欧几里得相似度:

朋友 相似度 银魂 S.x银魂 食灵零 S.x食灵零 雨月 S.x雨月
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协同过滤实现

训练数据

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

代码实现

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); //训练数据的MSEDouble MSE1 = cf.getMSE(splits[1].toJavaRDD(), model);System.out.println("Mean Squared Error1 = " + MSE1); //测试数据的MSE}public Double getMSE(JavaRDD<Rating> ratings, MatrixFactorizationModel model) { //计算MSEJavaPairRDD 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>() {@Overridepublic 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>() {@Overridepublic 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>>>() {@Overridepublic double call(Tuple2<Tuple2<Integer, Integer>, Tuple2<Double, Double>> o) throws Exception {double err = o._2()._1() - o._2()._2();return err * err;}}).mean();}
}

  

运行结果

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

转载于:https://www.cnblogs.com/fillPv/p/5478090.html

Spark MLlib之协同过滤相关推荐

  1. 使用spark mllib中协同过滤推荐算法ALS建立推荐模型

    使用spark mllib中协同过滤推荐算法ALS建立推荐模型 package com.yyds.tags.ml.rs.rddimport org.apache.spark.mllib.evaluat ...

  2. 孙其功陪你学之——Spark MLlib之协同过滤

    转自 程序员的自我修养 – SelfUp.cn 由于在学习 spark mllib 但是如此详细的资料真的很难找,在此分享.1,220次浏览 什么是协同过滤 协同过滤(Collaborative Fi ...

  3. Spark机器学习之协同过滤算法

    Spark机器学习之协同过滤算法 一).协同过滤 1.1 概念 协同过滤是一种借助"集体计算"的途径.它利用大量已有的用户偏好来估计用户对其未接触过的物品的喜好程度.其内在思想是相 ...

  4. 项目体系架构设计——基于Spark平台的协同过滤实时电影推荐系统项目系列博客(四)

    系列文章目录 初识推荐系统--基于Spark平台的协同过滤实时电影推荐系统项目系列博客(一) 利用用户行为数据--基于Spark平台的协同过滤实时电影推荐系统项目系列博客(二) 项目主要效果展示--基 ...

  5. 利用用户行为数据——基于Spark平台的协同过滤实时电影推荐系统项目系列博客(二)

    系列文章目录 初识推荐系统--基于Spark平台的协同过滤实时电影推荐系统项目系列博客(一) 利用用户行为数据--基于Spark平台的协同过滤实时电影推荐系统项目系列博客(二) 项目主要效果展示--基 ...

  6. 基础环境搭建——基于Spark平台的协同过滤实时电影推荐系统项目系列博客(五)

    系列文章目录 初识推荐系统--基于Spark平台的协同过滤实时电影推荐系统项目系列博客(一) 利用用户行为数据--基于Spark平台的协同过滤实时电影推荐系统项目系列博客(二) 项目主要效果展示--基 ...

  7. 实时推荐服务建设——基于Spark平台的协同过滤实时电影推荐系统项目系列博客(八)

    系列文章目录 初识推荐系统--基于Spark平台的协同过滤实时电影推荐系统项目系列博客(一) 利用用户行为数据--基于Spark平台的协同过滤实时电影推荐系统项目系列博客(二) 项目主要效果展示--基 ...

  8. spark之CF协同过滤

    一).协同过滤 1.1 概念 协同过滤是一种借助"集体计算"的途径.它利用大量已有的用户偏好来估计用户对其未接触过的物品的喜好程度.其内在思想是相似度的定义 1.2 分类 1.在基 ...

  9. 基于Spark平台的协同过滤实时电影推荐系统

    文章目录 摘要 0 引言 1 协同过滤算法 2 实时推荐服务 3 电影推荐系统设计部署 3.1 架构设计 3.2 系统功能设计 3.3 数据库设计 4 系统运行效果 5 结语 参考文献 摘要 摘要:随 ...

最新文章

  1. EOS主网上线只是开始,如何运营决定未来
  2. 用新语法写更简洁的ABAP代码
  3. ionic 混合应用开发
  4. 保持SVN仓库结构只checkout部分子目录
  5. 继裁员千人后 蔚来打算卖掉电动方程式车队
  6. [面试专题]Vue.js 2.0 独立构建和运行时构建的区别
  7. Day4:python之文件操作、函数初识(2)
  8. _DEVOBJ_EXTENSION结构体
  9. 拜托,面试别再问我TopK了!!!
  10. 微分比例控制与测速反馈控制
  11. Ele SOA Container
  12. nyoj 题目172 小柯的图表
  13. CTFSHOW-WEB详解
  14. 华三路由器配置mstp多生成树协议
  15. Cisco ❀ IPV4协议数据报头部
  16. 5月30日第壹简报,星期一,农历五月初一
  17. 太极安装的应用打开闪退_BUG:通过太极阴创建应用什么值得买的过程中太极闪退,应用创建失败...
  18. 植物大战僵尸资源文件提取 总结
  19. 绝不手软!严厉打击抄袭行为
  20. 2023年CCTV总台春晚主持人阵容定了

热门文章

  1. 复盘金典《歌手》2019踢馆变革 有机赋能为梦想助力
  2. welearn随行课堂一键完成
  3. MapReduce初级经典案例实现
  4. Google Chrome浏览器被2345绑定首页,尝试各种办法都无法改回,一打开就跳转?本修改方法试用于“联想笔记本“。
  5. 高等数学之可微,可导,可积与连续之间的关系
  6. 冷链保温箱在冷链中扮演了什么角色?
  7. java新特性lambda表达式快速入门
  8. 异或^操作符(C语言)
  9. 三星android 7.0 root,三星G9350 7.0 root教程及获取7.0系统的root权限
  10. 计算机的这些基础知识,你未必全都知道,不信你看看?