新聞推薦系統:基於內容的推薦演算法——TFIDF、衰減機制(github java程式碼)
轉自:
因為開發了一個新聞推薦系統的模組,在推薦演算法這一塊涉及到了基於內容的推薦演算法(Content-Based Recommendation),於是藉此機會,基於自己看了網上各種資料後對該分類方法的理解,用盡量清晰明瞭的語言,結合演算法和自己開發推薦模組本身,記錄下這些過程,供自己回顧,也供大家參考~
目錄
一、基於內容的推薦演算法 + TFIDF
二、在推薦系統中的具體實現技巧
正文
一、基於內容的推薦演算法 + TFIDF
主流推薦演算法大致可分為:
基於內容(相似度)的推薦
基於使用者/物品相似度的協同過濾
熱點新聞推薦(你看到的那些頭條新聞)
基於模型的推薦(通過輸入一些使用者特徵進入模型,產生推薦結果)
混合推薦(以上十八般兵器一起耍!)
(本文只詳述基於內容的推薦,其它的推薦方法大家可以另行搜尋。)
概念
基於內容相似度的推薦:顧名思義,把與你喜歡看的新聞內容相似新聞推薦給你。基於內容的推薦演算法的主要優勢在於無冷啟動問題,只要使用者產生了初始的歷史資料,就可以開始進行推薦的計算。而且隨著使用者的瀏覽記錄資料的增加,這種推薦一般也會越來越準確。
這裡有兩個重要的關鍵點需要首先有個基本理解:
怎麼知道使用者喜歡看那些新聞;
使用者有歷史的瀏覽記錄,我們可以從這些使用者歷史瀏覽的新聞中”提取”能代表新聞主要內容的關鍵詞,看哪些關鍵詞出現的最多。比如可以有”手機“,”電腦遊戲“,”釋出會“等等關鍵詞。
或者,統計這些新聞所屬的領域是哪些,比如國際政治、社會、民生、娛樂,找出使用者看的新聞來源最多的幾個領域。不過按這種方式判斷使用者興趣容易太寬泛,哪怕是同一個領域下的新聞,可能也會差異很大。比如某使用者可能喜歡A女星,而不喜歡B女星,而如果你只是認為該使用者喜歡娛樂新聞,結果把B女星的新聞不停給使用者推,那就肯定不好。而上述的關鍵詞就可以比較好地規避這個問題。
怎麼判斷兩個新聞內容相似;
找到定義使用者喜好的方法——關鍵詞,那麼我們自然而然就可以想到,能不能提取出兩個新聞的關鍵詞,然後對比看它們兩的關鍵詞是不是相同的呢?恩!思路正確,不過畢竟一個新聞可以有好幾個關鍵詞,要想全部一樣,還是比較困難的。所以我們需要對兩個新聞的關鍵詞匹配程度做一個合理的量化。
那麼這時就要說到TFIDF演算法了。
給大家一個連結去看TFIDF演算法的具體原理,而此處只是簡單地解釋:TFIDF演算法可以能夠返回給我們一組屬於某篇文字的”關鍵詞-TFIDF值”的詞數對,這些關鍵詞最好地代表了這篇文字的核心內容,而這些關鍵詞的相對於本篇文章的關鍵程度由它的TFIDF值量化。
好了,那我們現在也有了提取關鍵詞並量化關鍵程度的方法,那麼我們現在就可以來對比兩篇文字的相似程度了。公式如下:
-
m是兩篇文章重合關鍵詞的集合。此即將兩篇文字的共同關鍵詞的TFIDF的積全部加在一起,獲得最終代表兩篇文字的相似度的值。舉例: 剛抓進系統的兩個新聞,分別提取出關鍵詞與TFIDF值如下: A新聞:“美女模特”:100,“女裝”:80,“賓士”:40 B新聞:“程式設計師”:100,“女裝”:90,“程式設計”:30 兩篇文章只有一個共同關鍵詞“女裝”,故相似度為:80*90=7200。
- 1
- 2
- 3
- 4
- 5
- 6
使用者喜好衡量:喜好關鍵詞表
但是實際操作中,以上思路有一個問題了,使用者以前看了辣麼多新聞,每個新聞有好些個關鍵詞,我們難道拿剛抓進系統的新聞跟它們一個個比對嗎?
為了解決這個問題,我們需要引入新的東西:喜好關鍵詞表。
其實很好理解:我們為每個使用者在資料庫裡維持一個map,這個map裡放的都是“使用者喜好的關鍵詞-喜好程度”這樣的Key-Value對。而這個map最開始當然是空的,而從任意時刻開始,我們可以開始跟蹤某使用者的瀏覽行為,每當該使用者新瀏覽了一條新聞,我們就把該新聞的“關鍵詞-TFIDF值”“插入”到該使用者的喜好關鍵詞表中。當然這個“插入”要考慮關鍵詞表裡已經預先有了某預插入的關鍵詞的情況,那麼在這個基礎上,我們可以將預插入的關鍵詞的TFIDF值直接和詞表裡的值加起來。
當然,考慮到儲存問題,我們可以為使用者的喜好關鍵詞表設定一個容量上限,比如最多1000個詞,當然具體數值還是需要在實際執行過程根據效果做調整。
興趣遷移——衰減機制
最後一個問題。
我們大家會不會想到,我們的興趣點可能是會隨時間改變的呢?比如這段時間蘋果出了一款新產品,我關注一下,但一個月後,我可能就完全不在意這件事了,但是可能蘋果相關的關鍵詞還一直在我的關鍵詞表裡,那會不會導致我依然收到相似的我已經不關心的新聞的推薦呢?也就是如何處理這種興趣遷移問題呢?
為了解決這個問題,我們可以引入一個衰減機制,即讓使用者的關鍵詞表中的每個關鍵詞喜好程度都按一定週期保持衰減。考慮到不同詞的TFIDF值可能差異已經在不同的數量級,我們考慮用指數衰減的形式來相對進行公平的衰減。即引入一個λ
係數,1>λ>0,我們每隔一段時間,對所有使用者的所有關鍵詞喜好程度進行*λ的衰減,那麼就完成了模擬使用者興趣遷移的過程。
當然,一直衰減下去,也會使得一些本來就已經完全不感興趣的關鍵詞可能衰減到了0.0000001了,還在衰減,還死皮賴臉地待在詞表裡佔位置,那麼自然而然,我們可以設定一個閾值L,規定對每個使用者的每次衰減更新完成後,將詞表裡喜好值小於L的關鍵詞直接清除。
在推薦系統中的具體實現技巧
自己實現的推薦系統,包括了協同過濾、基於內容的推薦和基於熱點新聞的推薦,放在Github上了,歡迎拍磚!
這裡TFIDF值的提取我用的是ANSJ,有直接的TFIDF庫函式,直接呼叫就行,都不用自己分詞。
而在資料庫裡儲存與讀取使用者的關鍵詞表時,我用的是Json形式,相關的工具有fastjson和Jackson,大家選擇自己喜歡的用都可以。
另外,推薦過程是用Quartz定時任務庫定製在每天0點開始執行,包括像衰減機制,各個推薦演算法生成各自的推薦結果,都是這個時候完成的。所以這個推薦並不是實時的,當然做成實時的完全也沒問題,只要伺服器效能夠好。
後話
這裡只是提出自己的一個實現思路,思路的形成過程也是在看了許多推薦系統相關的學術文獻並進行了自己的總結與改變,並非權威的做法,歡迎各位提出修正意見。
聽說幾年前開始,ACM有一個每年舉辦的推薦系統學術會議叫RecSys,有興趣的小夥伴們也可以關注一下。
有問題歡迎私信我!