推荐系统中常用的权重计算方法



前言

说起推荐方面的技术,大家首先提到的往往是回归、Learning to rank这些数据挖掘或者说机器学习方面的名词,连协同过滤都少提了,可能是因为它太基础。然而基础的才是最重要的,实际上给推荐效果带来巨大差异的,往往不是模型的复杂度,而是对数据的处理是否足够完善。

本文就简单探讨一下在推荐系统中,在运用各种模型之前,要对数据进行哪些处理工作,以及这些处理工作中的常用方法。
简单描述一下数据

首先,被推荐的内容我们称为Item,用大写字母I来表示,比如在线视频中的电影、阅读App里的图书、电商网站里的商品等等,都叫Item;第二呢,我们用U来表示用户(User);第三,我们用T,也就是Tag(标签),来描述I的属性和U的喜好。

在实际应用中,I和U往往会有不同的标签集合,比如用户会有年龄、性别、籍贯、教育程度等标签,视频类的Item会有内容长度等信息,它们无法直接匹配。另外标签之间也是会有层次关系的。本文不讨论有层次关系的标签,也不讨论不能直接匹配的标签如何使用的问题,这些问题等有机会再谈。
数据收集和预处理

本应先说数据收集的工作,但由于在实践中预处理环节往往会被忽视,这里先说一下预处理要做的事情。第一是处理多义问题。比如“苹果”这一个标签,它可以是一种水果,也可以是手机的品牌。可以通过给标签添加领域词作为前缀的办法来解决多义的问题。第二是同义问题,比如“C罗”和“克里斯蒂亚诺·罗纳尔多”就是指同一个人。对于同义词,可以将它们映射到同一个ID上面,或者映射到一个最常用词上面。第三要说的是过滤,在真实的数据里面,脏数据的占比往往会超乎想象,错误的或者无效的标签会有很多。

可以使用词表(也就是黑名单)、DF(Document Frequency)的方式实现标签的过滤工作。DF的方法很简单,就是统计一下每一个标签在多少个内容里面出现过,这个值就是DF值,把DF值过大或者过小的标签过滤掉。最大和最小值要根据内容总数量和具体的应用场景来确定。

以上所说主要是数据的清理、规整化工作。实际上数据的集成、变换、归约等操作也是预处理阶段要做的事情,这些工作我们在下文中需要它们的地方再做介绍。

下面说一下数据收集的工作。

首先是内容本身的属性数据,包括内容的生产时间、长度、质量度(比如视频的清晰度、流畅度、画面精美度等等);第二是内容的meta信息,这里简化一下,认为它们是标签(T)的集合;第三是用户的描述信息,比如年龄、性别、生活地域、教育程度、家庭组成等等;第四是用户在内容上的行为数据,包括消费行为数据(购买商品、阅读图书、观看视频等等)、寻找行为数据(搜索、分类浏览、推荐结果的曝光和点击等)、以及主动的兴趣表达行为(收藏内容、分享内容、评分、评论、顶/踩等等);第五,还有一些其它数据,比如标签的流行度等等,可以从搜索引擎等站外数据源获取到。

我们这里做一下简化,在数据收集阶段,目标是获得以下几组数据。

1、<U, I, Score>,也就是用户U对内容I的喜好程度(Score)。Score的取值根据用户U对内容I的行为而定,这个跟业务有密切的关系,这里不作细述。

2、<I, Score>,就是每一条Item本身的得分,一般用来体现Item的流行度、新鲜度、本身质量等指标的综合得分。

3、<I, T, Weight>,就是对于一条内容I,它每一个标签T的重要程度。

4、<U, T, Preference>,表示用户U对标签T的喜好程度。

本文的一下部分分别介绍上面的score、weight、preference都如何计算。本文建议这些Score、weight、或者preference的取值都归一化到(0, 1)区间内,这样能为各种计算提供方便。

重要的事情再说一遍,收集好数据之后别忘了做一下前面介绍过的预处理。
用户-内容喜好的计算
在介绍各种权重或者得分的方法之前,先介绍一下sigmoid函数。这个函数是最常用的数值变换函数,同时会将结果值归一化,将分布区间很大的数字映射到(0, 1)的区间之内。Sigmoid函数的表达式如下:
这个函数的曲线如下:
结合下表可以看到,当x的取值小于-5或者大于5的时候,sigmoid(x)的值已经非常接近0或者1了,这意味着当x的取值在(-5, 5)区间之外的时候,x值的差异所带来的函数值的差异将会非常微小。
在使用sigmoid函数之前,一般会把要处理的值变换到(-N, N)这样一个对称的区间里。结合不同的应用场景,一般我们取整数N值在5~10之间。变换的操作一般是这样的:假设x的取值在集合A里面,那么我们取A的中值Me,那么x到x’的变换这样操作即可:

其中MAX的取值一般是所有|(x-Me)|里面最大的那个(绝对值)。不过真正操作的时候,要注意x里面是不是存在个别特别大的值,根据个别特别大的x计算得来MAX是不合适的,一般会把它们去掉之后再算MAX。去掉奇异值之后,会导致最终的x’的取值有个别不在(-N, N)之内的情况,不过它们带来的影响很小,可以忽略掉。

<U, I, Score>里面的Score是对“用户U对内容I的喜好程度”的一个客观描述,可以通过直接的计算来获取。举个例子,假如U是一个视频用户,I是一部电影,那么Score可以是用户U对电影I的观看时长t的sigmoid值。

