前言
推荐就是销售,目的就是把商品卖出去。那么如何像导购员那样把商品推荐并且销售出去呢?这里面就有两个方面的问题,一是如何精准的推荐用户想要的商品?二是如何精准的找到喜欢该商品的用户?推荐系统其实就是主要完成这个两件事。基于之前已有产品的一些业务,本文主要从第二个角度做一些实践和尝试。
本文假设是基于三方面的数据:电商A、社交网络B、传统企业C。需要解决的问题是搭建一个平台D,使传统企业C能够通过平台D去结合电商A和社交网络B的数据找到相似用户,然后给这些相似用户精准的发放广告的过程。当然,本文的目的是找到相似用户集。
数据分析
数据乃推荐之本,没有数据一切都没有意义。而已有的数据包括用户属性/用户行为信息,商品信息。如何从这些错综复杂的信息里面梳理出符合我们要求的信息,我们需要从下面三个角度去分析。
1. 用户数据分析
假设某用户在下面三个地方都有账号并且活跃。如表1-1所示。根据如下维度分析。
数据来源 | 用户年龄 | 用户性别 | 喜欢物品特征(兴趣) | 地域 | 收入 |
电商 A | 30 | F | 高端时尚 | 未知 | 未知 |
社交网络 B | 25~30 | N/A | 时尚护肤 | 未知 | 1万以上 |
传统企业 C | 30 | F | 高端护肤 | Nan Tong | 未知 |
表1-1
2. 物品数据分析
该场景下的物品主要来自传统企业,假设是某化妆品商。如表1-2所示。
商品类型 | 商品定位 | 商品标签 |
香水a | 高端 | 高端时尚 |
香水b | 普通 | 时尚 |
口红a | 高端 | 高端时尚 |
口红b | 普通 | 时尚 |
面膜a | 高端 | 时尚 |
沐浴乳b | 普通 | 运动清爽 |
表1-2
业务框架
那么如何能够更好的分析它们之间的关联,也就是相似度呢?这里就用到协同过滤等推荐算法,也就是推荐系统实践的核心部分。
图1-1是平台D的业务框架展示。这里是一个简易框架设计,不考虑资源优化、系统容错、并发、负载均衡等场景。
图1-1
从图1-1中的框架中,我们主要将平台D分为了四个层次:数据生成层,触发层,过滤排序层和数据存储曾。关于协同过滤、相似度计算、TOP-N选取等技术。这里不做具体描述,主要从实践业务的角度描述。
数据生成层:主要将来自电商A、社交网络B和传统企业C的数据进行收集,利用大数据处理工具Spark对三者数据进行清洗合并以生成一定格式数据的过程。
触发层:主要通过用户数据分析、商品数据分析和用户-商品分析这三个维度对数据进行重分析尝试生成推荐的集合组。
这里涉及到一个用户行为数据分析,主要是将用户数据和商品数据结合起来,包括分析用户和用户之间以及商品和商品之间,以及用户和商品之间的关联。然后按照一定的标签/格式/预定义将数据提取出来。
过滤排序层:对产生的集合组按照一定规则进行计算,通过排序过滤选取出做优的集合及集合内容。
数据存储层:对过滤排序层产生的数据集按照一定的格式和数据结构存储到数据库,以供客户查询使用。
场景分析
当得到满意的结果集的时候,如何使用呢?这不是本文的重点,但是对后面分析业务价值和逻辑实现却有着重要的意义,这里做一个简单的分析。
传统企业C有会员Mary、Jack和Lisa,信息如下:
Customer ID | Customer Name | Sex | age | Phone | City |
01002 | Female | 30 | 13675110030 | Nan Tong | |
20156 | Jack Li | Male | 28 | 13568200000 | Su Zhou |
01300 | Lisa Zhang | Female | 22 | 18500110030 | Su Zhou |
现企业C推出一款新的高端香水。除了通过会员信息发给已知的会员外,那么如何扩大发送范围,并且能够尽量准确的发送过其他用户呢?这里就是推荐。
经分析(已有系统),根据用户Mary Chen的收入年龄购物记录等分析出这款高端香水适合用户Mary Chen,那么输入用户Mary Chen,经过查询得到一系列相似用户集,根据相似性,将原本欲发送给用户Mary Chen的高端香水发送给这一系列用户集,这样就能够获得高于以往的转化率。
相似集获取
读到这里,你是否觉的获得了这个相似集一切问题就迎刃而解了呢?那么,这个相似集是如何获取的呢?通过前面框架和场景的介绍,也许你心里已经有一个粗略的轮廓。下面就通过电商A、社交网络B、传统企业C的数据来具体介绍相似集的获取。
数据收集
电商A数据:
{"_id" : ObjectId("4c33f8fcecf2b9320ac2981a"),"name" : "五月花开","age" : 30, "phone": "13675110030","sex" :"Female", "label":"养生,高端时尚"} {"_id" : ObjectId("4c33f8fcecf2b9320ac2981b"),"name" : "张三","age" : 23,"phone": "13675110032","sex" :"FeMale", "label":"青春时尚" } {"_id" : ObjectId("4c33f8fcecf2b9320ac2981c"),"name" : "李四","age" : 48,"phone": "13568200006","sex" :"Male","label":"养生健康"} {"_id" : ObjectId("4c33f8fcecf2b9320ac2981d"),"name" : "Jack", "age" : 28 ,"phone": "13568200000","sex" :"Male","label":"旅游运动" } {"_id" : ObjectId("4c33f8fcecf2b9320ac2981e"),"name" : "丽莎","age" : 22,"phone": "18500110030","sex" :"Female", "label":"青春时尚"} {"_id" : ObjectId("4c33f8fcecf2b9320ac2981f"),"name" : "王五","age" : 25 ,"phone": "18500110032","sex" :"Female","label":"文艺"} {"_id" : ObjectId("4c33f8fcecf2b3420ac2981f"),"name" : "四月","age" : 30 ,"phone": "18503110032","sex" :"Female", "label":"高端时尚,文艺,运动"} {"_id" : ObjectId("4c33f8fsecf2b9320ac2981f"),"name" : "赵李","age" : 40 ,"phone": "13230115685","sex" :"Female", "label":"运动"} {"_id" : ObjectId("4c33f56cecf2b9320ac2981f"),"name" : "陈三","age" : 25 ,"phone": "13625119696","sex" :"Male", "label":"青春时尚"} {"_id" : ObjectId("4c33f8fcecf2b6523ac2981f"),"name" : "孙明","age" : 30 ,"phone": "13230115686","sex":"Female" , "label":"高端时尚"} |
社交网络B
我们以weibo为例,在实际环境里面,SNS一般都是提供大文本数据,需要使用文本处理、大数据处理等技术来预处理这些文本信息,提取我们需要关注的数据,本文主要关注三方面(表/文件)的信息:
用户信息 user:ID,username...;
关注关系信息 attention: ID->ID,label...;
发布信息信息 info:ID->message;
下面是联合查询的结果,以表格形式展现:
ID | UserName | Sex | AttentionIds | Attention category | label | Register Phone |
1 | Jack | M | 2,3 | 海外名品 | 足球运动 | 13568200000 |
2 | Mary | N/A | 1 ,5,6 | 兰蔻 | 时尚护肤 | 13675110030 |
3 | 张无忌 | M | 5 | 哲学,迪卡侬 | 运动健身 | 1520000001 |
4 | 令狐冲 | M | 1,6 | 香奈儿 | 运动 | 18500110032 |
5 | 赵敏 | F | 1,3,6 | 欧洲风情,Nike | 旅游,运动 | 13230115686 |
6 | 任盈盈 | F | 1,3,4,5 | 香奈儿 | 高端时尚,家居 | 18500110030 |
传统企业C:
Customer ID | Customer Name | Sex | age | Phone | Purchase Record |
01002 | Mary Chen | Female | 30 | 13675110030 | 香水a, 口红a |
20156 | Jack Li | Male | 25 | 13568200000 | 口红a |
01300 | Lisa Zhang | Female | 22 | 18500110030 | 面膜b |
数据整合分析
数据整合我们主要做两步:第一步匹配用户;第二步创建用户索引列表。
这里的数据整合是实体解析的一个基础应用,在生活中,很多的场合会使用到数据解析。比如:根据车牌号找到车主,根据电话号码定位到住址,根据不同网站的注册浏览信息识别为同一个人等等。
实体引用解析所关注的是这样一个决策:两个引用实例是否等价,它们是否指向同一个实体?这个决策通常是通过引用的身份属性值的相似程度来做出的,这样的做法被称为匹配(Matching)过程。当不同引用被断定为等价时,链接操作为他们赋予相同的链值。关于具体的实体解析原理可以参看博文《实体引用解析》。
以上面数据为例,一般手机号码是可唯一标识用户的信息,这里就用手机号码作为匹配参数。
通过用户数据和商品数据分析,给每个用户匹配至少一个定义好的标签Label。
1. 找到匹配号码,标记为在不同平台的同一用户,并提取/赋予相同的标签
Phone | Source | label | Sex | age |
13675110030 | C ,B | 高端时尚 | F |
|
13568200000 | C, B,A | 运动 | M |
|
18500110030 | C, B,A | 青春时尚 | F |
|
13230115686 | B,A | 运动 | F |
|
2. 再以标签label为依据分类创建用户索引。
Label | Phone List(Sex) |
高端时尚 | 13675110030(F), 18503110032(M),13230115686(F) |
青春时尚 | 18500110030(F), 13675110032(F), 13625119696 |
旅游 | 13568200000, 13230115686 |
运动 | 13568200000, 13230115685, 13230115686, 18503110032 |
家居 | 13230115685, 18500110030 |
文艺 | 18500110032, 18503110032 |
过滤排序推荐集
当得到整合的多方数据之后,我们可以发现其实都是按照标签或者手机号码等标识的一些数据集合。而在实际中,线上数据如浩瀚无边,虽然我们已经按照一定的规则分门别类,但是对于用户来说要找到和目标用户最相近的集合还是有一些困难,这里,我们就需要按照推荐系统都会用到的协同过滤等算法实现最终的用户集选择。
相似度计算
企业C推出了新品香水a,该香水属于高端产品,已知用户Mary Chen是该产品的最大潜在购买用户,如何找到更多和她相似喜好的用户呢?
下面是一个余弦相似性的简单实现:
1. privatestatic Double calculateCos(LinkedHashMap<String, Integer>first, 2. LinkedHashMap<String, Integer>second) { 3. 4. List<Map.Entry<String, Integer>>firstList =new ArrayList<Map.Entry<String, Integer>>( 5. first.entrySet()); 6. List<Map.Entry<String, Integer>>secondList =new ArrayList<Map.Entry<String, Integer>>( 7. second.entrySet()); 8. //计算相似度 9. doublevectorFirstModulo = 0.00;//向量1的模 10. doublevectorSecondModulo = 0.00;//向量2的模 11. doublevectorProduct = 0.00;//向量积 12. intsecondSize =second.size(); 13. for (inti = 0; i < firstList.size(); i++) { 14. if (i <secondSize) { 15. vectorSecondModulo +=secondList.get(i).getValue() 16. .doubleValue() 17. * secondList.get(i).getValue().doubleValue(); 18. vectorProduct +=firstList.get(i).getValue().doubleValue() 19. * secondList.get(i).getValue().doubleValue(); 20. } 21. vectorFirstModulo +=firstList.get(i).getValue().doubleValue() 22. * firstList.get(i).getValue().doubleValue(); 23. } 24. returnvectorProduct 25. / (Math.sqrt(vectorFirstModulo) * Math.sqrt(vectorSecondModulo)); 26. } |
首先配置推荐规则。可以设置为一个properties文件,这里简单做一个分类标签配置。
Category1: 时尚|文艺|青春 Category2: 运动|足球 Category1: 健身|养生 |
根据Category1:时尚|文艺|青春这些关键类别找到:“高端时尚” 18503110032(M),13230115686,再根据标签”青春时尚”,”文艺”等找到18500110030, 13675110032, 13625119696,18500110032, 18503110032这样一系列用户。这样得到一组用户,18503110032是目标客户,以他为依据,根据设定的维度,比如”关注”,”标签“,”Like“分别计算出推荐规则之下产生的用户和他的相似度。
相似用户列表 | 关注相似度 | 标签相似度 | Like相似度 | |
13230115686 | 80% | 90% | 90% |
|
18500110030 | 70% | 80% | 80% |
|
13675110032 | 50% | 60% | 50% |
|
13625119696 | 30% | 40% | 40% |
|
18500110032 | 20% | 40% | 40% |
|
加权计算
设置关注相似度,标签相似度和Like相似度的权重分别是0.3,0.5,0.2.计算得出每个备选用户的全相似度。
相似用户列表 | 关注相似度 | 标签相似度 | Like相似度 | 全相似度 |
13230115686 | 80% | 90% | 90% | 87% |
18500110030 | 70% | 80% | 80% | 77% |
13675110032 | 50% | 60% | 50% | 55% |
13625119696 | 30% | 40% | 40% | 37% |
18500110032 | 20% | 40% | 40% | 34% |
排序TOP-N选取
根据系统设定的阀值(设定阀值为0.5)得到用户推荐列表[13230115686, 18500110030, 13675110032].
这样推荐用户集就产生了。
结语
本文的推荐系统实践着重于寻找相似用户,增加精准用户的个数,以便达到更大范围更精准客户群的广告效用。
这篇博客主要从开发设计的角度,从业务方向着手,阐述如何得到最优集的这样一个过程。对于具体的算法没有详细描述,可以参考另外一篇博客《推荐系统之算法介绍》。