做推荐算法的质量工作将近一年,这一年尝试了很多东西,踩了不少坑,也对推荐的评测工作稍微有了些自己的心得,现在分享出来,希望能和做这块工作的同学一起交流、探讨,也欢迎多拍砖,多提意见。
目前推荐技术的应用已经非常较普及了,新闻、商品、问答、音乐,几乎都会用到推荐算法来为你呈现内容。下面是淘宝、知乎、微博三个app的推荐模型,可以看到推荐都在非常重要的位置。
在介绍推荐算法评测之前,我先简单说下推荐系统,这里我以商品为例,简单描述下推流程,让大家更明白一些,一般推荐主要包含以下步骤: 召回->打分排序->透出
接下来说下如何保证这块的质量。由于推荐系统最终对用户需要提供实时的服务化,因此免不了有工程端的技术需要一起配合。因此我这块主要分为两个维度来开展,一方面是工程端的质量保证,一方面是算法侧的质量保证。
这一块可以将算法当成一个黑盒子,只把他当成一个有结果返回的接口。针对这方面前人已经有了丰富的经验,我们可以做接口的单元测试和冒烟测试,另外就是压测,在预估的qps下看rt是否满足业务方的要求,load是否过大,超时和错误的比例是否符合一定的预期。这里就不细说了,重点说说第二部分。
这里我再进行细分一下,分为三部分介绍:算法数据、算法模型、算法效果;
推荐系统能够推荐出来的“商品/类目”占“总商品/类目”集合的比例。假设系统的用户集合为U,推荐系统给每个用户推荐一个长度为N的物品列表R(u) ,总物品为N。那么:
描述推荐结系统对物品长尾发掘能力; 举个例子,淘宝上商品千千万万,推荐系统能否保证让新的一些商品有足够的机会曝光出去呢?还是有些商品永远都无法得到推荐曝光的机会。这个指标反应的就是这个情况,显然物品的覆盖率是达不到100%的,但是我们可以看类目的覆盖率来进行衡量,假设全网所有的一级大类目一共2千个(和全网上亿的物品相比非常的少),那么推荐系统一天之内推荐出去的商品对应的一级类目,这个就是我们要衡量的标准。如果覆盖率达不到100%,那么肯定是有问题的。
覆盖率反应出的分布情况是比较有限的,我们只能知道哪些类目覆盖了,哪些没有覆盖,那类目之间究竟哪个类目占的多,哪个类目占的少呢?为了更细致地描述推荐系统发掘长尾的能力,我们需要统计推荐列表中不同类目出现次数的分布,引入基尼系数来评价。
基尼系数:
按照类目的流行度(曝光次数)从大到小排序后进行统计后进行洛伦茨曲线的绘制。做法:
以类目分布基尼系数为例,算出所有的类目被曝光的次数,需要以天周期为单位进行数据的统计。
这里需要说明一下,基尼系数越大代表所有类目的分布越不均匀,系数越小代表类目分布越均匀。我们知道,每个电商网站都有其侧重的类目,因此绝对平均不是一件好事,头部的类目占比稍多一些但是不能太离谱,举个例子100个类目,前5个占比到30~40%是相对比较好的。当然绝对的只看这个数据意义也不是很大,更多的是长期对这个指标进行监控,看是否会发生大的变动。
定义:描述推荐结果中结果数据的分散程度。
这里需要解释一下,这里首先是对两两物品(不同的位置)计算为打散度后,得出整体的打散度。相似函数sim代表两两是否相同,相同则为1,不相似则为0。关于两个内容之间距离对打散度的影响,不能是线性的关系,因为随着两个商品出现的位置越来越大,用户对重复商品的感受会逐渐的减弱(很近的位置就有两个相似的内容觉得会有些重复,但是如果比较远的位置有两个相似的一般是可以接受的),一般双列流屏幕出现内容大概是4个,0.85^(5-1) 大概在 0.5左右,所以如果是5以内,则打散度会很低,但是如果>5了,打散度就不会衰减的比较厉害了。 相似的两个物品越靠近,权重越大。
定义:描述推荐系统不断迭代过程中推荐结果变化程度的指标。
上面公式还是以类目为例,$S_{昨日}$
代表昨天一天出现的所有商品所在的类目的个数,然后两天的交集除以并集,计算得出推荐出商品所属类目的更新率。
定义:推荐系统对用户未产生过关系的商品的发现能力。 在全网商品中,可能有一些比较好的商品,但是用户从来都没有点击过类似的物品,这时候推荐系统推荐给用户的时候,用户很有可能会眼前一亮,满满惊喜。
同样以类目为例,今天我点击了一个我感兴趣的商品,而这个商品的类似恰恰是我前一周都没有点击过过的内容,这就说明推荐系统的为我推荐了一个我之前都没有关注过并且我感兴趣的内容,也就是系统的发现性,在算出每个人的值之后,再进行求平均计算。
定义: 新内容被推荐系统推荐的曝光情况,这里可以从两个维度产出这项指标。
意义:对于一些社区类产品UGC内容的推荐,用户生产的优质是整个社区最重要的一部分,及时的曝光用户的新内容对于增加用户留存和给社区增添活力都有很大的帮助,因此需要这两个指标来评估推荐算法对于新内容的推荐能力。
有些文章中也推荐使用这个指标,但是个人觉得这个更加适合评价搜索结果,之前写过一篇关于NDCG的文章,有兴趣可以看下。
定义: 表示系统没有推荐或推荐后未被用户点击数据占全集的比例。
S(0) 表示实际点击次数为 0 的数据个数;S表示推荐集合的总数。首先需要定义一个时间范围来计算没有被推荐出的。其含义为最终未被用户真正感知的数据的占比,未感知包含未推荐和推荐出去后未被点击的内容。
定义:算法健壮性的评测主要利用模拟攻击。首先,给定一个数据集和一个算法,可以用这个算法给这个数据集中的用户生成推荐列表。然后,用常用的攻击方法向数据集中注入噪声数据,然后利用算法在注入噪声后的数据集上再次给用户生成推荐列表。最后,通过比较攻击前后推荐列表的相似度评测算法的健壮性。 总结:适合在离线环境进行完成,针对模型本身的评测。 除了上面介绍的通过这些指标的方法来进行评估,当推荐真正运用在业务上,通过业务侧的一些数据反馈也可以知道推荐算法的好坏。
定义:负反馈相当于一个轻量级便携的用户反馈,用户可以直接对推荐出的内容给与反馈,推荐系统在拿到了用户实时反馈后就会立刻针对反馈信息对推荐结果做出相应的调整,而我们也可以在事后拿到负反馈的整体数据来评价推荐系统在用户侧是否有重大舆情产生。一般app的推荐都会有负反馈机制,如图:
Click-Througt-Rate,即点击率,点击数/曝光数。推荐算法效果的最最重要指标,没有之一。一般算法好不好,都会直接用这个指标直接定义。通常算法模型在迭代的过程中都会进行ab test,所谓ab test就是有一个基准桶,一个对比桶,通过收集两个不同方案在用户侧的点击率,来评估算法的好坏,一般来说当流量特别大的时候,基本上一个ab实验上线几分钟就可以出算法的好坏了。当然算法的分桶不仅限只有两个桶,像下面这个推荐每个分桶的数据都可以非常直观的展示出来。一般需要借助像Blink这样的实时计算能力来实时的显示点击率数据。
Conversation Rate,即转化率,转化数/点击数。通常在广告上用的比较多,对于商品来说也就是用户最终点击并且购买的转化率。因为最终决定转化的因素还是比较多的,不单单是推荐算法影响的,所以这个指标通常不做为模型迭代优化的衡量标准,但是由于其和最终的”钱”挂钩,所以一般领导会更加关注这个指标。
上面说了很多指标,其实单看指标可能没有特别好的体感,更多的时候,我们需要真正的将这些内容结合到业务上去,看它究竟反应业务什么样的情况,抽丝剥茧,更加的理解业务、反哺业务,任何一个指标都需要对业务有指导意义,真正帮助业务提升。最后,我将整体的质量方案也画了一个概要图,可以参考看看。