推荐算法评测心得

时间:2022-12-07 17:00:26

   ◆版权声明:本文出自胖喵~的博客,转载必须注明出处。

    转载请注明出处:https://www.cnblogs.com/by-dream/p/10450880.html 

 

 

做推荐算法的质量工作将近一年,这一年尝试了很多东西,踩了不少坑,也对推荐的评测工作稍微有了些自己的心得,现在分享出来,希望能和做这块工作的同学一起交流、探讨,也欢迎多拍砖,多提意见。

 

推荐系统

目前推荐技术的应用已经非常较普及了,新闻、商品、问答、音乐,几乎都会用到推荐算法来为你呈现内容。下面是淘宝、知乎、微博三个app的推荐模型,可以看到推荐都在非常重要的位置。
推荐算法评测心得
 
 
在介绍推荐算法评测之前,我先简单说下推荐系统,这里我以商品为例,简单描述下推流程,让大家更明白一些,一般推荐主要包含以下步骤:

召回->打分排序->透出

召回

召回阶段通常的手段是协同过滤比较场景的i2i,u2i等这种x2x(有兴趣可以看下我写的基于itembase的推荐),也有使用embedding的方式通过向量之间的距离进行召回。以i2i为例,假如现在要针对我推荐一个商品,那么首先要找到我感兴趣的物品 ,这些数据是通过我的历史行为来进行获取,比如拿到我最近一段时间内的点击、加购、收藏、购买的物品,将这些商品做为trigger进行召回,协同算法的具体就不再这里叙述了,有兴趣可以看下链接,最终我们按照协同过滤算法算出商品之间的相似分值,然后按照一定数量进行截断,因为这里截断也是依靠分数来进行的,所以一般这一步也称粗排。这样召回截断就完成了。

打分

召回完商品后,我们需要对这些商品进行再一次的精排,这里需要用模型来预估ctr,一般情况下LR、GBDT、FM用的比较多,这里深度网络相对用的少,主要为了考虑到性能,尤其是rt,因为绝大部分的精排都是需要实时预测的,所有对耗时有一定的要求。继续说下模型预测的步骤,首先针对召回的商品进行特征的补充,例如该商品的一级类目、叶子类目(一级类目代表比较,叶子类目代表最细分的类目)、被多少用户购买等,然后再加入人的特征,例如性别、年龄、收入、对类目的偏好等,然后将这些信息做为feature,用模型进行预测,然后根据模型预测的结果进行排序,输出。

模型

打分过程中的模型是需要提前训练和部署,训练集的来源就是用户的实时行为加上用户和商品的特征。feature的构成是用户的特征和商品的特征,label则是用户是否点击了该商品。

推荐算法评测心得 

质量方案

接下来说下如何保证这块的质量。由于推荐系统最终对用户需要提供实时的服务化,因此免不了有工程端的技术需要一起配合。因此我这块主要分为两个维度来开展,一方面是工程端的质量保证,一方面是算法侧的质量保证。

工程端质量

这一块可以将算法当成一个黑盒子,只把他当成一个有结果返回的接口。针对这方面前人已经有了丰富的经验,我们可以做接口的单元测试和冒烟测试,另外就是压测,在预估的qps下看rt是否满足业务方的要求,load是否过大,超时和错误的比例是否符合一定的预期。这里就不细说了,重点说说第二部分。

算法端质量

这里我再进行细分一下,分为三部分介绍:算法数据、算法模型、算法效果;

算法数据:

大家都知道算法在做训练前数据的处理部分非常的重要,有兴趣可以看下特征工程相关的内容,数据的来源,特征的构造,数据抽取、加工整个的过程都有可能会出现错误,而且数据一般都是存储在分布式系统数据库里,因此需要借助类似hive这样的工具将sql转换成MapReduce的任务去进行离线的计算,离线任务的产出通常会耗费不少的时间,而对于一些日更新的模型通过对数据对产出时间有一定的要求。因此数据这块最主要的保证点为:数据本身的质量,和数据的产出时间。数据本身的质量一般可以通过数据大小的整体抖动,以及关键字段是否为空,主键是否重复,做法比较简单可以通过简单sql或者udf来完成,然后借助工程能力做到预警、检查、出报表等。

算法模型:

模型的本身在迭代过程中也是需要关注的,不过通常算法同学的训练优化也是参考这些指标,所以我们也可以把这几个指标做为模型本身好坏的评估。具体为:准确率、召回率、AUC。

算法效果:

