在推薦算法中矢腻,除了要考慮個性化,還要兼顧多樣性射赛,不然用戶很快就會覺得單調(diào)無趣多柑。
在衡量推薦結(jié)果的多樣性時,自然而然能想到的是統(tǒng)計推薦結(jié)果中含有不同tag的個數(shù)楣责,tag的個數(shù)越多竣灌,多樣性越好聂沙。但是這種指標(biāo)有個問題,它與用戶看的內(nèi)容條數(shù)正相關(guān)初嘹,用戶看的內(nèi)容條數(shù)越多及汉,自然tag個數(shù)會越多。假設(shè)一條feed平均有3個tag屯烦,只看了1條feed用戶的多樣性指標(biāo)是3坷随;看了10條feed的用戶,總共有30個 tag驻龟,假設(shè)有50%的重合度温眉,有15個不同tag,大大高于看了1條feed的用戶翁狐。
為了抵消feed條數(shù)的影響类溢,于是有人又想到了用不同tag個數(shù)/feed條數(shù)。這樣乍看起來比較合理露懒,但其實(shí)又會與feed條數(shù)負(fù)相關(guān)了闯冷。還是以上面的例子來計算,看了1條feed的用戶懈词,多樣性指標(biāo)是3/1=3蛇耀; 看了10條feed的用戶,多樣性指標(biāo)是15/10=1.5钦睡,低于看了1條feed的用戶蒂窒。只要看過的多條feed之間有重復(fù)的tag,多樣性指標(biāo)就會低于只看了1條feed的用戶荞怒。
以上兩種指標(biāo)都與用戶的行為條數(shù)相關(guān)洒琢,都不是穩(wěn)定的指標(biāo)。下面介紹一個穩(wěn)定的指標(biāo)褐桌,用feed兩兩之間不同tag個數(shù)的總和/feed兩兩組合個數(shù)衰抑,代碼如下:
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
這個指標(biāo)基本與用戶的行為條數(shù)無關(guān)了,因此是穩(wěn)定的荧嵌。
但上面的指標(biāo)也有個問題呛踊,就是過度依賴feed的tag。tag描述有兩個問題:一是無法全面表示feed內(nèi)容啦撮,另外是tag的粗細(xì)粒度不一致谭网,比如汽車和寶馬都是tag,但他們的描述范圍差別很大赃春。我們知道愉择,embedding向量可以用來表示feed,而且粒度相對一致。那么可不可以用embeding代替tag來計算多樣性呢锥涕,答案是肯定的衷戈。
用fi表示feedi的embedding;用<fi,fj>表示兩個embedding的點(diǎn)積层坠,點(diǎn)積代表兩個向量的相似度殖妇;用1-<fi,fj>表示兩個向量的差異性,即兩個feed之間的差別程度破花。參考上面tag的方式谦趣,可以用如下公式來計算feed列表的多樣性:
這個公式有點(diǎn)不完美的是只考慮了兩個feed之間的差別,沒有考慮多個feed之間的整體差別座每,舉個極端點(diǎn)的例子:假設(shè)第一組3個feed蔚润,A與B的點(diǎn)積為1,C與A尺栖、B的點(diǎn)積都為0,用上面公式計算這3個feed的多樣性為(0+1+1)/3=2/3; 第二組3個feed烦租,A延赌、B、C之間的點(diǎn)積都為0.5叉橱,多樣性為(0.5+0.5+0.5)/3=0.5; 單純從指標(biāo)上來看挫以,第一組的多樣性要高于第二組。但實(shí)際上第二組的多樣性更好窃祝,因?yàn)榈谝唤Mfeed A與B完全一樣掐松, 第二組3個feed兩兩之間的差別比較均勻。
那么有沒有更好的方式來計算feed列表的多樣性呢粪小。我們知道feed embedding是一個向量大磺,向量之間的夾角代表feed的差別大小,夾角越大差別越大探膊。那么我們可以用列表中所有feed embedding向量撐起的多維體的體積來表示整個列表的多樣性杠愧,體積越大多樣性越好,這既考慮了feed兩兩之間的差別逞壁,也考慮到了整體差別的均勻性流济,不會因?yàn)槟硟蓚€feed差別過大而忽略了其他feed的差別。
下面介紹怎么計算體積腌闯,定義矩陣L绳瘟,,表示feed embedding兩兩之間的點(diǎn)積,其中r表示feed embedding向量的長度姿骏,歸一化的embedding一般為1, 表示兩個feed之間的夾角糖声,矩陣的格式如下:
先下結(jié)論矩陣L的行列式|L|即為多維體體積的平方。
先看兩維的情況:
,
這正好是f1、f2兩個embedding向量組成的平行四面體的面積平方值姨丈。
再看三維的情況:
這正好是f1畅卓、f2、f3三個embedding向量組成的平行六面體的體積平方值
依此類推蟋恬,n維矩陣L的行列式為f1翁潘、f2、···歼争、fn組成的多維體的體積平方值拜马。
至此,我們可以用列表中feed embedding向量兩兩之間的點(diǎn)積組成矩陣L沐绒,然后計算L的行列式值表示該列表的多樣性俩莽。這種方式可以比較完美的衡量一個feed列表的多樣性。
在推薦算法中還有一種應(yīng)用場景乔遮,就是在排序后的m個feed中選出k(k<m)個feed扮超,使這k個feed的排序分盡量高,同時多樣性最大化蹋肮。這時不能只考慮多樣性了出刷,還要兼顧排序分。我們可以改造一下上面的矩陣L坯辩,使馁龟,其中s表示feed的排序分,也就是使原來feed embedding向量長度伸縮s倍漆魔。伸縮后的向量組成的多維體體積越大坷檩,即邊長(排序分)盡量大的同時,夾角(多樣性)也要盡量大,這樣同時兼顧了排序分和多樣性。這即是著名的dpp算法了赫蛇。
在實(shí)際使用中,還可以修改一下矩陣L裸删,使,通過修改w來調(diào)節(jié)排序分與多樣性之間的權(quán)重阵赠,使結(jié)果更偏重于排序還是多樣性涯塔。對不同的用戶用不同的w,即可以實(shí)現(xiàn)多樣性的個性化清蚀。對不同排序模型用不同的w來消除不同排序模型對dpp的bias影響匕荸。