说到这里,要引入一个“空间”的概念。假如我们要用sigmoid(t)来计算用户对视频的喜好Score,那么把电影和电视剧放一起就不是一个明智的做法。因为一部电影的时长一般在90~120分钟之间,而一部20集的电视剧,假设一集就30分钟,那么也有600分钟的总时长。这时候我们要分“空间”分别计算Score的取值,将同类内容放到同一个空间里,不同内容放在不同的空间里。

在实践中,也有直接把<U, I, Score>里的Score直接处理成0/1值的,用户对内容喜欢就是1,不喜欢就是0,这时候可以抹去Score为0的记录,剩下的<U, I, 1>元组里面的1也可以省略,这样每条记录就剩下一个用户ID和一个内容ID。
<U, I, Score>的结果是推荐系统中多个后续操作步骤的基础,包括协同过滤的计算、用户建模等等。
Item权重的计算

假如新来一位用户,对其我们一无所知,那么该给她推荐哪些内容?当然最热门的内容是不错的选择,同时我们不能忽略了新内容,尤其对于新闻这样的时效性非常强的应用领域来说。我们这里介绍<I, Score>里面Score的计算,它是内容Item本身流行度/质量分和时效性得分的综合。我们这里用P_Score表示流行度得分(可以认为流行度也包含了对内容质量的评价),用F_Score表示时效性得分(Freshness Score)。

对流行度得分P_Score的计算比较容易,在应用领域里面收集最能代表用户对内容喜好的指标值,再使用上面介绍过的sigmoid函数对该指标值进行处理即可。比如在视频领域,用户对视频的观看次数(Video View)就很有代表性。在新闻应用里面,可以使用阅读新闻的用户数。这

里还有两个要点需要说明,其一是,在每个应用领域里面都有多个指标能够代表用户对内容的喜好程度,比如视频领域里除了观看次数,还可以用观看时长、观看人数、用户评分、评论次数/人数等等,我们选择最有代表性的一个即可。如果有兴趣,可以研究一下把它们综合使用(可以引入一些数据挖掘的手段),看是否比单一使用有更好的效果。要说明的第二点是,在收集用户喜好的时候一定要注意数据的清洗。比如计算视频的观看次数的时候,会把观看时长小于一定值的观看给过滤掉,因为这说明用户并不是真的要去观看该视频。

对F_Score的计算需要引入一些技巧。在介绍F_Score的计算方法之前,我们先看看为什么要计算F_Score,以及应该如何用它。

首先,F_Score应该能够一定程度上解决“新内容”的问题,也就是冷启动问题的一种。新内容的问题就是我们对它们的流行度一无所知,也就是它们的P_Score还都是0。那么这时候F_Score就要为其作出补偿。其次,而当积累一定用户流量之后,对于优质内容来说,它们的P_Score就会快速提升,这时候F_Score的值应该相应地下降。

对于那些P_Score没有及时提升的内容来说,它们的整体得分就应该下降,从而在推荐排序中不断下降,减少被曝光的机会。P_Score的取值是sigmoid的结果,分布在(0, 1)区间里,对于新内容来说其值是0,这时候其F_Score的值应该是最大的,接近1。随着时间的推移,F_Score的值应该下降,其下降速度应该与多数内容的P_Score值的上升速度相当。

基于互补的思路,我们使用加权求和的方式结合P_Score和F_Score来得到<I, Score>中的Score的取值:
其中0≤α,β≤1,且α+β=1。
在实际应用中,时效性的过期是非常快的,热门内容的流行度提升也非常快。因此常用指数函数来描述时效性,如下:
其中w是我们给的一个权重,多数时候取1即可,a是底数,取值在(0, 1)区间,t是内容上线到目前为止过去的时间,根据不同场合以天或者小时为单位,取值范围是[0,+∞)。其函数曲线如下图所示。

底数a的选择比较关键。这我们定义一个半衰期T,来表示经过多长时间内容的时效性得分就减半,取a为T的倒数即可,即:a=1/T

其中T>1。可以结合主流内容的流行度得分随着时间的上升速度来确定T,使得P_Score和F_Score结合之后的得分对于主流内容来说比较平稳的T就是好的选择。

最后再解释一下使用加法来结合P_Score和F_Score的思路,那就是把二者看做是互补的两个值,在P_Score很小的时候F_Score取值较大,反之F_Score衰减到较小值的时候,优质内容的P_Score值已经得到了相应的提升。当然劣质内容在我们不知道真相时也会得到曝光机会,但是会随着用户的反馈而迅速衰减。

这里P_Score和F_Score的结合不适宜用乘法。试想,一条内容在没有流行度信息的时候和新鲜度衰减一定时间之后,二者的乘积都接近于0,那么新内容和热门老内容都得不到足够的曝光机会。在这里,加法更接近于逻辑运算里的“或”操作,乘法更接近于逻辑运算里的“与”操作。
内容-标签和用户-标签权重的计算

关于内容上面标签的得分,也就是<I, T, Weight>里面的Weight,分两种情况简单介绍。其一是对于文本内容来说,T的含义不是Tag,而是信息检索领域里的Term,有一种成熟的计算方式,就是tf-idf,请参考tf-idf的百科解释。其二就是像音乐、视频、商品等领域的标签信息,这些标签都是人工添加的,认为其权重都是1是最常见的做法。

关于用户-标签权重的计算,也就是<U, T, Preference>里面的Preference,基本是基于用户在内容上的行为来进行统计。统计方式很直接,如下面的公式所示:
其中用户在标签t上的〖Preference〗_(u,t),就是对于用户看过的每一个视频上的Tag,将其Score进行求和。不过还是要将〖Preference〗_(u,t)的取值归一化到(0, 1)区间内,这里一般使用max-min标准化的方式,其函数表达式如下:
推荐排序
(0)

相关推荐