大数据实时阶段_Day06_推荐系统

推荐系统开发实战

推荐系统是一个综合性的系统,涉及到前段JS代码、推荐服务(Web网站)、推荐算法、大数据处理平台等;各个系统有依赖很多基础服务,调用关系非常复杂;在实际的开发过程中,每个模块都是由一个团队负责开发和维护的;本例期望通过一个猜你喜欢的案例梳理出推荐系统开发的一般流程。
课程目标
了解推荐系统概念及整体架构
掌握推荐系统开发的整体流程
理解推荐系统之协同过滤算法及开发流程
动手实践

1、 推荐系统基础概念
推荐本质上是商品售卖系统,和电商网站的目的一样,用来售卖商品。
电商网站商品的售卖,正常展示商品(平台想展示什么样品)
推荐系统,是根据用户的喜好,展示对应的商品,提高用户的下单率和转化率。

怎么计算的用户的喜好?
会收集用户的所有的行为信息(网站浏览信息、订单信息、关注信息、收藏商品、评论系统、外部信息(微博信息、联盟网站)),分析用户对某一类商品感兴趣(用户A:电子产品:10|用户A:生活家居:3),推荐喜好强度推荐相关品类的商品。

1) 用户行为收集模块(点击流模块、订单支付模块(AMQ)、用户中心、外部信息)
2) 使用大数据平台对信息(用户和商品)进行处理,得到用户偏好数据(用户喜欢什么类别)
3) 将偏好数据计算出来之后,导入到某一个算法进行计算(预测),得到推荐的结果。
4) 将推荐的结果导入到数据库(Redis、Hbase)中
5) 开发一个推荐引擎(Web网站),对外开放一些接口,输出推荐结果(通过JS代码展现给用户)。

数据收集模块:
点击流模块:flume+kafka+storm+redis 处理用户当前浏览的信息,将信息计算好之后,保存到redis。(比如用户对一个品类的偏好)。
订单支付(AMQ),开发一个消费者程序(storm、javaapp),用来计算用户的偏好
外部信息:通过爬虫技术爬去用户在社交网站的数据,进行账号的打通,关联账号
合作数据;比如京东和腾讯合作,可以获取一些用户在腾讯应用上的数据。
大数据处理平台:
离线计算和实时计算

推荐算法:
协同过滤算法

推荐引擎
JavaWeb网站开发

2、 推荐系统一般架构
2.1、简化架构
大数据实时阶段_Day06_推荐系统
2.2、京东推荐系统架构
大数据实时阶段_Day06_推荐系统
2.3、淘宝推荐系统架构
大数据实时阶段_Day06_推荐系统
3、 基础数据处理
3.1 哪些数据可以表达出偏好
用户和商品的之间的关系,什么样的数据能够表示用户对商品的喜好呢?
要从用户的行为和偏好中发现规律,并基于此给予推荐,如何收集用户的偏好信息成为系统推荐效果最基础的决定因素。用户有很多方式向系统提供自己的偏好信息,而且不同的应用也可能大不相同,下面举例进行介绍:
大数据实时阶段_Day06_推荐系统
以上列举的用户行为都是比较通用的,推荐引擎设计人员可以根据自己应用的特点添加特殊的用户行为,并用他们表示用户对物品的喜好。在一般应用中,我们提取的用户行为一般都多于一种,关于如何组合这些不同的用户行为,基本上有以下两种方式:
 将不同的行为分组:一般可以分为“查看”和“购买”等等,然后基于不同的行为,计算不同的用户 / 物品相似度。比如:“购买了该图书的人还购买了 …”,“查看了图书的人还查看了 …”
 根据不同行为反映用户喜好的程度将它们进行加权,得到用户对于物品的总体喜好。一般来说,显式的用户反馈比隐式的权值大,但比较稀疏,毕竟进行显示反馈的用户是少数;同时相对于“查看”,“购买”行为反映用户喜好的程度更大,但这也因应用而异。

