工程方向的程序员看到算法相关的技术内心都会有或多或少的胆怯,但如果认真研究之后,其实会发现并没有那么难的。下面来介绍下市面上出现的各类推荐算法的实现原理:
协同过滤
什么是协同过滤?
维基百科:协同过滤简单来说是利用某兴趣相投、拥有共同经验之群体的喜好来推荐用户感兴趣的信息。
简要步骤
- 找到用户A收藏的电影。
- 找到喜欢用户A收藏电影的用户人群集合。
- 找到该群体喜欢的电影集合
- 将这些电影集合排序,从重合度高到低推荐给用户A。
具体步骤
- 查询到A用户喜欢{movie_1, movie_2, movie_3}电影。
- 再根据电影集合查询到喜欢该电影的人物集合movie_1{user_1, user_3, user_5}, movie_2{user_1, user_11, user_12}, movie_3{user_1, user_3, user_7};得到人物重合比较高的集合{user_1, user_3}。
- 找出该群体集合喜欢的电影user_1{movie_1, movie_2, movie_3, movie_7, movie_9}, user_3{movie_1, movie_3, movie_8, movie_18}
- 将电影合并并去除A喜欢的电影生成集合{movie_7, movie_9, movie_8, movie_18}推荐给用户A。
内容推荐
什么是内容推荐?
通过用户历史感兴趣的信息,抽象信息内容共性,根据内容共性推荐其他信息。
简要步骤
- 找到用户A收藏的职位。
- 分解各个职位的内容。
- 抽象化内容的共性内容。
- 由这些共性内容找到其他职位推荐给用户A。
具体步骤
- 得到求职者A访问过的三个职位,假设为{positions1, positions2, position3}
- 根据职位集合得到职位内容:
position1 -> {程序员, 杭州, 薪资7000, 3年经验}
position1 -> {程序员, 杭州, 薪资8000, 4年经验}
position1 -> {程序员, 杭州, 薪资7000, 3年经验}
数据可以从数据库得到。 - 得到的共性信息: {程序员, 杭州, 薪资7000, 3年经验}
- 由这些共性内容查找其他职位并实施推荐
以{程序员, 杭州, 薪资7000,3年经验}为查询条件,查询职位数据库,并按照一些规则进行排序(例如,最新发布的职位先推荐,点击过的职位不推荐等),完成推荐。
注意:如果查询的结果集过小,可以缩小条件召回,例如可以将查询条件缩小为{程序员, 杭州, 薪资7000},这是为了理解举的最简单的例子。下面会统一介绍给各个维度增加权重的算法。
相似性推荐
以上介绍的两个推荐算法都是需要根据用户的行为数据来分析推荐的(例如:电影收藏,职位收藏)。如果用户没有行为数据,就是一个用户刚注册登录进来,应该怎么推荐?
什么是相似性推荐?
比如用户A点击进入了item_1,就推荐和item_1电影最相似影集合items给他。那么问题就转化为,如何用一种通用的方法,表达item之间的相似性。
我们仍旧以电影为例子,如果新用户进入了《西虹市首富》的详情,那应该推荐什么电影给他?
复习下多维空间的概念:
二维空间的点N,如何得到与其最近的点?
answer:可以用二维空间中,点与点之间的距离,表示点与点之间的远近。对于全集中的任何一个点M(x1, y1),它与点N(x2, y2)的距离:
<center>distance = (x1-x2)^2 + (y1-y2)^2 </center >
所以,只要计算全集中所有点与N的距离,就能得到与它最近的3个点。
三维空间的点N,如何推荐与其最近的点?
answer:可以用三维空间中,点与点之间的距离,表示点之间的远近。
对于全集中的任何一个点M(x2, y2, z2),它与点N(x1, y1, z1)的距离:
distance = (x1-x2)^2 + (y1-y2)^2 + (z1-z2)^2
所以,只要计算全集中所有点与N的距离,就能得到与它最近的3个点。
循序渐进,对于一部电影《西虹市首富》,假设它有7个属性,则可以把它看做一个7维空间中的
点N{
导演:闫非
主演:沈腾
类型:喜剧
地区:中国大陆
语言:普通话
日期:2018
片长:118分钟
}
计算电影集合中的每个电影到《西虹市首富》的距离,那么公式就是:
<center>distance = f1(导演) + f2(主演) + f3(类型) + ... + +f7(片长) </center >
这个距离,通俗的解释,就是每个维度贡献分值的总和。
f函数我们可以这么定义:
f1(导演){
如果两部电影导演相同,得1分;
如果导演不同,得0分;
}
现在我们来看一下另一部电影《夏洛特烦恼》:
点M{
<font color=#FF0000>导演:闫非</font>
<font color=#FF0000>主演:沈腾</font>
<font color=#FF0000>类型:喜剧</font>
<font color=#FF0000>地区:中国大陆</font>
<font color=#FF0000>语言:普通话</font>
日期:2012
片长:100分钟
}
计算点N《西虹市首富》和点M《夏洛特烦恼》得到
distance = f1(导演) + f2(主演) + f3(类型) + ... + +f7(片长)
=1 + 1 + 1 + 1 + 1 + 0 + 0
= 5
即导演,主演,类型,地区,语言各得1分
遍历电影全集中的10w部电影,就能找到与点N《西虹市首富》最相近的3部电影,当用户点击《西虹市首富》的详情页时,直接推荐这3部最相近的电影即可。
相似性推荐,原理大致如上,要说明的是:
- 由于没有用户历史行为积累,所以所有用户进入一个电影的推荐结果都是相同的
- 一般来说,距离公式确实是线性的
- 一般来说,每个维度的权重不一样
- 一般来说,f1和f2的计算公式也可以不一样
- 这个线性公式,以及维度的权重,都可以通过机器学习训练出来
关联规则推荐
什么是关联规则?
百科:关联规则是形如X→Y的蕴涵式,其中,X和Y分别称为关联规则的先导(antecedent或left-hand-side, LHS)和后继(consequent或right-hand-side,RHS)。其中,关联规则XY,存在支持度和信任度。
关联规则推荐
关联规则是数据挖掘中的概念,通过分析数据找到两个物品直接的关联关系,电商中经常用来分析购买商品之间的关联关系,而商品本身并不存在明确的关系。例如:“购买尿布的用户有很大的概率会购买啤酒”,这就是一个最典型的关联规则。
证明:<font color = #FF0000>当尿布放入购物车之后,再推荐啤酒</font>比<font color = #FF0000>直接推荐啤酒</font>能获得更好的售卖效果。
推荐步骤
比如数据库存着5个购物车{A, B, C, D}, {A, C}, {A, B, C}, {A, C, D}, {A, B, D}。
- 计算关联规则(组合商品)的支持度
共5笔订单,4笔包含商品A,A的支持度是1。B的支持度是3/5
组合商品也有支持度:共5笔订单,3笔同时包含AB,即A->B的支持度是3/5。B->C的支持度是2/5。支持度评估商品包含在订单中的“概率”,一个订单,有多大概率包含这个商品。
- 计算关联规则的置信度
已知购买了A,有多大概率购买了B(即同时购买了AB),称A -> B的置信度。
分析购物车可以看到,商品A有5次购买,这5次中有3次购买了B,A->B的置信度是3/5。
<center>confidence(A->B) = support(A->B)/support(A)= (3/5)/(5/5) = 3/4 </center>
注意:X->Y与Y->X的置信度不一定相等。
比如A->B的置信度是3/5,买商品A时,3/5概率会买B,B->A的置信度是1,买商品B时,100%会买A。
- 计算关联规则的提升度
上面例子里,confidence(B->A)=1,即:如果用户购买商品B,100%会买A,那是不是意味着,如果用户将商品B放入购物车,就可以向用户推荐商品A呢?
当然不是,我们来回顾一下,关联规则推荐的目标,是希望达到<font color = #FF0000>当尿布放入购物车之后,再推荐啤酒</font>比<font color = #FF0000>直接推荐啤酒</font>能获得更好的售卖效果。
虽然购买商品B,100%会买A,但直接推荐A,用户也100%会买A,会发现,购买A与购买B是独立事件,用户买不买A和用户买不买B没有直接关系。这里的关联规则推荐,并没有比直接推荐获取更好的效果。
那我们就要用提升度(lift)来评估关联效果了,A->B关联规则推荐,与直接推荐B,的比值,可以用来评估推荐效果:
- 大于1,说明有效,在购买A时推荐B,比直接推荐B,效果更好
- 等于1,说明无关,购买A与购买B,是独立事件
- 小于1,说明负相关,购买A时推荐B,效果还不如直接推荐B
<center>lift(A->B) =confidence(A->B)/support(B)</center>
分子:confidence(A->B),购买A时,有多大概率同时购买B
分母:support(B),有多大概率直接购买B
来看看关联规则B->D,与直接推荐D,效果有没有提升:
- 有3个订单购买B,这3个订单中有2个订单购买了D,所以B->D的置信度是2/3,即买了B有2/3的概率会买D
- 直接推荐B的话,5个订单中有3个购买了D,所以D的支持度是3/5,即有3/5的概率会直接买D
会发现,关联规则推荐的效果更好。
再来来看看关联规则C->D,与直接推荐D,效果有没有提升:
- 有4个订单购买C,这4个订单中有2个订单购买了D,所以C->D的置信度是1/2,即买了C有1/2的概率会买D
- 直接推荐D的话,5个订单中有3个购买了D,所以D的支持度是3/5,即有3/5的概率会直接买D
会发现,关联规则推荐的效果很差,还不如直接推荐。
- 总结
关联规则A->B推荐,目标是,在“用户将A放入购物车时,推荐B”比“单独推荐B”获取更好的效果
- A->B的支持度,是用户同时购买A和B概率
- A->B的置信度,是用户购买A的同时,有多大概率购买B
- A->B的提升度,是“用户购买A的同时,有多大概率购买B”与“直接购买B的概率”的比值
个性化推荐
不知道大家有没有经历过杀熟的现象,比如今年新闻联播报道:相同起点,相同终点的两个手机打车,价格不一样。
年也有新闻引起过激烈的讨论:相同的起点,相同终点的两个用户买飞机票,机票价格不一样。
下面我就用通俗的语言说说此类“个性化价格”是如何实现的。
方式一:用户分级
对用户进行分级,不同类型的用户会有不同的补贴,定价,营销策略。
待拉新用户
- 竞品用户:短信发大额优惠券营销
- 竞品重合用户:短信发优惠券营销
- 沉默用户:定额微信红包唤醒
首单用户:大额折扣券或者直减券
非首单用户
- 2单用户:降低优惠券金额试探
- 3单用户:降低优惠券金额试探
- 疑似粘性用户:随机优惠券试探
- 强粘性用户:意思意思优惠券
所以,对于“相同起点,相同终点的两个手机打车”,可能出现:新手便宜,熟客贵。
方式二:个性化推荐
对用户的历史行为进行分析,抽象用户的标签,针对不同标签的用户进行不同的补贴,定价,营销策略。
例如
平台可以从日志中分析出用户A的历史特征是:
- 有优惠券也不使用
- 等待30秒没人接单就加价
- 等待60秒没人接单就打专车
可以分析出:用户A是土豪,对接单时间敏感,对价格不敏感
从日志中分析出用户B的历史行为特征是:
- 没有优惠券就不下蛋
- 宁愿等待10分钟也不加价
- 从不打专车,也绝不在高峰期(价格会加倍)打车
可以分析出:用户B是屌丝,对价格敏感,以省钱为优先
于是,用户A和用户B同时打车,可能出现:
- 时间敏感的用户A贵
- 价格敏感的用户B便宜
从历史数据,一定能还原出真实的你,“杀熟,杀豪”是个性化价格的两大利器。