推薦系統的目的是聯系用戶的興趣和物品,這種聯系需要以來不同的媒介。GroupLens在一篇文章中表示目前流行的推薦系統基本上通過3種方式聯系童虎興趣和物品。
第一種方式是利用用戶喜歡過的物品,給用戶推薦與他喜歡過的物品相似的物品,也就是基于物品的推薦算法。第二種方式是利用和用戶興趣相似的其他用戶,給用戶推薦那些和他們興趣愛好相似的其他用戶的喜歡的物品,也就是基于用戶的推薦算法。第三種方式是通過一些特征聯系用戶和物品,給用戶推薦那些具有用戶喜歡的特征的物品**。特征有不同的表現方式,比如可以表現為物品的屬性集合(比如對于圖書,屬性集合包括作者、出版社、主題和關鍵詞等),也可以表行為隱語義向量,可以通過隱語義模型學習得到。還有一種重要的特征表現方式---標簽。
根據維基百科的定義,標簽是一種無層次化結果的、用來描述信息的關鍵詞,可以用來描述物品的語義。根據給物品打標簽的人的不同,標簽應用一般分為兩種:一種是讓作者或者專家給物品打標簽;另一種是讓普通用戶給物品打標簽,也就是UGC(User Generated Content,用戶生成的內容)的標簽應用。UGC的標簽系統是一種表示用戶興趣和物品語義的重要方式。當一個用戶對一個物品打上一個標簽,這個標簽一方面描述了用戶的興趣,另一方面則表示了物品的語義,從而將用戶和物品聯系了起來。
UGC標簽系統的代表應用
UGC標簽系統是很多Web2.0網站的必要組成部分,使用UGC標簽系統的代表網站---UGC標簽系統的鼻祖Delicious、論文書簽網站CiteULike、音樂網站Last.fm、視頻網站Hulu、書和電影評論網站豆瓣等。
Delicious
Delicious允許用戶給互聯網上的每個網頁打標簽,從而通過標簽重新組織整個互聯網。
CiteULike
CiteULike是一個著名的論文書簽網站,允許研究人員提交或者收藏自己感興趣的論文并且給論文打標簽,從而幫助用戶更好地發現和自己研究領域相關的優秀論文。
標簽系統在各種各樣的(音樂、視頻和社交等)網站中都得到了廣泛應用。標簽系統的最大優勢在于可以發揮群體的智能,獲得對物品內容信息比較準確的關鍵詞描述,而準確的內容信息是提升個性化推薦系統性能的重要資源**。
標簽系統中的推薦問題
打標簽作為一種重要的用戶行為,蘊含了很多用戶興趣信息,深入研究和利用用戶打標簽的行為可以很好地知道我們改進個性化推薦系統的推薦質量。同事標簽的表示形式非常簡單,便于很多算法處理。
標簽系統中的推薦問題主要有以下兩個:
- 如何利用用戶打標簽的行為為其推薦物品(基于標簽的推薦)?
- 如何在用戶給物品打標簽時為其推薦適合該物品的標簽(標簽推薦)?
為了研究上面的兩個問題,首先需要回答3個問題:
- 用戶為什么要打標簽?
- 用戶怎么打標簽?
- 用戶打什么樣的標簽?
用戶為什么打標簽
在設計基于標簽的個性化推薦系統之前,需要深入了解用戶的標注行為(即打標簽的行為),知道用戶為什么要標注,用戶怎么標注,只有深入了解用戶的行為,才能基于這個行為設計出令他們滿意的個性化推薦系統。
Morgan Ames從兩個維度探討。首先是社會維度,有些用戶標注是給內容上傳者使用的(便于上傳者組織自己的信息),而有些用戶標注是給廣大用戶使用的(便于幫助其他用戶找到信息)。利用一個維度是功能維度,有些標注用戶更好地組織內容,方便用戶將來的查找,而另一些標注用戶傳達某種信息,比如照片的拍攝時間和地點等。
用戶如何打標簽
在互聯網中,盡管每個用戶的行為看起來是隨機的,但其實這些表面隨機的行為背后蘊含著很多規律。
用戶活躍度和物品流行度的分布都遵循長尾分布,發現標簽流行度的分布也呈現非常典型的長尾分布。
用戶打什么的標簽
在用戶看到一個物品時,希望他打的標簽是能夠準確描述物品內容屬性的關鍵詞,但用戶旺旺不是按照我們的想法操作,可能會給物品打上各種各樣奇奇怪怪的標簽。
常見的情況是提供許多各種各樣的標簽供用戶選擇,給物品打上他認為的標簽。
基于標簽的推薦系統
用戶用標簽來描述對物品的看法,因此標簽是聯系用戶和物品的紐帶,也是反應用戶興趣的重要數據源,如何利用用戶的標簽數據提高個性化推薦結果的質量?
一個用戶標簽行為的數據集一般由一個三元組的集合表示,其中記錄(u,i,b)表示用戶u給物品i打上了b標簽。用戶真實標簽行為數據遠遠比三元組表示的復雜,比如用戶打標簽的時間、用戶的屬性數據、物品的屬性數據等。
一個最簡單的標簽系統推薦算法
算法描述如下:
- 統計每個用戶最常用的標簽;
- 對于每個標簽,統計被打過這個標簽次數最多的物品;
- 對于一個用戶,首先找到他最常用的標簽,然后找到具有這些標簽的最熱門物品推薦給這個用戶。
對于上面算法,用戶u對物品i的興趣公式如下:
B(u)是用戶u打過的標簽集合,B(i)是物品i被打過的標簽集合,是用戶u打過標簽b的次數,
是物品i被打過標簽b的次數。
算法改進
預測用戶u對物品i的興趣公式,可以發現很多缺點。
1.TF-IDF
原來的計算公式傾向于給熱門標簽對應的熱門物品很大的比重,會造成推薦熱門的物品給用戶,從而降低推薦結果的新穎性。另外,利用用戶的標簽向量對用戶興趣建模,其中每個標簽都是用戶使用過的標簽,而標簽的權重是用戶使用該標簽的次數。這種建模方法的缺點是給熱門標簽過大的權重,從而不能反應用戶個性化的興趣。借鑒TF-IDF思想,對其進行改進:
記錄標簽b被多少個不同的用戶使用過。
也可以對熱門物品進行懲罰,得到如下公式:
其中,表示物品i被多少不同的用戶打過標簽。
實驗表明,適當懲罰熱門標簽和熱門物品,在增進推薦結果個性化的同時并不會降低推薦結果的離線精度。
2.數據稀疏性
在前面的算法中,用戶興趣和物品的聯系是通過中的標簽建立的。但對于新用戶或者新物品,這個集合中的標簽數量會很少。為了提高推薦的準確率,可能要對標簽集合做擴展,比如用戶曾經用過“推薦系統”這個標簽,可以將這個標簽的相似標簽也加入到用戶標簽集合中,比如“個性化”,“協同過濾”等標簽。
進行標簽擴展有很多方法,常用的有話題模型(topic model),簡單的方法有基于鄰域的方法。
標簽擴展的本質是對每個標簽找到和它相似的標簽,也就是計算標簽之間的相似度。最簡單的相似度可以是同義詞,如果有一個同義詞詞典,可以根據詞典進行標簽擴展;如果沒有詞典,可以從數據中統計出標簽的相似度。
如果認為同一個物品上的不同標簽具有某種相似度,那么當兩個標簽同時出現在很多物品的標簽集合中時,可以認為這兩個標簽具有較大的相似度。
實驗發現,進行標簽擴展確實能夠提高基于標簽的物品推薦的準確率和召回率,但可能會稍微降低推薦結果的覆蓋率和新穎度。
3.標簽清理
不是所有標簽都能反應用戶的興趣。標簽清理的另一個重要意義在于將標簽作為推薦解釋。如果我們要把標簽呈現給用戶,將其作為給用戶推薦某一個物品的解釋,對標簽的質量要求就很高。首先,這些標簽不能包含沒有意義的停止詞或者表示情緒的詞,其次這些推薦解釋里不能包含很多意義相同的詞語。
一般標簽清理方法:
- 去除詞頻很高的停止詞;
- 去除因詞根不同造成的同義詞,比如recommender system 和 recommendation system;
- 去除因分隔符造成的同義詞,比如collaborative_filtering 和 collaborative-filtering。
為了控制標簽的質量,很多網站也采用了讓用戶進行反饋的思想,即讓用戶告訴系統某個標簽是否合適。
基于圖的推薦算法
首先,我們需要將用戶打標簽的行為表示到一張圖上。帶權圖是由頂點、邊和邊上的權重組成的。而在用戶標簽數據集上,有3種不同的元素,即用戶、物品和標簽。因此,需要定義3種不同的頂點,即用戶頂點、物品頂點和標簽頂點。然后,如果我們得到一個表示用戶u給物品i打了標簽b的用戶標簽行為 (u,i,b),那么在圖中增加3條邊,首先需要在用戶u對應的頂點v(u)和物品i對應的頂點v(i)之間增加一條邊(如果這兩個頂點已經有邊相連,那么就應該將邊的權重加1),同理,在v(u) 和v(b)之間需要增加一條邊, v(i)和v(b)之間也需要邊相連接。
用圖模型解釋前面的簡單算法。用戶對物品的興趣公式表示為:
公式假定用戶對物品的興趣通過標簽傳遞。因此,可以更簡單的建模,省去用戶和物品之前的連線。
基于標簽的推薦解釋
基于標簽的推薦其最大好處是可以利用標簽做推薦解釋,這方面的代表性應用是豆瓣的個性化推薦系統。
要讓用戶直觀上感覺推薦結果有道理是很困難的,而豆瓣將推薦結果的可解釋性拆分成了兩部分,首先讓用戶覺得標簽云是有道理的,然后讓用戶覺得從某個標簽推薦出某本書也是有道理的。
- 用戶對標簽的興趣對幫助用戶理解為什么給他推薦某個物品更有幫助(因為你對這個標簽感興趣,所以給你推薦這個標簽下的物品);
- 用戶對標簽的興趣和物品標簽相關度對于幫助用戶判定自己是否喜歡被推薦物品具有同樣的作用;
- 物品標簽相關度對于幫助用戶判定被推薦物品是否符合他當前的興趣更有幫助;
- 客觀事實類標簽相比主觀感受類標簽對用戶更有作用。
給用戶推薦標簽
當用戶瀏覽某個物品時,標簽系統非常希望用戶能夠給這個物品打上高質量的標簽,這樣才能促進標簽系統的良性循環。因此,很多標簽系統都設計了標簽推薦模塊給用戶推薦標簽。
為什么要給用戶推薦標簽
給用戶推薦標簽有以下好處:
- 方便用戶輸入標簽: 讓用戶從鍵盤輸入標簽會增加用戶大標簽的難度,這樣很多用戶不愿意給物品打標簽,因此需要一個輔助工具來減小用戶打標簽的難度,從而提供用戶打標簽的參與度。
- 提高標簽質量: 同一個語義不同的用戶可能用不同的詞語來表示。這些同義詞會使標簽的詞表變得很龐大,而且會使計算相似度不太準確。而使用推薦標簽時,可以對詞表進行選擇,首先保證詞表不出現太多的同義詞,同事保證出現的詞都是一些比較熱門的、有代表性的詞。
如何給用戶推薦標簽
用戶u給物品i打標簽時,有很多方法可以給用戶推薦和物品i相關的標簽。比較簡單的方法有4種。
第1種方法就是給用戶u推薦整個系統里最熱門的標簽;令tags[b]表示標簽b的熱門程度,
def RecommendPopularTags(user, item, tags, N):
return sorted(tags.items(),key=lambda a:a[1],reverse=True)[:N]
第2種方法是給用戶u推薦物品i上最熱門的標簽;item_tags[i][b]為物品i被打上標簽b的次數,
def RecommendItemPopularTags(user, item, item_tags, N):
return sorted(item_tags[item].items(),key=lambda a:a[1],reverse=True)[:N]
第3種方法是給用戶u推薦他自己經常使用的標簽;users_tags[u][b]為用戶u經常使用的標簽b的次數:
def RecommendUserPopularTags(user,item,user_tags,N):
return sorted(user_tags[user].items(),key=lambda a:a[1],reverse=True)[:N]
第4種方法是前面兩種方法的融合,通過一個系數將上面的推薦結果線性加權,然后生成最終的推薦結果:
def RecommendHybridPopularTags(user,item,user_tags,item_tags,alpha,N):
max_user_tag_weight = max(user_tags[user].values())
for tag,weight in user_tags[user].items():
ret[tag] = (1-alpha)*weight / max_user_tag_weight
max_item_tag_weight = max(item_tags[item].values())
for tag,weight in item_tags[item].items():
if tag not in ret:
ret[tag] = alpha * weight / max_item_tag_weight
else:
ret[tag] += alpha*weight/max_item_tag_weight
return sorted(ret.items(),key=lambda a:a[1],reverse=True)[:N]
在將兩個列表線性相加時將兩個列表按最大值做了歸一化,好處是便于控制兩個列表對最終結果的影響,不至于因為物品非常熱門而淹沒用戶對推薦結果的影響,或因為用戶非常活躍淹沒物品對推薦結果的影響。
但是,上面基于統計用戶常用標簽和物品常用標簽算法有一個缺點,對新用戶或者不熱門的物品很難有推薦結果。解決這一問題有兩個思路:
- 從物品的內容數據中抽取關鍵詞作為標簽。這方面的研究很多,特別是在上下文廣告領域。
- 針對有結果,但結果不太多的情況。對標簽進行標簽擴展。標簽擴展的關鍵在于計算標簽之間的相似度。
基于圖的標簽推薦算法
圖模型可以用于標簽推薦。