,
(1.濟南職業(yè)學院,山東 濟南 250014;2.山東廣播電視大學,山東 濟南 250014)
隨著網(wǎng)絡的飛速發(fā)展,網(wǎng)絡信息飛速增長,人們面臨著“信息過載”和“信息迷航”的問題。借助于搜索引擎,人們可以從海量信息中查找到自己所需的信息。但是,搜索引擎只適用于在有明確需求的情況下幫人們查找信息,如果在沒有明確需求的情況下,搜索引擎則難以幫助人們有效地篩選信息。此時推薦技術應運而生,它通過研究用戶的興趣偏好,自動建立起用戶和信息之間的聯(lián)系,從而幫助用戶從海量信息中去發(fā)掘自己潛在的需求。
推薦系統(tǒng)是建立在海量數(shù)據(jù)挖掘基礎上的,它通過分析用戶的歷史數(shù)據(jù)來了解用戶的需求和興趣,從而將用戶感興趣的信息、物品等主動推薦給用戶,其本質(zhì)是建立用戶與物品之間的聯(lián)系。常用的推薦算法主要有專家推薦、基于統(tǒng)計的推薦、基于內(nèi)容的推薦和協(xié)同過濾推薦等。其中協(xié)同過濾推薦是推薦系統(tǒng)中應用最早和最為成功的算法。
協(xié)同過濾算法的關鍵是計算相似度及求解推薦評分,在計算時需要用到矩陣的一些運算。Python的第三方擴展庫Numpy是一科學計算庫,提供了大量的數(shù)組及矩陣運算,因此很多推薦系統(tǒng)中都是利用Numpy來實現(xiàn)協(xié)同過濾算法,但因協(xié)同過濾算法中涉及到的矩陣多是稀疏矩陣,采用普通的二維數(shù)組存放存在大量的無效存儲,空間利用率較低,同時利用Numpy擴展庫也無法進行算法的優(yōu)化,因此本文利用Python的內(nèi)置序列字典來存放稀疏矩陣,自行編制相應的代碼來求解推薦評分,可有效提高算法的時間空間效率。
協(xié)同過濾算法分為基于用戶的協(xié)同過濾算法和基于物品的協(xié)同過濾算法。
基于用戶的協(xié)同過濾算法(簡稱UserCF),通過不同用戶對物品的評分來評測用戶之間的相似性,基于用戶之間的相似性做出推薦。簡單說就是給用戶推薦和他興趣相似的其他用戶喜歡的物品。
基于物品的協(xié)同過濾算法(簡稱ItemCF),通過用戶對不同物品的評分來評測物品之間的相似性,基于物品之間的相似性做出推薦。簡單說就是給用戶推薦和他之前喜歡的物品相似的物品。
UserCF算法和ItemCF算法最主要的區(qū)別在于:UserCF推薦的是那些和目標用戶有共同興趣愛好的其他用戶所喜歡的物品,ItemCF算法則推薦那些和目標用戶之前喜歡的物品類似的其他物品。因此,UserCF算法的推薦更偏向社會化,適合應用于新聞推薦、微博話題推薦等應用場景;而ItemCF算法的推薦則是更偏向于個性化,適合應用于電子商務、電影、圖書等應用場景。
UserCF算法和ItemCF算法思想類似,其實現(xiàn)過程也基本類似,唯一不同的是一個是計算用戶相似度,一個是計算物品相似度,本文以ItemCF算法為例詳細說明其具體實現(xiàn)。
以一組用戶的觀影記錄作為測試數(shù)據(jù)集,共包括兩個數(shù)據(jù)文件,一個是rating.txt,存放的是用戶對電影的評分記錄,其數(shù)據(jù)如圖1所示,每一行用逗號分隔的3個數(shù)據(jù)項分別表示用戶ID、電影ID和評分。
圖1 評分數(shù)據(jù)
另一個數(shù)據(jù)文件是movies.txt,存放的是電影信息,其數(shù)據(jù)如圖2所示,每一行用逗號分隔的3個數(shù)據(jù)項分別表示電影ID、電影名稱和上映時間,該數(shù)據(jù)文件主要用于推薦結果輸出。
圖2 電影信息數(shù)據(jù)
1.數(shù)據(jù)預處理
將數(shù)據(jù)集中的文件讀入并進行一定的處理,將用戶評分記錄及電影信息分別存入相應的字典中。其Python代碼如圖3所示。
圖3 數(shù)據(jù)預處理代碼
2.建立同現(xiàn)矩陣
ItemCF算法的關鍵是計算物品(此處為電影)的相似度,相似度的計算方法有很多,在此直接以同時出現(xiàn)的次數(shù)多少作為相似度的衡量,因此需要建立物品的同現(xiàn)矩陣M。
建立過程如下:
step1:列出每個用戶看過的電影列表,結果如圖4所示。
圖4 用戶看過的電影列表
step2:求出每個用戶的電影同現(xiàn)矩陣
例對用戶1,其看過的電影有11、12、13,因此在矩陣對應的位置(11,12)(12,11)(11,13)(13,11)(12,13)(13,12)處寫上1,其余為0。也即用戶1的同現(xiàn)矩陣如圖5所示。
圖5 用戶1的同現(xiàn)矩陣
step3:將所有用戶的同現(xiàn)矩陣相加,得到最終的同現(xiàn)矩陣,如圖6所示。
圖6 所有用戶的同現(xiàn)矩陣
利用Python來實現(xiàn)同現(xiàn)矩陣的建立,其代碼如圖7所示。
圖7 求解電影同現(xiàn)矩陣
3.計算推薦評分
計算每個用戶曾看過的電影的推薦評分。推薦評分=同現(xiàn)矩陣M*評分向量R。
評分向量即用戶對所有物品(電影)的評分,由評分記錄表可得出。
由前面計算出的同現(xiàn)矩陣和用戶1的評分向量可得出用戶1對電影104的推薦評分為:
U1:14=4.5*3+3.5*1=17
具體求解方法如圖8所示。
用戶ID電影ID1用戶評分電影ID2電影ID1與電影ID2的關聯(lián)權重得分=用戶評分?電影ID1與電影ID2的關聯(lián)權重1114.51434.5?3=13.51123.51413.5?1=3.511331400114014001150141011601430總分=13.5+3.5=17
圖8推薦評分求解過程
同樣方法可求得每個用戶對未曾看過的電影的推薦評分,其結果如圖9所示。圖中陰影部分為每個用戶未曾看過的電影中推薦評分最高的,也是要推薦的結果。
然后將推薦得分從高到低排序,實際應用中通常采用Top-N推薦,即為目標用戶提供一個長度為N的推薦列表,使該推薦列表能夠盡量滿足用戶的興趣和需求。利用Python來計算推薦評分的代碼如圖10所示。
圖9 所有用戶對未曾觀看的電影的推薦得分
圖10 求解推薦評分
4.輸出推薦結果
求得推薦評分的前N項后就可將結果輸出給用戶。輸出推薦結果時,有時可能需要為某個指定用戶來輸出推薦結果,也可能需要為所有用戶都輸出推薦結果,為使程序更加靈活,可編制兩個不同的函數(shù)來滿足其需求。為一個指定用戶輸出推薦結果的Python代碼如圖11所示。
圖11 輸出推薦結果
例如要為用戶1推薦兩部電影可直接調(diào)用主函數(shù):main_one(“rates.txt”,“movies.txt”,“1”,2),程序運行結果如圖12所示,與前面手工計算得出的結果相同。
圖12 用戶1的推薦結果
若想為每個用戶都輸出其推薦結果,其相應的主函數(shù)代碼如圖13所示。
圖13 為每個用戶推薦結果
如要為每個用戶推薦1部電影,則可直接調(diào)用主函數(shù):main_all(“rates.txt”,“movies.txt”,1),運行結果如圖14所示。
圖14 所有用戶的推薦結果
其輸出結果與前面手工求解的結果完全相同。
前面給出的測試數(shù)據(jù)集數(shù)據(jù)很少,主要應用于系統(tǒng)開發(fā)測試中。實際應用中推薦系統(tǒng)所用的數(shù)據(jù)集通常為海量數(shù)據(jù),為驗證系統(tǒng)在海量數(shù)據(jù)中的使用,可以MovieLens(http://grouplens.org/datasets/movielens)作為電影推薦系統(tǒng)中的實驗數(shù)據(jù)來測試系統(tǒng)。MovieLens是GroupLens Research實驗室的一個非商業(yè)性質(zhì)、以研究為目的的實驗性項目,采集了一組從20世紀90年代末到21世紀初的電影評分數(shù)據(jù),包含大小不同的數(shù)據(jù)集,每個數(shù)據(jù)集中包括電影信息數(shù)據(jù)及電影評分記錄等。如MovieLens 1M數(shù)據(jù)集中存放了1000多名用戶對近2000部電影的評分記錄,每個用戶至少對20部電影進行過評分,一共有100000多條電影評分記錄。當數(shù)據(jù)量增大時,存儲同現(xiàn)矩陣所需要的空間也相應增加,通過前述也可以看出同現(xiàn)矩陣是一稀疏矩陣,因此采用字典來存儲同現(xiàn)矩陣中的非零元素要比直接存儲整個同現(xiàn)矩陣節(jié)省空間。又因字典是Python的內(nèi)置對象,而numpy是第三方擴展庫,需要安裝和導入相應的模塊,因此同一算法采用內(nèi)置對象比用擴展庫會獲得更優(yōu)的時間性能和空間性能。
本文利用Python實現(xiàn)的協(xié)同過濾算法框架清晰,代碼簡潔,同時因其用Python的內(nèi)置序列字典代替二維數(shù)組來存放稀疏矩陣,有效提高了算法的時間空間效率。