PM技術(shù)課 | 推薦系統(tǒng),從原理到實(shí)現(xiàn)
大數(shù)據(jù)時(shí)代,冗雜的信息讓身處其中的用戶們感到迷茫,無法抉擇。所以,大數(shù)據(jù)時(shí)代推薦系統(tǒng)的重要程度就不言而喻了。如何在有限的時(shí)間內(nèi)給用戶推薦合適的信息或商品,是推薦系統(tǒng)最重要的工作。那么,推薦系統(tǒng)是如何運(yùn)轉(zhuǎn)的,其原理以及運(yùn)轉(zhuǎn)流程如何?以下,將由筆者為大家詳細(xì)講述。
一、你關(guān)心的,才是頭條
隨著互聯(lián)網(wǎng)行業(yè)的發(fā)展,網(wǎng)絡(luò)的數(shù)據(jù)量也在不斷增加。僅微信,平均每個(gè)人要關(guān)注幾十甚至上百個(gè)公眾號(hào);淘寶的商品數(shù)量也有上億種。
如何在有限的時(shí)間找到需要的信息或者商品?如何給用戶推薦合適的內(nèi)容和商品?
除了搜索引擎按照用戶的搜索展示外,推薦系統(tǒng)也起了關(guān)鍵作用,通常有兩種推薦方式。
第一種推薦方式是:大眾推薦。
基于“大家都喜歡潮流(跟風(fēng))”這一假設(shè),根據(jù)流行程度進(jìn)行大眾推薦,常見的有熱搜、排行榜,對(duì)于新的作品或者新的商品,也會(huì)單獨(dú)推薦,以提高新鮮感。
這種大眾推薦方式主要依靠閱讀量或者人工進(jìn)行推薦,主要有兩個(gè)問題:一來熱門的數(shù)量有限,用戶可能看一會(huì)兒就沒什么可看的了;另一方面,用戶或許對(duì)特定的領(lǐng)域更感興趣,愿意為此花時(shí)間或者花錢,這也就是所說的長尾效應(yīng)。
這就催生出了第二種推薦方式:個(gè)性推薦,也是我們要講述的。
個(gè)性推薦本質(zhì)上是一種信息過濾系統(tǒng),用于預(yù)測用戶對(duì)物品的偏好,推薦用戶更感興趣的內(nèi)容,用戶使用時(shí)長會(huì)快速增加,刷新聞,一刷就是幾個(gè)小時(shí);推薦用戶更感興趣的商品,“逛”商場的時(shí)間和客單價(jià)也會(huì)相應(yīng)提高。
最近風(fēng)頭正盛的今日頭條正是使用推薦系統(tǒng),獲得快速成長的絕佳范例。
按照今日頭條官網(wǎng)的介紹:今日頭條“一款基于數(shù)據(jù)挖掘的推薦引擎產(chǎn)品,它為用戶推薦有價(jià)值的、個(gè)性化的信息,提供連接人與信息的新型服務(wù)”。通過個(gè)性推薦,今日頭條在短短幾年時(shí)間內(nèi),成長為互聯(lián)網(wǎng)領(lǐng)域炙手可熱的明星。
今日頭條融合了多種特征進(jìn)行計(jì)算,包括興趣、年齡、性別、行為等用戶特征,地理位置、時(shí)間、天氣等環(huán)境特征,主題詞、熱度、時(shí)效性、質(zhì)量、作者來源等文章特征。通過數(shù)據(jù)計(jì)算特征,根據(jù)特征計(jì)進(jìn)行推薦,最終實(shí)現(xiàn)“千人千面”的新聞推薦方式。
在電商領(lǐng)域,最值得稱道的是亞馬遜,亞馬遜宣稱,通過個(gè)性推薦提高了其30%的銷售。
亞馬遜記錄用戶瀏覽頁面的點(diǎn)擊、加入購物車、購買、評(píng)價(jià)等行為,將用戶的行為記錄與其他用戶的進(jìn)行對(duì)比,通過相似用戶,向用戶推薦更多可能感興趣的商品。與此同時(shí),根據(jù)用戶的行為的變化,不定期更新推薦內(nèi)容,充分考慮到了用戶喜好的改變。
除了電商和新聞,在視頻、圖書、音樂等領(lǐng)域,個(gè)性推薦系統(tǒng)也發(fā)揮了越來越大的作用。
常見的個(gè)性推薦算法主要包括:基于內(nèi)容個(gè)性推薦、利用用戶行為的協(xié)同過濾、基于數(shù)學(xué)模型的推薦等。在實(shí)際應(yīng)用中,往往會(huì)將這些推薦系統(tǒng)的結(jié)果進(jìn)行融合,生成最終的推薦。
二、基于內(nèi)容的推薦(Content-Based Recommendation)
1. 猜你喜歡
基于內(nèi)容的推薦主要利用內(nèi)容本身的特征進(jìn)行推薦,把類似的內(nèi)容推薦給用戶。
比如:根據(jù)音樂的流派、類型、歌手等推薦類似的音樂,如果用戶喜歡聽《青花瓷》,音樂APP就會(huì)推薦周杰倫的《千里之外》。同樣也可以根據(jù)商品推薦同類的商品,如果用戶搜索過手機(jī),電商APP就會(huì)在首頁推薦各種牌子的智能手機(jī)。
基于內(nèi)容的推薦是非?;A(chǔ)的推薦策略,最核心環(huán)節(jié)的是:計(jì)算內(nèi)容本身的相似性。
以音樂為例:向用戶推薦同一個(gè)歌手的音樂是很簡單的,用戶喜歡《青花瓷》,就直接把周杰倫的歌單推薦過去就好了。
相比之下,向用戶推薦某個(gè)流派的音樂稍微有些難度,首先要有每一首歌的流派標(biāo)簽,之后根據(jù)標(biāo)簽進(jìn)行推薦,還好幾乎每首歌都有流派標(biāo)簽,比如:流行、輕音樂、搖滾、民謠等。
語言、主題、場景等標(biāo)簽也是類似的。所有這些標(biāo)簽都需要手工標(biāo)記,雖然麻煩,但是也能實(shí)現(xiàn)。
但,如果用戶可能就是喜歡某種調(diào)調(diào),某些歌詞呢?如何向用戶推薦某種曲風(fēng)、曲調(diào)或者歌詞的音樂?這就需要計(jì)算旋律的相似性、歌詞的相似性等。
涉及到音頻處理,這個(gè)問題有些復(fù)雜,一時(shí)半會(huì)兒也說不清楚,我們拿稍微簡單些的新聞推薦,剖析下如何實(shí)現(xiàn)基于內(nèi)容的推薦,雖然具體的操作和算法不同,但原理是相通的。
雖說稍微簡單些,但新聞相似度的計(jì)算也是相當(dāng)復(fù)雜的工作,主要包括獲取新聞、清洗數(shù)據(jù)、數(shù)據(jù)挖掘、計(jì)算相似度等環(huán)節(jié)。
按照所述《網(wǎng)絡(luò)爬蟲》,我們可以使用爬蟲來獲取新聞,這里不再贅述。
數(shù)據(jù)獲取之后,就是數(shù)據(jù)清洗,主要是新聞去重,新聞熱點(diǎn)就那么多,大家“借鑒來借鑒去”,不可避免存在重復(fù)的內(nèi)容。
比較簡單的去重方式就是直接計(jì)算句子是否重復(fù)出現(xiàn),如果連續(xù)幾句話都一模一樣,重復(fù)的可能性就比較大。說句題外話,“洗稿”基本就把句子重新寫了一遍,直接重復(fù)很少,這也是洗稿不容易被發(fā)現(xiàn)的一個(gè)主要原因。
在去重的同時(shí),也會(huì)識(shí)別色情內(nèi)容、廣告、政治敏感內(nèi)容等。
2. 新聞分類
基于內(nèi)容的推薦,大多數(shù)的時(shí)間都在進(jìn)行內(nèi)容挖掘和分析。
數(shù)據(jù)清洗之后,基本就是一篇篇新聞文本了。但一篇文章動(dòng)輒幾百上千字,文本自身的數(shù)據(jù)量太大,直接計(jì)算相似度還很困難,需要通過數(shù)據(jù)挖掘,計(jì)算文本的特征,之后再利用特征計(jì)算相似度。
最常見的特征是關(guān)鍵詞,我們可以用關(guān)鍵詞表示一篇文章,就像我們?cè)u(píng)價(jià)一個(gè)不是特別熟悉的人一樣,使用“標(biāo)簽”來表示我們對(duì)他的看法。
常用的關(guān)鍵詞獲取技術(shù)是上一章《搜索引擎》所講的TF-IDF(Term Frequency–Inverse Document Frequency)模型,通過分詞、去除關(guān)鍵詞、計(jì)算每個(gè)詞出現(xiàn)的頻率獲得TF;計(jì)算關(guān)鍵詞在所有新聞中出現(xiàn)的頻率,計(jì)算IDF,之后按照TF-IDF模型,計(jì)算關(guān)鍵詞特征。
這里為了方便展示,沒有計(jì)算TF-IDF具體數(shù)值。
比如:這篇新聞(2019年3月7日《人民日?qǐng)?bào)》),原文有上千字,我們使用TF-IDF模型,去掉停用詞和常用詞,提取關(guān)鍵詞。通過計(jì)算, “國產(chǎn)”“科幻電影”“流浪地球”等直接體現(xiàn)本文內(nèi)容詞語就是本文的關(guān)鍵詞。
按照同樣的方法,另一篇類似的文章(2019年2月14日《中國經(jīng)濟(jì)網(wǎng)》),我們可以提取其中的關(guān)鍵詞,“好萊塢”“科幻電影”“現(xiàn)實(shí)”等。
為了便于對(duì)比,我還找了另一篇文章來自微軟亞洲研究院的文章(2018年11月6日),關(guān)鍵詞是 “推薦系統(tǒng)”“收入”等。
我們用關(guān)鍵詞表示這幾篇新聞,使用新聞1代指第一篇新聞,其他類似:
新聞1={“中國”,“科幻電影”,“流浪地球”,“人類”}
新聞2={“好萊塢”,“科幻電影”,“人類”}
新聞3={“推薦系統(tǒng)”,“收入”}
這樣,一篇幾千字的新聞,就被我們壓縮成了幾個(gè)關(guān)鍵詞,當(dāng)然,實(shí)際的情況沒有這么簡單,一篇新聞可能有數(shù)十個(gè)關(guān)鍵詞。
這里還不能明顯看出什么區(qū)別,當(dāng)我們把這三篇文章的關(guān)鍵詞放在一起,就很容易發(fā)現(xiàn)文章之間的相似程度。
因?yàn)橛邢嗤年P(guān)鍵詞,相較新聞3,新聞1和新聞2明顯比較類似,可以把新聞1和新聞2歸為一類,新聞3單獨(dú)一類。
3. 余弦相似度
通過數(shù)據(jù)TF-IDF模型,我們已經(jīng)獲得了關(guān)鍵詞,并發(fā)現(xiàn)可以根據(jù)關(guān)鍵詞的不同,判斷新聞內(nèi)容的相似性。
那么,我們?nèi)绾瘟炕@種類似關(guān)系呢?
最簡單的方式是余弦相似度,通過計(jì)算兩個(gè)向量的夾角余弦值來評(píng)估他們的相似度。
如圖所示,我們使用向量夾角的大小,來判斷兩個(gè)向量的相似程度,夾角越小,兩個(gè)向量越類似;夾角越大,兩個(gè)向量越不同。左邊的夾角就要小于右邊,我們可以認(rèn)為,左邊的兩個(gè)向量更加類似。
在二維空間中,我們使用a、b表示兩個(gè)向量,a和b的坐標(biāo)分別是(x1,y1),(x2,y2),向量a和向量b的余弦計(jì)算公式如下:
余弦的這種計(jì)算方法對(duì)多維向量也成立,這里我們假設(shè)總共有n維向量。
利用余弦相似度,我們可以計(jì)算關(guān)鍵詞之間的相似程度。
我們把每一個(gè)新聞當(dāng)做向量,每一個(gè)關(guān)鍵詞作為一個(gè)維度(可以理解為一個(gè)坐標(biāo)軸,如果有兩個(gè)關(guān)鍵詞,就是二維向量;如果有三個(gè)關(guān)鍵詞,就是三維向量,依此類推)。
這樣,每篇新聞都用關(guān)鍵詞表示,每個(gè)關(guān)鍵詞都有一個(gè)TF-IDF值。
下表是一個(gè)簡單的TF-IDF表格,不同新聞?dòng)胁煌年P(guān)鍵詞,以及對(duì)應(yīng)TF-IDF值。
之后,按照多維向量的計(jì)算公式,我們可以計(jì)算所有新聞兩兩之間的相似程度。
- 如果向量夾角為0度,余弦相似度為1,此時(shí)兩個(gè)向量應(yīng)該是最相似的。這表明,兩篇新聞內(nèi)容非常相似,當(dāng)然,也有可能是重復(fù)的文章。
- 如果夾角為90度,此時(shí)余弦相似度為0。這表明,兩篇新聞的關(guān)鍵詞都不一樣,內(nèi)容完全是無關(guān)的。
- 余弦相似度在0~1之間,說明兩篇新聞具有一定的相關(guān)性。
通過計(jì)算余弦相似度,我們可以發(fā)現(xiàn):新聞1和新聞2的余弦相似度較大,說明兩個(gè)新聞很類似;而新聞1、新聞2和新聞3之間的余弦相似度接近0,說明新聞1、新聞2與新聞3基本沒有關(guān)系。
需要注意的是:在實(shí)際計(jì)算中,一篇文章的關(guān)鍵詞可能有幾十甚至上百個(gè),所有文章組成的關(guān)鍵詞可能就是幾萬個(gè)了。用關(guān)鍵詞代表文章,相當(dāng)于大小數(shù)萬的矩陣相乘,計(jì)算量會(huì)很大,即使是最快的服務(wù)器,計(jì)算所有的新聞之間的相似程度,也要好幾天。
在實(shí)踐上,會(huì)有很多優(yōu)化的空間,比如:代表文章的向量中有很多0不需要計(jì)算,這樣可以把計(jì)算復(fù)雜度降低幾十上百倍。也可以利用數(shù)學(xué)模型,進(jìn)行矩陣分解,加速計(jì)算。
4. 基于內(nèi)容推薦的特點(diǎn)
首先,基于內(nèi)容的推薦實(shí)現(xiàn)起來比較簡單。相較其他推薦系統(tǒng),不需要復(fù)雜的算法和計(jì)算,因此在新聞、電影、音樂、視頻等推薦中有廣泛的應(yīng)用。
第二,如果只計(jì)算標(biāo)題的相關(guān)性,就可以實(shí)時(shí)計(jì)算。這在電商的商品推薦,非常有吸引力。試想一下,根據(jù)用戶的瀏覽行為,實(shí)時(shí)更新“猜你喜歡”,對(duì)用戶來說,是非常貼心的了,隨之而來是較高的轉(zhuǎn)化率。
第三,基于內(nèi)容的推薦可以解決冷啟動(dòng)的問題。在最開始做推薦的時(shí)候,往往沒有大量且有效的用戶行為數(shù)據(jù)的,無法實(shí)現(xiàn)協(xié)同過濾等更加高級(jí)的推薦方式,只能利用商品本身的數(shù)據(jù)做內(nèi)容推薦。更多關(guān)于冷啟動(dòng)的內(nèi)容,會(huì)在后面介紹。
需要注意的是:在特定場景中,基于內(nèi)容的推薦也存在很多問題。
比如:電商推薦會(huì)根據(jù)用戶購買記錄,推薦一些同款或者類似的產(chǎn)品。對(duì)于那些手機(jī)、單反相機(jī)等低頻購買行為,重復(fù)購買率很低,最好的展位就這樣被浪費(fèi)掉了,機(jī)會(huì)成本非常大,這就需要更多的算法優(yōu)化來改進(jìn)基于內(nèi)容的推薦,比如用戶可以手動(dòng)過濾一些不想看到的內(nèi)容等。
三、協(xié)同過濾(Collaborative Filtering,CF)
1. 什么是協(xié)同過濾
如果你想看個(gè)電影,但不知道看哪部,你會(huì)怎么做?
可能直接找個(gè)熱門的電影,這是基于熱度的大眾推薦;可能會(huì)找科幻、愛情類型的電影觀看,這是基于內(nèi)容的推薦;還可能問問周圍的人,看有沒有什么好看的電影推薦,周圍有朋友、同事甚至父母,但我們一般不會(huì)找父母推薦,而是找朋友推薦,因?yàn)槲覀兿矚g的電影很可能是類似的,這也是協(xié)同過濾的核心思想。
前面講的基于內(nèi)容的推薦,只利用了內(nèi)容之間的相似性,在冷啟動(dòng)或者用戶數(shù)據(jù)較少的情況下,可以使用。有了用戶(User)數(shù)據(jù),比如點(diǎn)擊、購買、播放、瀏覽等操作,就可以投其所好,推薦用戶感興趣的文章、音樂、電影或商品,統(tǒng)稱為物品(Item)。這就是協(xié)同過濾。
按照計(jì)算相似度采用的標(biāo)準(zhǔn)不同,協(xié)同過濾主要分為:基于用戶的協(xié)同過濾(User-based Collaborative Filtering,User-based CF)和基于物品的協(xié)同過濾(Item-based Collaborative Filtering,Item-based CF)。
基于用戶的協(xié)同過濾通過計(jì)算用戶之間相似度進(jìn)行推薦,基于物品的協(xié)同過濾通過計(jì)算基于物品之間相關(guān)度進(jìn)行推薦,這有些拗口,具體的內(nèi)容會(huì)在后文介紹。
2. 數(shù)據(jù)獲取
由上面的分析,我們可以發(fā)現(xiàn):無論是用戶的相似度計(jì)算,還是物品之間的相關(guān)性的計(jì)算,前提都是要有大量的數(shù)據(jù)。
那么,如何收集數(shù)據(jù)呢?
“當(dāng)你在看風(fēng)景時(shí),你已成為別人眼中的人風(fēng)景”,當(dāng)你刷新聞APP的時(shí)候,后臺(tái)也在默默記錄你的點(diǎn)擊的新聞、觀看時(shí)長、點(diǎn)贊、評(píng)論等信息。
比如:新聞APP可能會(huì)記錄,用戶小明,早上8點(diǎn)半打開了APP,此時(shí)使用4G網(wǎng)絡(luò),同時(shí)GPS定位在持續(xù)快速移動(dòng),他先瀏覽了首頁的推薦新聞,點(diǎn)擊了20條,點(diǎn)贊了5條,單個(gè)新聞停留最長時(shí)間為3分鐘,之后打開了“財(cái)經(jīng)”板塊,發(fā)表了3條評(píng)論,快到9點(diǎn)的時(shí)候,小明關(guān)閉了APP。
同樣的,當(dāng)你逛電商APP的時(shí)候,后臺(tái)也會(huì)默默記錄你點(diǎn)擊、瀏覽、看評(píng)論、加入購物車、購買等行為。
比如,電商可能會(huì)記錄,用戶小紅,晚上10點(diǎn)用iPhone打開了APP,此時(shí)使用WIFI,GPS定位穩(wěn)定,她先瀏覽了首頁的個(gè)性推薦,點(diǎn)擊了幾個(gè)熱銷的女裝,之后在搜索框輸入了口紅,在瀏覽了18支口紅之后,她點(diǎn)擊進(jìn)入了購物車,把2天前加入購物車的高跟鞋結(jié)算了,使用花唄支付,晚上11點(diǎn),小紅關(guān)閉了APP。
數(shù)據(jù)獲取有幾個(gè)需要注意的問題。
首先,是數(shù)據(jù)量的問題。針對(duì)每一個(gè)用戶,需要記錄幾乎所有的操作,無論是隱性還是顯性操作,偏好還是厭惡行為,都要把這些行為數(shù)據(jù)上傳到服務(wù)器。如果一個(gè)APP有幾億的用戶,同一時(shí)刻可能有上百萬的在線瀏覽量,數(shù)據(jù)量之大可想而知,遇到雙十一、春晚等高流量場景,服務(wù)器可能一下子就宕機(jī)了。
其次,如何確定用戶身份的問題。一個(gè)用戶可能有多個(gè)手機(jī);可能使用微信、QQ、手機(jī)號(hào)、郵箱、微博、淘寶等不用方式登錄;可能使用手機(jī)APP,也可能使用電腦瀏覽器。同一個(gè)用戶不同終端、賬號(hào)的信息要同步,這樣才能準(zhǔn)確地計(jì)算用戶特征。APP通常會(huì)鼓勵(lì)用戶同時(shí)綁定微博、微信、手機(jī)等賬戶,很大程度上也是為了確定用戶的身份。
第三,數(shù)據(jù)的進(jìn)一步清洗。比如因?yàn)榫W(wǎng)絡(luò)中斷,用戶在短時(shí)間內(nèi)產(chǎn)生了大量點(diǎn)擊的操作,或者手機(jī)閃退,造成的信息丟失。這都需要針對(duì)每一個(gè)情況,具體分析,甚至需要針對(duì)每一種情況單獨(dú)寫代碼應(yīng)對(duì),工作量之大,可想而知。
第四,還有難以避免的隱私問題。記錄GPS、上傳通訊錄、訪問內(nèi)容等算是APP的常規(guī)操作,不斷有APP被曝出偷偷錄音、拍照等行為,某互聯(lián)網(wǎng)大佬,在論壇上演講直接說出,“多數(shù)情況下,中國人愿意用隱私交換便捷性”, 引起輿論嘩然。隱私問題,無法僅僅依靠技術(shù)來解決。
3. 基于用戶的協(xié)同過濾(User-Based CF)
基于用戶的協(xié)同過濾,通過用戶對(duì)不同物品的偏好,計(jì)算用戶之間的相似度,之后基于用戶的相似度進(jìn)行推薦,本質(zhì)上就是將類似的用戶偏好的物品推薦給當(dāng)前用戶。
亞馬遜的 “瀏覽詞商品的顧客也同時(shí)瀏覽”就是User-based協(xié)同過濾的典范。比如:在亞馬遜上搜索《統(tǒng)計(jì)學(xué)習(xí)方法》這本書,系統(tǒng)會(huì)推薦瀏覽《統(tǒng)計(jì)學(xué)習(xí)方法》這本書的人,也同時(shí)瀏覽《機(jī)器學(xué)習(xí)》《深度學(xué)習(xí)》等書。
基于用戶的協(xié)同過濾計(jì)算分兩步:第一步,根據(jù)用戶行為,計(jì)算用戶的相似程度;第二步,把與當(dāng)前用戶類似的用戶喜歡的物品推薦給當(dāng)前用戶,這句話同樣拗口,可以參考下圖。
計(jì)算用戶的相似度,與前文計(jì)算內(nèi)容之間相似度的方法基本一樣,最常使用的是余弦相似度,通過計(jì)算用戶之間的余弦距離,判斷用戶相似程度。
比如下表,代表不同用戶對(duì)不同物品的喜好程度。
首先,計(jì)算用戶的相似度。用戶A、用戶C都喜歡商品1、商品3,但與用戶B基本沒有什么交集,所以,用戶A和用戶C比較相似。
之后,我們可以把相似用戶喜歡的物品互相推薦給對(duì)方。比如:用戶C喜歡物品4,而用戶A沒有買過,我們就把物品4推薦給用戶A,實(shí)現(xiàn)了推薦的過程。
這里需要注意的是:我們沒有必要根據(jù)用戶C喜歡物品3,就把物品3也推薦給用戶A ,因?yàn)槲锲?已經(jīng)是用戶A喜歡的,這里沒有必要重復(fù)推薦。
4. 基于物品的協(xié)同過濾(Item-Based CF)
基于物品的協(xié)同過濾,通過分析用戶的記錄,計(jì)算物品之間的相關(guān)性,推薦與當(dāng)前物品類似的物品。
基于物品的協(xié)同過濾有個(gè)經(jīng)典的案例:超市巨頭沃爾瑪發(fā)現(xiàn)購買啤酒的人同時(shí)也會(huì)購買紙尿布,于是,就把啤酒和紙尿布放在一個(gè)貨架上,在這里,啤酒和紙尿布具有很大的相關(guān)性。
基于內(nèi)容的推薦(Content-Based Recommendation)、基于物品的協(xié)同過濾(Item-Based Collaborative Filtering),兩者有些類似,都需要計(jì)算物品之間的關(guān)系,但兩者也有很大的不同。
基于內(nèi)容的推薦,本質(zhì)是計(jì)算內(nèi)容本身的相似度。其中最大的問題是:我們無法通過用戶喜歡的音樂,給他推薦類似的電影;用戶購買了電視,我們無法給用戶推薦空調(diào)。
基于物品的協(xié)同過濾,本質(zhì)上是通過用戶行為,計(jì)算相關(guān)性。不需要計(jì)算音樂和電影的相似程度,喜歡某首歌的人,也喜歡看某部電影,我們就說這首歌和這部電影有相關(guān)性;用戶購買電視的時(shí)候,很多時(shí)候也會(huì)順便購買空調(diào),我們就判斷電視和空調(diào)具有相關(guān)性。
基于物品的協(xié)同過濾,同樣有兩個(gè)步驟:第一步,根據(jù)用戶行為,計(jì)算物品的相關(guān)度;第二步,根據(jù)用戶的偏好,推薦相關(guān)的物品給他。
相似度的計(jì)算是都是類似的,通常情況下直接計(jì)算余弦距離就可以了。這里著重講一下推薦的過程。
如下表所示:物品1同時(shí)受到用戶A、用戶B、用戶C喜歡,物品3同時(shí)受到用戶A、用戶B喜歡,而物品2只有用戶B喜歡,我們可以發(fā)現(xiàn)物品1和物品3有某種相似性或者相關(guān)性。我們就可以把物品3推薦給用戶C,這里同樣要避免重復(fù)推薦。
User-Based CF 和Item-Based CF是協(xié)同過濾的兩個(gè)最基本的算法,有各自的適用場景。User-Based CF計(jì)算用戶之間的相似度,適用于用戶較少的場景,Item-Based CF計(jì)算物品之間的相似度,適用于產(chǎn)品較少的場景。
User-Based CF很早以前就提出來了,Item-Based CF是從 Amazon 的論文和專利發(fā)表之后(2001 年左右)開始流行,其中的一個(gè)主要原因是亞馬遜提供很多都是自營服務(wù),商品數(shù)量有限,商品的數(shù)據(jù)也比較穩(wěn)定,計(jì)算起來比較方便。相比之下,用戶的數(shù)據(jù)就很多,而且分散,計(jì)算速度比較慢。
但對(duì)于新聞、影視等內(nèi)容推薦系統(tǒng),或者淘寶等電商平臺(tái),情況正好是相反的,物品的數(shù)量很多,更新頻繁。相比之下,用戶數(shù)量就相對(duì)較少并且比較穩(wěn)定了。在這種情況下,就比較適合User CF推薦系統(tǒng)。
5. 協(xié)同過濾的特點(diǎn)
協(xié)同過濾的優(yōu)勢顯而易見。
首先,在于充分利用了現(xiàn)有的數(shù)據(jù),從而可以挖掘出更多的信息。比如:前面所說的紙尿布和啤酒的相關(guān)性,使用基于內(nèi)容的推薦無論如何也是計(jì)算不出來的。
其次,協(xié)同過濾可以更加直觀地展示推薦理由。讓人信服的理由,總能激發(fā)人們的點(diǎn)擊和購買的欲望。比如:亞馬遜在推薦頁面顯示“瀏覽此商品的顧客也同時(shí)瀏覽”就比較有說服力,用戶購買的可能性就比較大。使用基于內(nèi)容的推薦或者更高級(jí)的基于數(shù)學(xué)模型的推薦算法,往往不能簡潔清楚地說明推薦理由,總不能顯示“根據(jù)計(jì)算新聞之間的相似度,這篇新聞和某篇新聞比較相似,推薦給你”。
但,協(xié)同過濾也存在一些問題。
首先,是數(shù)據(jù)的問題。在用戶冷啟動(dòng)或者產(chǎn)品上新時(shí),因?yàn)闆]有數(shù)據(jù),協(xié)同過濾就無法實(shí)現(xiàn)推薦。與此同時(shí),大量的數(shù)據(jù)隨著而來的是較大的計(jì)算量,在一些實(shí)時(shí)推薦系統(tǒng)中,應(yīng)用受到一定限制。
第二,是用戶喜好的變化。不少追星族可能會(huì)三天兩頭換一個(gè)明星追,在推薦領(lǐng)域,也存在類似的問題。協(xié)同過濾通過歷史數(shù)據(jù)計(jì)算用戶的愛好、用戶之間的類似程度,這就存在一個(gè)基本假設(shè):用戶會(huì)喜歡和他以前喜歡的相似的東西,但用戶的愛好會(huì)隨著時(shí)間、新產(chǎn)品的出現(xiàn)、營銷等發(fā)生改變。
甚至在某種程度上,推薦系統(tǒng)本身就在有意無意地影響用戶的喜好,典型的社交電商會(huì)通過各種方式“種草”新的流行產(chǎn)品。
6. 50行代碼實(shí)現(xiàn)Item-Based協(xié)同過濾
import pandas as pd
import numpy as np
#?原始數(shù)據(jù)
data = {‘張三’: {‘小時(shí)代’: 2.5, ‘大圣歸來’: 3.5, ‘無雙’: 2.5},
‘李四’: {‘小時(shí)代’: 3.0, ‘我不是藥神’: 3.5,’致青春’: 1.5, ‘霸王別姬’: 3.0},
‘王五’: {‘小時(shí)代’: 2.5,? ‘大圣歸來’: 3.5, ‘霸王別姬’: 4.0},
‘趙六’: {‘我不是藥神’: 3.5, ‘致青春’: 3.0, ‘霸王別姬’: 4.5, ‘無雙’: 2.5},
‘小甲’: {‘致青春’: 2.0,? ‘大圣歸來’: 3.0, ‘無雙’: 2.0},
‘小乙’: {‘我不是藥神’: 4.0, ‘霸王別姬’: 3.0,? ‘無雙’: 3.5},
‘小丙’: {‘我不是藥神’: 4.5, ‘無雙’: 1.0, ‘大圣歸來’: 4.0}}
#讀取數(shù)據(jù),清晰數(shù)據(jù),數(shù)據(jù)歸一化[0,1]
data = pd.DataFrame(data)
data = data.fillna(0)
mdata = data.T
np.set_printoptions(3)
mcors = np.corrcoef(mdata, rowvar=0)
mcors = 0.5 + mcors * 0.5
mcors = pd.DataFrame(mcors, columns=mdata.columns, index=mdata.columns)
#計(jì)算user-item評(píng)分
def cal_score(matrix, mcors, item, user):
totscore = 0;totsims = 0;score = 0
if matrix[item][user] == 0:
for mitem in matrix.columns:
if matrix[mitem][user] == 0:
continue
else:
totscore += matrix[mitem][user] * mcors[item][mitem]
totsims += mcors[item][mitem]
score = totscore / totsims
else:
score = matrix[item][user]
return score
#計(jì)算物品之間的相關(guān)性
def cal_matscore(matrix, mcors):
score_matrix = np.zeros(matrix.shape)
score_matrix = pd.DataFrame(score_matrix, columns=matrix.columns, index=matrix.index)
for mitem in score_matrix.columns:
for muser in score_matrix.index:
score_matrix[mitem][muser] = cal_score(matrix, mcors, mitem, muser)
return score_matrix
#根據(jù)物品相關(guān)性,進(jìn)行推薦
def recommend(matrix, score_matrix, user):
user_ratings = matrix.ix[user]
not_rated_item = user_ratings[user_ratings == 0]
recom_items = {}
#排除用戶已經(jīng)看過的電影
for item in not_rated_item.index:
recom_items[item] = score_matrix[item][user]
recom_items = pd.Series(recom_items)
#推薦結(jié)果排序
recom_items = recom_items.sort_values(ascending=False)
return recom_items[:1]
score_matrix = cal_matscore(mdata, mcors)
user = input(‘請(qǐng)輸入用戶名:’)
recom_items=recommend(mdata, score_matrix, user)
print(recom_items)
如果你的電腦有Python環(huán)境,運(yùn)行這個(gè)程序,按照提示輸入,就可以看到輸出結(jié)果:
你可以對(duì)這些Python語言不太了解、對(duì)編程也不太感興趣,但你不用知道每行代碼用什么用,如何運(yùn)行這些代碼,只需要有個(gè)直觀的印象,直觀了解程序員每天的工作——協(xié)同過濾原來是這么做的呀。
首先獲取User-Item信息,進(jìn)行數(shù)據(jù)處理,計(jì)算用戶或者物品之間的相關(guān)性,最后進(jìn)行推薦就好了。每一個(gè)步驟都可以用一個(gè)代碼模塊寫出來,之后匯總到一起就可以了。
在實(shí)際寫代碼的過程中,也有開源的解決方案可以使用,在開源解決方案的基礎(chǔ)上,可以在較短的時(shí)間內(nèi)、花費(fèi)較短的成本,獲得可靠的解決方案。
當(dāng)然,現(xiàn)實(shí)中的推薦系統(tǒng)沒有這么簡單,應(yīng)用場景不同,使用的算法、系統(tǒng)的配置也不盡相同,程序員要花很多時(shí)間在系統(tǒng)的配置上,這個(gè)我們?cè)谧詈髸?huì)講到。
四、現(xiàn)實(shí)中的推薦系統(tǒng)
1. 如何實(shí)現(xiàn)冷啟動(dòng)
在推薦系統(tǒng)中,數(shù)據(jù)積累量較少,無法給新用戶或者新產(chǎn)品做個(gè)性推薦,這就是冷啟動(dòng)問題。沒有用戶數(shù)據(jù),就沒辦法推薦;沒有更好的推薦,用戶留下的數(shù)據(jù)就很少,這也是一個(gè)先有雞還是先有蛋的問題。
冷啟動(dòng)問題基本可以分為兩類:用戶冷啟動(dòng)和物品冷啟動(dòng)。顧名思義,用戶冷啟動(dòng)指如何給新用戶進(jìn)行個(gè)性化推薦。
物品冷啟動(dòng)指:如何將新的物品推薦給可能對(duì)它感興趣的用戶?
產(chǎn)品經(jīng)理、程序員、創(chuàng)業(yè)者想了很多辦法來解決冷啟動(dòng)問題,最常見的兩種解決辦法。
第一種解決方式是:大眾推薦。
通常20%的產(chǎn)品獲得了80%的關(guān)注和流量,給用戶推薦一些熱門產(chǎn)品,比如:熱搜榜、熱銷榜等,點(diǎn)擊率也不錯(cuò),通過這種方式,可以滿足用戶的基本需求。對(duì)于一些新上架的商品或者新的音樂,也會(huì)有新品榜單獨(dú)推薦,以此解決物品冷啟動(dòng)的問題。
第二種方式是:盡可能獲得更多的信息。
比如:在用戶注冊(cè)時(shí)候,激勵(lì)用戶綁定微博賬號(hào),從微博的數(shù)據(jù)接口,可以發(fā)掘用戶的一些偏好;激勵(lì)用戶選擇一些感興趣的博主或者板塊,可以直接獲得用戶的喜好;利用用戶注冊(cè)時(shí)填寫的年齡、性別、手機(jī)號(hào)碼(歸屬地)甚至教育程度等信息,也可以獲得很多有用的數(shù)據(jù)。
一些APP或者網(wǎng)頁也會(huì)開發(fā)出有趣的測試,獲得用戶的偏好。
2. 位置和時(shí)間約束
地理位置約束:
在很多情況下,地理位置是推薦系統(tǒng)最常見的一個(gè)約束,不少外賣、本地電商等平臺(tái),在排序中也有距離優(yōu)先的選項(xiàng)。比如:我們使用本地電商平臺(tái)找餐廳,通常情況下,我們不會(huì)跑大半個(gè)城市吃飯,所以APP會(huì)推薦較近的餐廳。
那么,如何實(shí)現(xiàn)基于地理位置進(jìn)行個(gè)性推薦呢?
常見的方式是在排序的時(shí)候,對(duì)距離添加一個(gè)權(quán)重,如果距離越近,相應(yīng)的權(quán)重越高,排名越靠前。比如:我們?cè)诤贾莼疖囌舅阉鞑宛^,會(huì)優(yōu)先推薦附近的,這也是搜索引擎和個(gè)性推薦的一個(gè)交集。
為了加快計(jì)算速度,通常會(huì)采用樹狀存儲(chǔ),比如:下面這張圖,可以通過杭州、上城區(qū)、火車站,快速找到火車站范圍內(nèi)的餐館。
時(shí)間約束:
在協(xié)同過濾中,我們講到,用戶的喜好可能會(huì)隨著時(shí)間發(fā)生改變,比如:電商產(chǎn)品在賣衣服時(shí),冬天推薦的衣物和夏天推薦的衣物是不同的;上班時(shí)候上看的新聞跟下班看的也可能不一樣。這就要求我們?cè)谶M(jìn)行推薦的時(shí)候,把時(shí)間這個(gè)因素考慮進(jìn)去。
最常用的處理方式,是在推薦中添加跟時(shí)間相關(guān)的權(quán)重。比如:用戶一個(gè)月前加入購物車跟今天加入購物車的行為應(yīng)該有不同的權(quán)重,今天的行為權(quán)重更高,在個(gè)性推薦時(shí),應(yīng)更多地根據(jù)今天的行為進(jìn)行推薦,這也是電商APP實(shí)時(shí)更新推薦商品的重要方式。
實(shí)時(shí)熱榜,也是利用時(shí)間約束的一個(gè)范例,用戶可以關(guān)注時(shí)下最流行的新聞、衣服、電影等,閱讀時(shí)長、購買轉(zhuǎn)化率等都會(huì)有很大的提高。比如:微博的Slogan就是“隨時(shí)隨地,發(fā)現(xiàn)新鮮事”,把熱點(diǎn)利用到了極致。
3. 推薦系統(tǒng)架構(gòu)
融合:
在實(shí)際使用中,單獨(dú)使用一種推薦系統(tǒng)無法解決所有的問題,推薦系統(tǒng)需要將用戶的行為、物品的特征、時(shí)間和地理?xiàng)l件等考慮進(jìn)去。通常情況下,推薦系統(tǒng)會(huì)同時(shí)使用基于內(nèi)容的推薦、協(xié)同過濾、基于時(shí)間的推薦等作為推薦引擎,之后,對(duì)這些推薦結(jié)果進(jìn)行按照一定權(quán)值進(jìn)行合并。
這樣的好處非常明顯,每一個(gè)推薦引擎都實(shí)現(xiàn)了特定的目的,相當(dāng)于解耦合,降低了系統(tǒng)的復(fù)雜度,我們可以單獨(dú)調(diào)整某個(gè)模塊進(jìn)行優(yōu)化。
需要注意的是:推薦引擎也會(huì)添加一些大眾推薦或者隨機(jī)推薦,以增加系統(tǒng)的多樣性,給用戶帶來新鮮感。同時(shí),在某種程度上也可以避免“信息繭房”的道德指責(zé)。比如推薦音樂,如果完全按照用戶的習(xí)慣進(jìn)行推薦,結(jié)果往往就局限在一個(gè)很小的范圍——聽民謠的人,可能永遠(yuǎn)不會(huì)被推薦搖滾,這就需要加入大眾推薦或者隨機(jī)推薦,適當(dāng)拓展推薦的內(nèi)容。
過濾:
過濾是對(duì)初始的推薦結(jié)果進(jìn)行處理,這里主要有兩個(gè)方面的過濾。
一方面,為了針對(duì)實(shí)際需求,對(duì)推薦結(jié)果進(jìn)行篩選。
最常見的是過濾熱門的物品,比如:TFBOYS新出了一首歌,成為爆款,很多年輕人都聽過,再把這首歌推薦給用戶可能就沒有什么意義。
除此之外,還需要過濾用戶已經(jīng)看過的新聞、電影、購買過的商品,比如:我們已經(jīng)買了一款手機(jī),電商APP還在一直推薦,我們就會(huì)覺得這個(gè)APP很傻。針對(duì)一些質(zhì)量差、評(píng)價(jià)低的商品,也可以有選擇的過濾,比如電商APP會(huì)折疊一些低質(zhì)低價(jià)的商品。
另一方面,是合規(guī)的需求。
無論是什么產(chǎn)品,都要合法合規(guī),今日頭條等不少內(nèi)容平臺(tái),也加大力度,對(duì)熱搜、推薦進(jìn)行審查。
比如:今日頭條成立早期,官媒就連發(fā)評(píng)論,批評(píng)其讓用戶困在信息繭房,低俗內(nèi)容污染網(wǎng)絡(luò)生態(tài),字節(jié)跳動(dòng)旗下內(nèi)涵段子就被廣電總局永久關(guān)停。為此,今日頭條張一鳴公開道歉,聲稱要傳播正能量,符合時(shí)代要求,尊重公序良俗。
4. 現(xiàn)實(shí)中的推薦系統(tǒng)
個(gè)性推薦系統(tǒng)可以提高用戶體驗(yàn),增加用戶使用時(shí)長,提高銷量,但在實(shí)踐上,根據(jù)應(yīng)用場景和數(shù)據(jù)規(guī)模的不同,系統(tǒng)的差異也非常大。
對(duì)小型的網(wǎng)頁或者APP而言,由于成本、內(nèi)容數(shù)量、技術(shù)的限制,很可能是不進(jìn)行個(gè)性推薦的,運(yùn)營人員直接編輯推薦或者通過熱度進(jìn)行大眾推薦,可以滿足一般的使用。
對(duì)于稍大些的網(wǎng)頁或者APP,可能在單個(gè)或較少的服務(wù)器上就可以搭建出推薦系統(tǒng),每天進(jìn)行離線特征提取、模型訓(xùn)練,訓(xùn)練完成之后,再上線運(yùn)行。對(duì)于這類需求而言,有成熟的開源推薦系統(tǒng)可以使用,比如Spark的機(jī)器學(xué)習(xí)(Machine Learning,ML)模塊可以直接使用。
離線數(shù)據(jù)處理,對(duì)一段時(shí)間(比如一天)的數(shù)據(jù)進(jìn)行集中計(jì)算,對(duì)于用戶今天的操作,可能第二天才會(huì)更新模型,并進(jìn)行個(gè)性推薦。離線數(shù)據(jù)處理實(shí)現(xiàn)起來比較簡單,但速度慢是硬傷。與離線數(shù)據(jù)處理對(duì)應(yīng)的是在線處理,兩者最大的差別是數(shù)據(jù)處理是不是實(shí)時(shí)的。
比如:我們點(diǎn)擊商品之后,個(gè)性推薦就會(huì)實(shí)時(shí)更新,這個(gè)是根據(jù)用戶的數(shù)據(jù),實(shí)時(shí)進(jìn)行處理。在線數(shù)據(jù)處理要求實(shí)時(shí)記錄用戶行為、上傳到服務(wù)器、進(jìn)行推薦、之后再反饋給用戶,完成整個(gè)過程可能只有50ms的時(shí)間,眨眼的時(shí)間200ms,真真一眨眼的功夫就計(jì)算好了。
對(duì)于大型的信息或者電商平臺(tái),可能有百萬的用戶同時(shí)在線,數(shù)據(jù)量也急劇上升,通常采用實(shí)時(shí)數(shù)據(jù)處理和離線數(shù)據(jù)處理相結(jié)合的方式。
由前面章節(jié)的介紹,我們知道:當(dāng)用戶數(shù)據(jù)量增加十倍,系統(tǒng)的復(fù)雜度可能不是十倍增加,而是上百倍的增加,甚至直接演變成了另外一個(gè)系統(tǒng)。
復(fù)雜系統(tǒng)的每一個(gè)環(huán)節(jié)都有可能成為系統(tǒng)的短板,進(jìn)而拉低整個(gè)系統(tǒng)的運(yùn)行效率,所以就需要對(duì)整個(gè)系統(tǒng)進(jìn)行重新開發(fā)。大多數(shù)時(shí)候也不是簡單的推倒再來,而是在現(xiàn)有基礎(chǔ)上進(jìn)行的修改,這就像在老城區(qū)開發(fā)一樣,既要維持現(xiàn)有的秩序,又要滿足不斷增長的流量需求。
對(duì)于大數(shù)據(jù)離線處理而言,單個(gè)服務(wù)器的數(shù)據(jù)存儲(chǔ)容量、處理速度有限,通常使用幾十甚至上百個(gè)服務(wù)器同時(shí)進(jìn)行數(shù)據(jù)存儲(chǔ)和計(jì)算,如同上百人的大公司一樣,人與人之間的交流和分工,要耗費(fèi)大量的時(shí)間和精力。
上百服務(wù)器通常作為一個(gè)集群,使用分布式管理,比如:使用開源的工具Hadoop作為整個(gè)分布式系統(tǒng)的基礎(chǔ)架構(gòu),使用Hive進(jìn)行分布式存儲(chǔ),使用Spark進(jìn)行分布式計(jì)算和數(shù)據(jù)挖掘。
幸運(yùn)的是,這些優(yōu)秀的工具都是開源的,這也是互聯(lián)網(wǎng)發(fā)展速度非??斓闹匾?。相比之下,不少行業(yè)更加封閉,一個(gè)公司老員工、新員工之間的技術(shù)交流尚且不暢,更別說不同公司之間的技術(shù)共享了。
對(duì)實(shí)時(shí)數(shù)據(jù)處理而言,處理速度是最大的追求,通常使用“流”式處理,就像生產(chǎn)工廠的流水線一樣,數(shù)據(jù)實(shí)時(shí)從用戶傳到服務(wù)器集群,服務(wù)器對(duì)接收的數(shù)據(jù)處理、更新模型、保存結(jié)果,客戶端實(shí)時(shí)獲取這些更新。
大規(guī)模的數(shù)據(jù)處理,特別是實(shí)時(shí)處理,要花不少時(shí)間在系統(tǒng)的架構(gòu)、調(diào)試上,還要時(shí)不時(shí)面對(duì)流量過高的宕機(jī)風(fēng)險(xiǎn),這種情況下進(jìn)行個(gè)性推薦,有時(shí)候,難度可能不在推薦算法本身。
本文由@linghu 原創(chuàng)發(fā)布于人人都是產(chǎn)品經(jīng)理,未經(jīng)許可,禁止轉(zhuǎn)載
題圖來自Unsplash, 基于CC0協(xié)議
請(qǐng)問 {‘小時(shí)代‘: 2.5, ‘大圣歸來‘: 3.5, ‘無雙‘: 2.5},這里面的2.5,3.5是怎么計(jì)算出來的呢?
“常用的關(guān)鍵詞獲取技術(shù)是上一章《搜索引擎》所講的TF-IDF(Term Frequency–Inverse Document Frequency)模型,通過分詞、去除關(guān)鍵詞、計(jì)算每個(gè)詞出現(xiàn)的頻率獲得TF” —–>應(yīng)該是通過分詞、去除停用詞/功能詞、計(jì)算每個(gè)關(guān)鍵詞吧
干貨,正在學(xué)習(xí)中!
滿屏都是干貨
受益匪淺,請(qǐng)問在推薦系統(tǒng)這方面,有什么書或者課程可以學(xué)習(xí)嗎,先謝謝啦?
2012年有本《推薦系統(tǒng)實(shí)踐》,不過都是比較傳統(tǒng)的推薦方式了,現(xiàn)在很多都轉(zhuǎn)深度學(xué)習(xí)了,相關(guān)的書籍和課程還比較少。
好的,謝謝~
難的干貨
真是一篇好文章