推薦系統(二) —— 利用用戶行爲數據 —— 基於領域的算法

爲了讓推薦結果符合用戶口味,我們需要深入瞭解用戶。用戶的行爲不是隨機的,而是蘊含着許多模式的。基於用戶行爲分析的推薦算法是個性化推薦系統的重要算法,僅僅基於用戶行爲數據設計的推薦算法學術上稱作“協同過濾算法”。協同過濾,就是指用戶可以齊心協力,通過不斷地和網站互動,是自己的推薦列表能夠不斷過濾掉自己不感興趣的物品,從而越來越滿足自己的需求。

系統過濾算法,包含基於領域的算法、隱語義模型、基於圖的算法等。

下面我們先從用戶行爲數據的一些特點講起,再詳細講解上述各類算法。

1、用戶行爲數據

1.1 簡介

用戶行爲數據在網站上最簡單的存放形式就是日誌。網站在運行過程中都會產生大量原始日誌,很多互聯網業務會把多種原始日誌按照用戶行爲彙總成會話日誌,其中每個會話表示一次用戶行爲和對應的服務。會話日誌通常存儲在分佈式數據倉庫中,如支持離線分析的Hadoop Hive和支持在線分析的Google Dremel。

用戶行爲在個性化推薦系統中一般分爲兩種:顯性反饋行爲,和隱性反饋行爲。顯性反饋行爲包括用戶明確表示對物品喜惡的行爲。隱性反饋行爲指的是那些不能明確反映用戶喜惡的行爲,但數據量更大。在很多網站中,很多用戶甚至只有隱性反饋數據。

互聯網中的用戶行爲有很多種,用一種統一的方式來表示所有行爲很困難。一種叫可行的用戶行爲的統一表示可以包含以下部分:

user id,item id,behavior type,context(上下文),behavior weight,behavior content。

1.2 用戶行爲中蘊含的規律

互聯網上的很多數據分佈都滿足Power Law分佈,在互聯網領域也稱作長尾分佈:。

有意義的是,很多用戶行爲數據也蘊含着這種規律,例如:

對個物品產生過行爲用戶數;

被個用戶產生過行爲的物品數;

對應物品流行度爲的物品總數;

對應用戶活躍度爲的用戶總數;

對應用戶活躍度爲的所有用戶評過分的物品的平均流行度;

等等。。。。

這些規律並不是只存在於一兩個網站中的特例,而是存在於很多網站中的普遍規律。

2、基於領域的算法

2.1 基於用戶的協同過濾算法

1、 UserCF是推薦系統中最古老的算法,其誕生標誌着推薦系統的誕生。UserCF算法主要包含兩個步驟:

(1) 找到和目標用戶興趣相似的用戶集合

(2) 找到這個集合中的用戶喜歡的,且目標用戶沒有聽說過的物品,並將其推薦給目標用戶。

2、 UserCF算中(1)中,用戶之間的興趣相似度可以通過餘弦相似度公式計算

實際上,用戶間對冷門物品採取過同樣的行爲更能說明他們興趣的相似度,因此,我們可以通過懲罰用戶間共同興趣列表中熱門物品的影響(通過下式可見是用分子懲罰的),對上述用戶相似度計算式進行改進

3、 UserCF算中(2)中,度量用戶對某物品的感興趣程度可以用:

其中r爲用戶v對物品i的興趣指數。

4、UserCF算法(與改進興趣相似度公式後的User-IIF算法)的Python實現

UserCF algorithm

def UserSimilarity(train):

input trainSet is a dict, for example:

# train = {'A':{'a':rAa, 'b':rAb, 'd':rAd}, 'B':{...}, ...}
# build the inverse table for item_users
item_users_table = dict()
for user, items in train.items():
    for item in items.keys():
        if item not in item_users_table:
            item_users_table[item] = set()
        item_users_table[item].add(user)
# calculate co-rated items between users
# item_users_table = {'a':set('A','B'), 'b':set('A','C'), ...}
C = dict() # this is the member of W
N = dict() 
for item, users in item_users_table.items():
    for uu in users:
        N[uu] += 1
        for vv in users:
            if uu == vv:
                continue
            ## simple cosine user similarity
            C[uu][vv] += 1
            ## modified cosine user similarity
            C[uu][vv] += 1 / math.log(1.0+len(item))
# calculate final similarity matrix W
W = dict()  
for uu, related_user in C.items():
    for vv, Cuv in related_user.items():
        W[uu][vv] = Cuv / math.sqrt(N[uu]*N[vv])
return W

def Recommend(train, user_u, W, K):
rank = dict()
uu = user_u
interacted_items = train[uu]

S(u,K) ahead of N(i)

for vv, Wuv in sorted(W[uu].items, key=itemgetter(1), reverse=True)[0:K]:
    for item, rvi in train[vv].items():
        if item in interacted_items.keys():
            continue
            # filter the items which user interacted before
        rank[item] += Wuv * rvi
return rank

5、 算法性能分析

(1) UserCF算法中重要參數K與推薦算法的精度指標(Recall和Precision)並不成線性增長關係,且精度對K也不是特別敏感。

(2) K越大,參考的人越多,結果就越趨近於全局熱門物品,因而導致流行度指數越高,即推薦結果的新穎度降低。