那么这个算法推荐出的效果究竟好不好呢,这个是一个非常主观的事情,每个人的感受也不是一样的,但是我们仍然要衡量它的好坏,这里我参考业内学者的推荐书籍以及自己的一些摸索,总结出下面一些方法,供大家参考。

人工评测:

顾名思义,邀请一帮人来对你的推荐系统的结果进行评测。这里想法来自于我在做翻译评测时期的经验,首先这个成本比较高,另外就是参杂了人的主观性非常的高,翻译的好坏我们可以通过制定一些细致的规则来进行约束,但是推荐的好坏我们却不好制定详细的规则,另外就是推荐之前的用户行为如何模拟,如何让评测者进行感知,这些都是比较难的,并且和基准的对比也不是很好做,所以这里不是很推荐用这个方法,但是还是要提一下。

指标评估:

指标化推荐结果,也就是将推荐的结果用不同的指标来进行说明,通过这些指标,你可以更加的了解你的推荐系统,部分指标不一定越高越好,但是你需要让它保持在一定的范围内。说到具体的例子的时候,我会提一下。下面我们看下这些指标。

覆盖率

定义:
推荐系统能够推荐出来的“商品/类目”占“总商品/类目”集合的比例。假设系统的用户集合为U,推荐系统给每个用户推荐一个长度为N的物品列表R(u) ,总物品为N。那么:

覆盖率 =  $\frac{\Sigma R(u)}{N}$

意义:
描述推荐结系统对物品长尾发掘能力;
举个例子,淘宝上商品千千万万,推荐系统能否保证让新的一些商品有足够的机会曝光出去呢?还是有些商品永远都无法得到推荐曝光的机会。这个指标反应的就是这个情况,显然物品的覆盖率是达不到100%的,但是我们可以看类目的覆盖率来进行衡量,假设全网所有的一级大类目一共2千个(和全网上亿的物品相比非常的少),那么推荐系统一天之内推荐出去的商品对应的一级类目,这个就是我们要衡量的标准。如果覆盖率达不到100%,那么肯定是有问题的。

基尼系数

覆盖率反应出的分布情况是比较有限的,我们只能知道哪些类目覆盖了,哪些没有覆盖,那类目之间究竟哪个类目占的多,哪个类目占的少呢?为了更细致地描述推荐系统发掘长尾的能力,我们需要统计推荐列表中不同类目出现次数的分布,引入基尼系数来评价。
基尼系数:按照类目的流行度(曝光次数)从大到小排序后进行统计后进行洛伦茨曲线的绘制。
做法: 以类目分布基尼系数为例,算出所有的类目被曝光的次数,需要以天周期为单位进行数据的统计。
推荐算法评测心得
 
这里需要说明一下,基尼系数越大代表所有类目的分布越不均匀,系数越小代表类目分布越均匀。我们知道,每个电商网站都有其侧重的类目,因此绝对平均不是一件好事,头部的类目占比稍多一些但是不能太离谱,举个例子100个类目,前5个占比到30~40%是相对比较好的。当然绝对的只看这个数据意义也不是很大,更多的是长期对这个指标进行监控,看是否会发生大的变动。

打散度

定义:描述推荐结果中结果数据的分散程度。

打散度 =  $\frac{2}{k(k-1)} \sum\limits_{i\neq j}^{k} 0.85^{dis((i,j)-1) * sim(i,j)}  $ (dis(i,j) = |i-j|,sim(i,j) 为 i==j?1!0)
这里需要解释一下,这里首先是对两两物品(不同的位置)计算为打散度后,得出整体的打散度。相似函数sim代表两两是否相同,相同则为1,不相似则为0。关于两个内容之间距离对打散度的影响,不能是线性的关系,因为随着两个商品出现的位置越来越大,用户对重复商品的感受会逐渐的减弱(很近的位置就有两个相似的内容觉得会有些重复,但是如果比较远的位置有两个相似的一般是可以接受的),一般双列流屏幕出现内容大概是4个,0.85^(5-1) 大概在 0.5左右,所以如果是5以内,则打散度会很低,但是如果>5了,打散度就不会衰减的比较厉害了。 相似的两个物品越靠近,权重越大。

更新率

定义:描述推荐系统不断迭代过程中推荐结果变化程度的指标。

更新率 = 1 - $\frac{S_{昨日}  ∩  S_{昨日}}{S_{昨日}  ∪  S_{昨日}}$

上面公式还是以类目为例,$S_{昨日}$代表昨天一天出现的所有商品所在的类目的个数,然后两天的交集除以并集,计算得出推荐出商品所属类目的更新率。

发现性

