美文网首页推荐算法
从多样性谈起到dpp

从多样性谈起到dpp

作者: lipku | 来源:发表于2021-04-10 18:01 被阅读0次

    在推荐算法中,除了要考虑个性化,还要兼顾多样性,不然用户很快就会觉得单调无趣。
    在衡量推荐结果的多样性时,自然而然能想到的是统计推荐结果中含有不同tag的个数,tag的个数越多,多样性越好。但是这种指标有个问题,它与用户看的内容条数正相关,用户看的内容条数越多,自然tag个数会越多。假设一条feed平均有3个tag,只看了1条feed用户的多样性指标是3;看了10条feed的用户,总共有30个 tag,假设有50%的重合度,有15个不同tag,大大高于看了1条feed的用户。
    为了抵消feed条数的影响,于是有人又想到了用不同tag个数/feed条数。这样乍看起来比较合理,但其实又会与feed条数负相关了。还是以上面的例子来计算,看了1条feed的用户,多样性指标是3/1=3; 看了10条feed的用户,多样性指标是15/10=1.5,低于看了1条feed的用户。只要看过的多条feed之间有重复的tag,多样性指标就会低于只看了1条feed的用户。
    以上两种指标都与用户的行为条数相关,都不是稳定的指标。下面介绍一个稳定的指标,用feed两两之间不同tag个数的总和/feed两两组合个数,代码如下:

    def compute_diversity(item_list, item_cate_map):
        n = len(item_list)
        diversity = 0.0
        for i in range(n):
            for j in range(i+1, n):
                diversity += item_cate_map[item_list[i]] != item_cate_map[item_list[j]]
        diversity /= ((n-1) * n / 2)
        return diversity
    

    这个指标基本与用户的行为条数无关了,因此是稳定的。
    但上面的指标也有个问题,就是过度依赖feed的tag。tag描述有两个问题:一是无法全面表示feed内容,另外是tag的粗细粒度不一致,比如汽车和宝马都是tag,但他们的描述范围差别很大。我们知道,embedding向量可以用来表示feed,而且粒度相对一致。那么可不可以用embeding代替tag来计算多样性呢,答案是肯定的。
    用fi表示feedi的embedding;用<fi,fj>表示两个embedding的点积,点积代表两个向量的相似度;用1-<fi,fj>表示两个向量的差异性,即两个feed之间的差别程度。参考上面tag的方式,可以用如下公式来计算feed列表的多样性:
    \frac{\sum_{i=0}^n\sum_{j=i+1}^n1-f_i\cdot f_j}{(n-1)*n/2}
    这个公式有点不完美的是只考虑了两个feed之间的差别,没有考虑多个feed之间的整体差别,举个极端点的例子:假设第一组3个feed,A与B的点积为1,C与A、B的点积都为0,用上面公式计算这3个feed的多样性为(0+1+1)/3=2/3; 第二组3个feed,A、B、C之间的点积都为0.5,多样性为(0.5+0.5+0.5)/3=0.5; 单纯从指标上来看,第一组的多样性要高于第二组。但实际上第二组的多样性更好,因为第一组feed A与B完全一样, 第二组3个feed两两之间的差别比较均匀。
    那么有没有更好的方式来计算feed列表的多样性呢。我们知道feed embedding是一个向量,向量之间的夹角代表feed的差别大小,夹角越大差别越大。那么我们可以用列表中所有feed embedding向量撑起的多维体的体积来表示整个列表的多样性,体积越大多样性越好,这既考虑了feed两两之间的差别,也考虑到了整体差别的均匀性,不会因为某两个feed差别过大而忽略了其他feed的差别。

    多维体体积.png

    下面介绍怎么计算体积,定义矩阵L,L_{ij}=f_i\cdot f_j=r_ir_j\cos\alpha_{ij},表示feed embedding两两之间的点积,其中r表示feed embedding向量的长度,归一化的embedding一般为1, \alpha_{ij}表示两个feed之间的夹角,矩阵的格式如下:
    \begin{bmatrix} f_1\cdot f_1&f_1\cdot f_2&\cdots&f_1\cdot f_n\\ f_2\cdot f_1&f_2\cdot f_2&\cdots&f_2\cdot f_n\\ \vdots&\vdots&\ddots&\vdots\\ f_n\cdot f_1&f_n\cdot f_2&\cdots&f_n\cdot f_n\\ \end{bmatrix}= \begin{bmatrix} r_1^2&r_1r_2\cos\alpha_{1,2}&\cdots&r_1r_n\cos\alpha_{1,n}\\ r_1r_2\cos\alpha_{1,2}&r_2^2&\cdots&r_2r_n\cos\alpha_{2,n}\\ \vdots&\vdots&\ddots&\vdots\\ r_1r_n\cos\alpha_{1,n}&r_2r_n\cos\alpha_{2,n}&\cdots&r_n^2\\ \end{bmatrix}
    先下结论矩阵L的行列式|L|即为多维体体积的平方。
    先看两维的情况:
    \left|\begin{matrix} r_1^2&r_1r_2\cos\alpha_{1,2}\\ r_1r_2\cos\alpha_{1,2}&r_2^2\\ \end{matrix}\right|= r_1^2r_2^2(1-\cos^2\alpha_{1,2})= (r_1r_2\sin\alpha_{1,2})^2,
    这正好是f1、f2两个embedding向量组成的平行四面体的面积平方值。

    平行四边形.png

    再看三维的情况:
    \left|\begin{matrix} r_1^2&r_1r_2\cos\alpha_{1,2}&r_1r_3\cos\alpha_{1,3}\\ r_1r_2\cos\alpha_{1,2}&r_2^2&r_2r_3\cos\alpha_{2,3}\\ r_1r_3\cos\alpha_{1,3}&r_2r_3\cos\alpha_{2,3}&r_3^2\\ \end{matrix}\right|= r_1^2r_2^2r_3^2(1+2\cos\alpha_{1,2}\cos\alpha_{1,3}\cos\alpha_{2,3}-\cos^2\alpha_{1,2}-\cos^2\alpha_{1,3}-\cos^2\alpha_{2,3})
    这正好是f1、f2、f3三个embedding向量组成的平行六面体的体积平方值

    平行六面体.png

    依此类推,n维矩阵L的行列式为f1、f2、···、fn组成的多维体的体积平方值。
    至此,我们可以用列表中feed embedding向量两两之间的点积组成矩阵L,然后计算L的行列式值表示该列表的多样性。这种方式可以比较完美的衡量一个feed列表的多样性。
    在推荐算法中还有一种应用场景,就是在排序后的m个feed中选出k(k<m)个feed,使这k个feed的排序分尽量高,同时多样性最大化。这时不能只考虑多样性了,还要兼顾排序分。我们可以改造一下上面的矩阵L,使L_{ij}=s_is_jf_i\cdot f_j=s_is_jr_ir_j\cos\alpha_{ij},其中s表示feed的排序分,也就是使原来feed embedding向量长度伸缩s倍。伸缩后的向量组成的多维体体积越大,即边长(排序分)尽量大的同时,夹角(多样性)也要尽量大,这样同时兼顾了排序分和多样性。这即是著名的dpp算法了。
    在实际使用中,还可以修改一下矩阵L,使L_{ij}=ws_is_jf_i\cdot f_j,通过修改w来调节排序分与多样性之间的权重,使结果更偏重于排序还是多样性。对不同的用户用不同的w,即可以实现多样性的个性化。对不同排序模型用不同的w来消除不同排序模型对dpp的bias影响。

    相关文章

      网友评论

        本文标题:从多样性谈起到dpp

        本文链接:https://www.haomeiwen.com/subject/vwpnkltx.html