3.2 一个用户对一个商品的偏好数据
计算偏好数据的时候,需要将所有的操作得分通过算法进行汇总
1)根据用户操作的复杂度,对以上操作进行分类。
一般可以分为四类
根据用户操作的复杂度,将用户的操作分为四类;
一类:查看、停留、评分、投票、收藏、关注;
二类:转发、评论;
三类:加入购物车:
四类:订单;
每个类别的得分的权重不一样
一类:10%
二类:20%
三类:30%
四类:40%

2)计算用户的整体偏好值
大数据实时阶段_Day06_推荐系统
3)得到用户的偏好值
大数据实时阶段_Day06_推荐系统

4、 推荐算法-协同过滤
概念:了解是什么?
使用:使用mahout算法库
结果:结果数据导入的redis

4.1、协同过滤-用户
第一代协同过滤技术是基于用户的协同过滤算法,基于用户的协同过滤算法在推荐系统中获得了极大的成功,但它有自身的局限性。
基于用户的协同过滤算法先计算的是用户与用户的相似度(兴趣相投,人以群分物以类聚),然后将相似度比较接近的用户A购买的物品推荐给用户B,专业的说法是该算法用最近邻居(nearest-neighbor)算法找出一个用户的邻居集合,该集合的用户和该用户有相似的喜好,算法根据邻居的偏好对该用户进行预测。

张三、王五、李四
张三和王五是否相似? 100
张三和李四是否相似? 90
大数据实时阶段_Day06_推荐系统
4.1.1、怎么计算相似度?
张三购买过,橘子,橙子、苹果、手机、卫生纸
王五购买过,橘子,橙子、苹果、手机、
李四购买过,橘子,橙子、苹果

张三和王五的相似度 4分
张三和李四的相似度 3分
王五和李四的相似度 3分

4.1.2、怎么推荐?给李四进行推荐?
1)和李四相似的用户有谁? 张三和王五
在实际的网站中,和李四相似的用户可能有几千万。
因为一个电商网种注册用户有1000万,就需要计算每个用户之间的相似度。
A:{B:98、C:77、D:66、E:65、F:60、G:53、X:44、Y:37、Z:27 ……}
最近领域:
只选三个、只选相似度分数大于60分(5个)
 固定数量的邻居:K-neighborhoods 或者 Fix-size neighborhoods
 基于相似度门槛的邻居:Threshold-based neighborhoods
大数据实时阶段_Day06_推荐系统
2)张三和王五购买过什么东西?
橘子,橙子、苹果、手机、卫生纸
橘子,橙子、苹果、手机、
3)对多个结果集进行汇总
橘子,橙子、苹果、手机、卫生纸
4)给李四进行推荐(购买过的就别推荐)
橘子,橙子、苹果
橘子,橙子、苹果、手机、卫生纸
5)推荐结果:手机和卫生纸

4.2、协同过滤-物品
第二代协同过滤技术是基于物品的协同过滤算法,基于物品的协同过滤算法与基于用户的协同过滤算法基本类似。他使用所有用户对物品或者信息的偏好,发现物品和物品之间的相似度,然后根据用户的历史偏好信息,将类似的物品推荐给用户。这听起来比较拗口,简单的说就是几件商品同时被人购买了,就可以认为这几件商品是相似的,可能这几件商品的商品名称风马牛不相及,产品属性有天壤之别,但通过模型算出来之后就是认为他们是相似的。
4.2.1、怎么计算相似度?
张三购买过,橘子,橙子、苹果、手机、卫生纸
王五购买过,橘子,橙子、苹果、手机、
李四购买过,橘子,橙子、苹果

当两个商品同时被购买,就认为相似。
橘子 和 橙子的相似度 3
橘子 和 苹果的相似度3
橘子 和 手机的相似度2
橘子 和 卫生纸的相似度 1

4.2.2、怎么推荐?
用户麻子,购买过橘子。
和橘子相似的商品:橙子3、苹果3、手机2、卫生纸1
产生推荐结果:橙子3、苹果3、手机2、卫生纸1