(3) 隨着K增大,推薦物品的流行度增加,算法將傾向於推薦熱門物品,從而對長尾物品挖掘能力變差,造成算法覆蓋率降低。

(4) UserCF算法固有缺點在於:一則,隨着網站的用戶數目增多,計算用戶興趣相似度矩陣W將越來越困難,其運算時間複雜度和空間複雜度的增長與用戶數的增長近似成平方關係。二來,UserCF算法難以對其推薦的結果作出解釋,不太適用於商品推薦、視頻推薦等場景。

2.2 基於物品的協同過濾算法

1、 ItemCF算法是目前業界應用最多的算法。ItemCFB算法並不是利用物品的內容屬性計算物品之間的相似度,而是通過分析大量用戶的行爲來記錄並計算物品之間的相似性,因此可以利用用戶的歷史行爲給推薦結果提供推薦。ItemCF算法主要分爲兩步:

(1) 計算物品之間的相似度

(2) 根據物品的相似度以及用戶的歷史行爲給用戶生成推薦列表

2、 ItemCF算法(1)中,在前提“每個用戶的興趣都侷限在某幾個方面”下,可以用下式計算

當上式還存在一個問題,由於每個用戶的興趣列表都會對物品的相似度產生貢獻,但活躍用戶的興趣顯然沒有非活躍用戶的興趣那麼集中,應該使活躍用戶對物品相似度的貢獻低於不活躍用戶才合理,因此可以引進IUF,即用戶活躍度對數的倒數的參數,對上式進行改進:

實際上,IUF只是對活躍用戶做了一種軟性懲罰,實際計算中,往往直接把過於活躍的用戶的興趣列表忽略掉,完全不將其納入相似度計算中,同時避免了相似度矩陣過於稠密。
3、 ItemCF算法(2)中,度量用戶對某物品的感興趣程度可以用:

4、 ItemCF算法(與改進興趣相似度公式後的Item-IUF算法)的Python實現

ItemCF algorithm

def ItemSimilarity(train):

calculate co-rated users between items

C = dict()
N = dict()
for user, items in train.items():
    for ii in items:
        N[ii] += 1
        for jj in items:
            if ii == jj:
                continue
            ## the simple cosine item similarity
            C[ii][jj] += 1
            ## the modified cosine item similarity
            C[ii][jj] += 1 / math.log(1.0+len(user))
# calculate final similarity matrix W
W = dict()  
for ii, related_items in C.items():
    for jj, Cij in related_items.items():
        W[ii][jj] = Cij / math.sqrt(N[ii]*N[jj])
return W

def Recommend(train, user_u, W, K):
rank = dict()
uu = user_u
interacted_items = train[uu]

N(u) ahead of S(j,K)

for item, rui in interacted_items.items():
    for jj, Wij in sorted(W[item].items, key = itemgetter(1), reverse = True)[0:K]:
        if jj in interacted_items.keys():
            continue
            # filter the items which user interacted before
        rank[jj].weight += Wij * rui
        rank[jj].reason[item] = Wij * rui
        # give the reason of recommendation
return rank

5、 算法性能分析

(1) 同樣,ItemCF算法中參數K也不與結果精度呈正相關或者負相關。

(2) 區別於UserCF,參數K對ItemCF結果的流行度並不是完全正相關的,隨着K增大,流行度逐漸提高但最終會緩慢下降。

(3) 同UserCF,K的增加會降低系統的覆蓋率。

(4) 注意,通過將ItemCF的相似度矩陣按列最大值歸一化,可以提高系統的準確率、覆蓋率和多樣性,即。

(5) ItemCF算法的覆蓋率和新穎度都不高,是由於熱門物品在相似度矩陣計算中造成了太大的影響,一般可以在wij的分母上對N(i)取指數1-alpha,N(j)取指數alpha,通過調整使熱門物品的alpha大於0.5,甚至更大,對其作出懲罰,可以一定程度上犧牲精度而顯著提高覆蓋率和新穎性。但此方法依然效果一般,即在不同領域的最熱門物品之間往往具有較高的相似度情況下,僅僅靠用戶行爲數據很難解決上述問題。此時,只能依靠引入物品的內容數據解決此問題,比如對不用領域的物品降低權重等,當然這些暫時不是協同過濾的討論範疇。

2.3 UerCF 與ItemCF 比較

1、 從二者的推薦原理來看,UserCF的推薦結果着重於反應和用戶興趣相似的小羣體的熱點,而ItemCF的推薦結果着重於維繫用戶的歷史興趣,即,前者的推薦更社會化,反映了用戶所在的小型興趣羣體中物品的熱門程度,而後者更加個性化,反映了用戶自己的興趣傳承。
2、 從技術角度來看,UserCF需要維護一個用戶相似度矩陣,而ItemCF需要維護一個物品相似度矩陣。
3、 從這兩點,大致能看出爲什麼文章分享網站Digg使用前者,而亞馬遜使用了後者。
4、 這從另一方面又啓示我們,離線實驗的性能並不是選擇推薦算法的決定性要素,反而應該按照以下順序來選取:(1)應該滿足產品的需求,例如是否需要提供推薦解釋(2)需要看實現代價,也就是用戶更多還是物品更多(3)離線指標和點擊率等在線指標不一定成正比,即使離線指標不太好也沒關係,何況經過各種優化改進,一般都不會太差。
5、 來份優缺點對錶表:

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章