定义:推荐系统对用户未产生过关系的商品的发现能力。
在全网商品中,可能有一些比较好的商品,但是用户从来都没有点击过类似的物品,这时候推荐系统推荐给用户的时候,用户很有可能会眼前一亮,满满惊喜。
发现性 = $\frac{1}{n} \sum\limits_{i=1}^{n}  \frac{ S_{今日点击(前一周未点击)}  }{  S_{前一周点击}}$  
同样以类目为例,今天我点击了一个我感兴趣的商品,而这个商品的类似恰恰是我前一周都没有点击过过的内容,这就说明推荐系统的为我推荐了一个我之前都没有关注过并且我感兴趣的内容,也就是系统的发现性,在算出每个人的值之后,再进行求平均计算。

上新率

定义: 新内容被推荐系统推荐的曝光情况,这里可以从两个维度产出这项指标。
上新率1 = $\frac{当日曝光的内容中内容为最近一周生产的内容数}{当日曝光内容数} $
上新率2 = $\frac{当日曝光的内容中内容为最近一周生产的内容数}{最近一周生产的内容数} $
意义:对于一些社区类产品UGC内容的推荐,用户生产的优质是整个社区最重要的一部分,及时的曝光用户的新内容对于增加用户留存和给社区增添活力都有很大的帮助,因此需要这两个指标来评估推荐算法对于新内容的推荐能力。

NDCG

有些文章中也推荐使用这个指标,但是个人觉得这个更加适合评价搜索结果,之前写过一篇关于NDCG的文章,有兴趣可以看下。

失效率

定义: 表示系统没有推荐或推荐后未被用户点击数据占全集的比例。
失效率 = $\frac{S(0)}{S} $
S(0) 表示实际点击次数为 0 的数据个数;S表示推荐集合的总数。
首先需要定义一个时间范围来计算没有被推荐出的。其含义为最终未被用户真正感知的数据的占比,未感知包含未推荐和推荐出去后未被点击的内容。

健壮性

定义:算法健壮性的评测主要利用模拟攻击。首先,给定一个数据集和一个算法,可以用这个算法给这个数据集中的用户生成推荐列表。然后,用常用的攻击方法向数据集中注入噪声数据,然后利用算法在注入噪声后的数据集上再次给用户生成推荐列表。最后,通过比较攻击前后推荐列表的相似度评测算法的健壮性。
总结:适合在离线环境进行完成,针对模型本身的评测。

除了上面介绍的通过这些指标的方法来进行评估,当推荐真正运用在业务上,通过业务侧的一些数据反馈也可以知道推荐算法的好坏。具体看下面两项:

负反馈

定义:负反馈相当于一个轻量级便携的用户反馈,用户可以直接对推荐出的内容给与反馈,推荐系统在拿到了用户实时反馈后就会立刻针对反馈信息对推荐结果做出相应的调整,而我们也可以在事后拿到负反馈的整体数据来评价推荐系统在用户侧是否有重大舆情产生。一般app的推荐都会有负反馈机制,如图:
推荐算法评测心得

ctr

Click-Througt-Rate,即点击率,点击数/曝光数。推荐算法效果的最最重要指标,没有之一。一般算法好不好,都会直接用这个指标直接定义。通常算法模型在迭代的过程中都会进行ab test,所谓ab test就是有一个基准桶,一个对比桶,通过收集两个不同方案在用户侧的点击率,来评估算法的好坏,一般来说当流量特别大的时候,基本上一个ab实验上线几分钟就可以出算法的好坏了。当然算法的分桶不仅限只有两个桶,像下面这个推荐每个分桶的数据都可以非常直观的展示出来。一般需要借助像Blink这样的实时计算能力来实时的显示点击率数据。
推荐算法评测心得

 

ctr

Conversation Rate,即转化率,转化数/点击数。通常在广告上用的比较多,对于商品来说也就是用户最终点击并且购买的转化率。因为最终决定转化的因素还是比较多的,不单单是推荐算法影响的,所以这个指标通常不做为模型迭代优化的衡量标准,但是由于其和最终的"钱"挂钩,所以一般领导会更加关注这个指标。
 
 

总结

上面说了很多指标,其实单看指标可能没有特别好的体感,更多的时候,我们需要真正的将这些内容结合到业务上去,看它究竟反应业务什么样的情况,抽丝剥茧,更加的理解业务、反哺业务,任何一个指标都需要对业务有指导意义,真正帮助业务提升。最后,我将整体的质量方案也画了一个概要图,可以参考看看。 
推荐算法评测心得