4.3 如何使用协同过滤算法
在实际的工作中,不需要我们自己动手开发一个算法,如同我们保存数据库的时候,不需要自己开发一个数据库。只需要调用现成的算法库。
调用时,需要知道算法库中算法的输入参数有哪些、输出参数有哪些。
Java mahout算法库,支持协同过滤。
Python
R
C

Mahout使用步骤

public static void main(String[] args) throws Exception {
    //1) 准备数据 这里是电影评分数据
    // 1,1,4
    // 1,1,3
    File file = new File("E:\\itcast\\env\\ml_data\\ml-10m\\ml-10M100K\\ratings.dat");
    //2) 将数据加载到内存中,GroupLensDataModel是针对开放电影评论数据的
    DataModel dataModel = new GroupLensDataModel(file);
    //3) 计算相似度,相似度算法有很多种,欧几里得、皮尔逊等等。
    UserSimilarity similarity = new PearsonCorrelationSimilarity(dataModel);
    //4) 计算最近邻域,邻居有两种算法,基于固定数量的邻居和基于相似度的邻居,这里使用基于固定数量的邻居
    UserNeighborhood userNeighborhood = new NearestNUserNeighborhood(100, similarity, dataModel);
    //5) 构建推荐器,协同过滤推荐有两种,分别是基于用户的和基于物品的,这里使用基于用户的协同过滤推荐
    Recommender recommender = new GenericUserBasedRecommender(dataModel, userNeighborhood, similarity);

    //给用户ID等于5的用户推荐10部电影
    List<RecommendedItem> recommendedItemList = recommender.recommend(5, 10);
    //打印推荐的结果
    System.out.println("使用基于用户的协同过滤算法");
    System.out.println("为用户5推荐10个商品");
    for (RecommendedItem recommendedItem : recommendedItemList) {
        System.out.println(recommendedItem);
    }
    long start = System.currentTimeMillis();
    recommendedItemList = recommender.recommend(11, 10);
    System.out.println(System.currentTimeMillis()-start);
}

大数据实时阶段_Day06_推荐系统

5、 猜你喜欢
5.1、推荐产品介绍
一个成熟的电商网站,会有很多推荐位,每个推荐位都有自己的推荐逻辑。如此,每个推荐位后面的算法和推荐规则也会不一样。下图是京东的推荐产品信息。
大数据实时阶段_Day06_推荐系统
下图是部分推荐广告位。
大数据实时阶段_Day06_推荐系统
一般推荐位上都会有一段解释性的文字,告诉用户为什么给你推荐,增加用户对推荐结果的信任。

5.2、猜你喜欢推荐的逻辑
1)输入要展示广告的编号和用户的id
2)根据广告的编号获取广告位的信息
这个广告位的要展示的商品数量、产品经理设置的强制推广商品信息、用户接口需要返回的数据类型。
3)根据广告的编号找到对应的推荐模型
四个模型:
基于用户的协同过滤算法产生的推荐结果(需要上下线检查)
基于物品的协同过滤算法产生的推荐结果 (需要上下线检查)
基于物品的相似度(协同过滤算法),实时计算推荐结果 (需要上下线检查)
基于物品的相似度(基于内容算法),实时计算推荐结果 (需要上下线检查)

4)根据多个模型的结果,进行排序
排序算法
5)设置硬广,强制显示

5.3、实时推荐的逻辑
1、计算物品与物品的相似度,将相似度数据保存到数据库
1)通过协同过滤算法计算了物品的相似度
两个商品被同时购买了就相似
2)通过基于内容的算法计算了物品的相似度
根据商品的属性标签,计算商品相似度。
2、获取当前用户浏览的商品信息
用户A:浏览A\B\C\A
3、根据用户的浏览信息开始推荐
根据用户浏览的逻辑寻找相似商品,如果一个用户对一个商品产看的次数很多,为了却分出这个差别,就设置了一个权重。用户浏览一次,就设置权重值为1.0.浏览第二次就累加0.1,例如:浏览5次,权重值就等于1.0+0.1+0.1+0.1+0.1 =1.4

4、依次获取每个商品的相似商品
5702142:2,5383292:3,5458870:3,5042921:2,4918048:4,3820581:1,5702142:4,4983566:2,5014152:4,4983566:1

利用相似和权重相乘 得到推荐值
大数据实时阶段_Day06_推荐系统
按照权重值进行排序
大数据实时阶段_Day06_推荐系统

5.4、推荐结果的排序
大数据实时阶段_Day06_推荐系统

从四个模型中获取24个商品
第1个 从模型1 获取
第2个 从模型2 中获取
第3个 从模型3 中获取
第4个 从模型4 中获取
第5个 从模型1 中获取
第6个 从模型2 中获取
第7个 从模型1 获取
第8个 从模型2 中获取
第9个 从模型3 中获取
第10个 从模型4 中获取
第11个 从模型1 中获取
第12个 从模型2 中获取

第13个 从模型1 获取
第14个 从模型2 中获取
第15个 从模型3 中获取
第16个 从模型4 中获取
第17个 从模型1 中获取
第18个 从模型2 中获取

获取数据的算法
使用for循环,循环24次,每次到不同的容器中获取一个商品。

For(int i=1;i<=24;i++){
If(i%6==1){从模型1中获取数据}
If(i%6==2){从模型2中获取数据}
If(i%6==3){从模型3中获取数据}
If(i%6==4){从模型4中获取数据}
If(i%6==5){从模型1中获取数据}
If(i%6==0){从模型2中获取数据}
}

5.5、如何展示推荐结果
1)第三方的网站
配置 请求http://ad.itcast.cn/js/b.js
大数据实时阶段_Day06_推荐系统
需要请求一段js代码 http://ad.itcast.cn/js/b.js

细节:域名解析

大数据实时阶段_Day06_推荐系统
2)推荐服务的网站
推荐系统需要对外提供一段js代码。

主要逻辑如下:
从window中获取一个叫做aid值,也就是拿到了121这个广告位的编号。
通过编号,发起一个请求:
http://ad.itcast.cn/ad.html?aid=121&ran=0.3796911426711371&callback=callbackHandler
得到一个结果集,其实一个jsonp中的回调。

callbackHandler([{"id":"1739475","name":"我的推荐,你的选择","price":"199999","img":"http://img13.360buyimg.com/n6/s488x350_jfs/t2476/214/1387387908/47235/648d8471/5653ca40N964e7ee4.jpg","url":"http://item.jd.com/1739475.html","status":1},{"id":"5733232","name":"新疆阿克苏苹果 果径80mm-85mm 约5kg 新鲜水果 ","price":"853","img":"//img10.360buyimg.com/n2/jfs/t7306/206/3342297079/289205/e0ca6c94/59f14e33N7063ee48.jpg","url":"//item.jd.com/5733232.html","status":1},{"id":"3820581","name":"江西名牌 杨氏YANG’S 赣南脐橙 12粒铂金果 简致礼盒装 新鲜水果 新包装 ","price":"796","img":"//img13.360buyimg.com/n2/jfs/t3295/14/5775084582/492685/47d076e7/587e0252Nf62a419b.jpg","url":"//item.jd.com/3820581.html","status":1},{"id":"3659335","name":"农夫山泉 17.5°橙 3kg装  钻石果 春节年货水果礼盒 【每10个优质脐橙,约只有1个入选17.5°橙钻石果】糖度更高、味道更好、果子更美的优质脐橙才能入选钻石果。钻石果不仅更漂亮,而且会更好吃!疯狂【沃柑】低价来袭!!!","price":"668","img":"//img12.360buyimg.com/n2/jfs/t11806/291/1856579940/352750/eca1795f/5a0d4df5N52843ddf.jpg","url":"//item.jd.com/3659335.html","status":1}])

这个回调,就会运行,我们b.js代码中定义的
大数据实时阶段_Day06_推荐系统
callbackHandler会帮我们拼装一个html文档并最终显示在页面上。