基于python实现的电影推荐系统
設計總說明
本文設計了一個個性化電影推薦系統.眾所周知,現在電影資源是網絡資源的重要組成部分,隨著網絡上電影資源的數量越來越龐大,設計電影個性化推薦系統迫在眉睫.所以本文旨在為每一個用戶推薦與其興趣愛好契合度較高的電影.
論文首先闡述推薦系統的研究現狀以及意義,隨后介紹了相關的推薦算法,重點介紹協同過濾算法,并對系統實現所需技術進行了研究,接著介紹了整個推薦系統的實現,最后對整個項目進行了回顧與總結.
本系統包含電影前端展示界面、電影評分板塊、推薦算法的實現以及后端數據庫的設計.其中實現推薦算法是整個電影推薦系統的核心.系統采用由grouplens項目組從美國著名電影網站movielens整理的ml-latest-small數據集,該數據集包含了671個用戶對9000多部電影的10萬條評分數據.首先將該數據集包含的全部文件經過篩選重組之后存儲到建好的數據庫中,并將數據集按一定比例劃分為訓練集和測試集,對訓練集進行算法分析生成Top-N
個性化電影推薦列表,然后在測試集上對算法進行評測,至少包括準確率和召回率兩種評測指標.
協同過濾算法是推薦領域最出名也是應用最廣泛的推薦算法.所以系統擬采用兩種協同過濾算法給出兩種不同的推薦結果,一種是基于用戶的協同過濾算法,另一種是基于物品的協同過濾算法,用戶可以根據兩種推薦結果更加合理的選擇合適的電影.系統采用了改進之后的ItemCF-IUF和UserCF-IIF算法,對計算用戶相似度和物品相似度的計算都做出了改進.最后通過計算兩種算法的準確率(Precision)、召回率(Recall)和流行度從而對系統進行評測、并比較了兩種算法各自的優勢和劣勢.實驗證明,改進后的算法比原始的協同過濾算法推薦效果要好,準確率更高.
整個系統涉及到的編程語言包含Python、Html5、JQuery、CSS3以及MySQL數據庫編程.用到的框架是Django重量級web框架,通過該框架連接系統的前、后端.用戶首先需要填寫用戶名、密碼以及郵箱注冊系統,然后才能登陸推薦系統.進入首頁后會看到8個電影分類,包括恐怖片、動作片、劇情片等.用戶需要給自己看過的電影進行評分,評分起止為0.5-5.0分,共10個分段.每評價一部電影就要點擊一下提交按鈕,將所評分的電影的
imdbId號以及對應的評分存入數據庫中.用戶點擊“推薦結果”按鈕,系統就調用推薦算法遍歷數據庫所存數據,得出推薦列表之后將結果反饋給瀏覽器,同時調取數據庫所存電影海報圖片進行展示.用戶點擊自己登陸的昵稱,會跳轉頁面顯示自己已經評價過的電影.
本文還分析了系統的需求,并對需求進行相關設計,最后用Django框架實現了該系統,
并給出了系統所用的主要數據表展示以及各個功能界面的展示.
關鍵詞:電影推薦系統;協同過濾;基于鄰域推薦;個性化服務
第 1 章 緒論
研究背景及意義
隨著互聯網技術的快速發展,現在已經進入了大數據時代,網絡上的信息呈現爆炸式增長,每天都會有數以億計的數據涌現.人們接觸各種信息的途徑也越來越豐富,比如微博、Facebook、Twitter、微信公眾號等等.而這些在給用戶帶來便利的同時也帶來了前所未有的問題——“信息過載”[1].
“信息過載”就是指用戶很難從龐大的數據中找到自己感興趣的信息[2],[3].為了解決信息過載問題,首先出現的是搜索引擎,但是一旦用戶無法準確描述自己所需的關鍵詞,搜索引擎就無能為力了,且搜索是一種被動的檢索.而且,不同用戶之間的需求差異很大.如果只是單純的靠搜索引擎以及無法滿足獲取自身需求的信息.隨著科技的發展,后來才有了推薦系統[4].
但是,最初的自動推薦系統,只是會將時下熱門的、大眾都愛的或者能使公司獲得最大收益的產品推薦給用戶,并沒有針對每一個用戶進行分析給出推薦.這樣推薦的效果非常不理想.因此,人們希望有一種能向用戶自動推薦項目的系統和方法,并且這個系統基于用戶的偏好且對所推薦的產品進行屬性分析.這就是個性化推薦系統.
個性化推薦系統技術可以應用到很多網站上,比如圖書網站、視頻網站、音樂網站、交友網站等.用戶使用推薦系統的時間越長,不僅可以提高用戶對該網站的忠誠度[5],還能為網站帶來更多收益.最近幾年推薦系統發展迅速,這要歸功于Web2.0技術的成熟.現在用戶已經成為了網頁的積極參與者而不再是被動的網頁瀏覽者[6].所以,為眾多平臺用戶提供個性化推薦迫在眉睫.
截止于2017年底,國內知名視頻網站優酷網上的電影和電視劇數量已達16040部.在如此龐大的視頻數量下,怎樣快速幫助用戶發掘自己感興趣的電影在網站運營中顯得尤為重要.而且看電影常常被用戶當做一種放松娛樂的方式,所以用戶在打開電影網站時可能沒有明確想看的電影.這樣只有靠推薦系統通過分析用戶的歷史行為以及現下看的電影去分析潛在的用戶可能感興趣的電影.
國內外研究現狀
“推薦系統”這個概念首次由Resnick在1997年提出[7],此后就一直被廣泛引用.2007
年,ACM推薦系統會議開始舉辦,這是第一個以“推薦系統”命名的頂級會議,旨在分享研究成果和方法,推動該領域的發展.現在,AI(人工智能)、DM(數據挖掘)等學科的研究更加推動了推薦系統的發展.
如今,人們生活的方方面面已經離不開推薦系統了.幾乎所有的領域都在應用個性化推薦,比如電子商務、圖書網站、社交網站等等.
-
電子商務推薦
Amazon是電子商務推薦系統的代表,當用戶登錄后進入亞馬遜圖書網站首頁,就會看到“為您推薦”板塊,系統根據你的歷史行為生成了圖書推薦列表,如圖1-1所示.還有一
個“與您瀏覽過的商品相關的推薦”板塊.正式這樣有針對性的推薦,潛在的給Amazon帶來了巨大的經濟收益.
圖1-1 亞馬遜網站的推薦板塊1
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-lzvl81jE-1617337753444)(media/c4b7635f4d00ca1b003f542abbe022d5.jpeg)]
圖1-2 亞馬遜網站的推薦板塊2
國內的淘寶網也是典型代表.淘寶app首頁的“必買清單”其實就是根據用戶的瀏覽和購物行為而自動生成的產品推薦.當用戶購買商品之后,頁面下方有“你可能喜歡”板塊,
這樣對用戶進行針對性的推薦,極大的促進了每日的交易量.
-
社交網絡推薦
扎克伯格開發的Facebook是社交網絡推薦領域的代表[16],它也是利用社交網絡數據進行相關推送.比如里面的好友推薦界面,其實是根據用戶現有的好友以及用戶的行為記錄給用戶推薦新的好友.因為如果社交網站里的用戶的好友量很稀少,就不能體驗到社會化的優勢.因此,好友推薦模塊已經成為社交網絡的標配.
-
視頻推薦
Netflix是電影和視頻推薦領域的代表,它舉辦了在整個業界都產生廣泛影響的Netflix
比賽,極大促進了推薦技術的研究.國內的愛奇藝視頻網站也有相應的電影推薦模塊.
-
音樂推薦
國內非常受大眾喜愛的音樂播放器有“網易云音樂”.打開界面就能看到“私人FM”
板塊,里面全部是根據用戶歷史聽過的歌曲進行的推薦;“個性化推薦”板塊如圖1-3所示,其中展示了三個歌單,都是根據用戶聽過的歌曲所生成的推薦列表.里面還包括了“每日歌曲推薦”,也是根據用戶的音樂口味生成.點進去查看如圖1-4所示.
圖1-3 網易云“個性化推薦”板塊
圖1-3 網易云“每日歌曲推薦”板塊
國外對音樂個性化推薦系統的研究:認為用戶所處的情境,比如用戶當時所處的地點、時間以及天氣等因素,都會對用戶的偏好類型有影響[8].如Wang等人[9]用手機作傳感器來收
集用戶聽音樂時的環境信息,然后構建出概率模型進行分析后給用戶做推薦.
基本現在所有的推薦系統都是由前端web頁面、推薦算法、后臺日志系統組成.其中最核心的就是推薦算法.目前常用的算法有:協同過濾算法(Breese
JS et al,1998)、基于內容的推薦算法(Mooney et al,2000)、
基于關聯規則的推薦算法(Agrawal el)以及混合推薦算法(Claypool M et al,1999).
基于內容的過濾算法是根據信息資源和用戶興趣的相似度來推薦商品.能推薦新項目或者冷門的項目,使推薦系統不受冷啟動和數據稀疏問題的影響.其實搜索引擎就是基于內容的檢索,該算法在國外的主要應用有Pazzani等人設計[19]的Syskill&Webert系統[17].
協同過濾是利用用戶之間的相似性來推薦用戶該興趣的物品.但有兩個很難解決的問題,一個是稀疏性:系統初期由于系統資源還未獲得足夠的評價與反饋[9],[10],另一個是可擴展性:用戶和資源的增多會使系統性能越來越差.
本文研究目標和研究內容
本論文的研究目標是通過協同過濾算法實現一個個性化電影推薦系統:用戶首先通過填寫用戶名、密碼、郵箱地址注冊后進入系統,然后對系統主頁所展示的8個類別的電影中看過的電影進行評分,0.5分為最低分,滿分為5分,所對應的評價分別是:不喜歡、一般、喜歡、推薦.提交評分后瀏覽器將評分數據通過表單提交到數據庫,推薦系統后臺的分析算法通過UserCF(基于用戶的協同過濾算法)和ItemCF(基于物品的協同過濾算法)
給出兩種推薦.即一個是基于用戶之間的相似度,一個是基于電影之間的相似度.
本文主要研究內容包括:
研究原始的協同過濾算法,并調研應用該算法的視頻網站.
對原始的協同過濾算法做出改進,使推薦結果更加切符合用戶興趣.
選定Top-N推薦的常用評價標準召回率和準確率與原始的協同過濾算法進行比較.
以傳統的協同過濾算法為基礎,設計和實現一個個性化電影推薦系統,并從需求分析、系統設計、系統實現三個方面對該系統進行闡述.
論文結構安排
本文的結構安排如下: 第一章 緒論
主要闡述個性化推薦系統技術的研究背景及意義,說明推薦系統的實用性,講解推薦算法的國內外研究現狀以及推薦系統的國內外應用現狀,并簡述本文的研究目標以及研究內容.
第二章 推薦算法的研究
分析并介紹現有的幾種推薦算法:協同過濾算法、基于內容的推薦算法、基于標簽的推薦算法,重點分析協同過濾算法.簡要介紹相似度的計算公式:余弦相似度、歐式距離、皮爾遜(Pearson)相關系數以及曼哈頓距離,本系統所用的相似度計算公式為余弦相似度.還介紹了幾種推薦系統常用的評測指標.
第三章 實驗設計及系統實現相關技術的研究
介紹了三個實驗的設計流程及結果分析,對算法進行了評測.介紹了實現系統所需技術,重點介紹了Python、Django和MySQL.
第四章 推薦系統的設計與實現
對國內外主流視頻網站進行調研.闡述了系統的需求分析,詳細描述了系統的各個功能模塊設計、數據庫設計以及界面展示等方面的內容.
第五章 總結與展望
本章對整篇論文的研究過程進行回顧,并總結出不足之處,對推薦系統的后續研究做出相關探討.
第 2 章 推薦算法的研究
推薦算法簡介
協同過濾算法
協同過濾算法[12]主要包括基于用戶的協同過濾算法(UserCF)和基于物品的協同過濾算法(ItemCF)兩種推薦算法.
基于用戶的協同過濾算法是推薦系統中最古老的算法,它是推薦系統誕生的標志[17].
其主要包括兩個步驟:
找到和目標用戶興趣相似的用戶集合
找到這個集合中大多數用戶都喜歡的,且目標用戶沒有買過或者看過的物品進行推薦[18]
基于物品的協同過濾算法目前使用也很普遍.很多著名的視頻網站如:Hulu、YouTube
推薦算法的基礎都是該算法.該推薦算法的原理是向用戶推薦和他們之前購買過的物品相似度很高的物品.比如,該算法會因為你購買過《python編程從入門到實踐》而給你推薦《用
python寫網絡爬蟲》.主要分為兩個步驟:
計算各個物品間的相似度
對物品的相似度從高到低進行排序,然后挑選一定數量的相似度較高物品進行推薦.或者根據用戶曾經的歷史記錄進行推薦.
基于內容的推薦算法
從每個物品中抽取一些特征,然后利用一個用戶過去喜歡和不喜歡的物品的特征數據來學習此用戶的喜好特征.通過比較用戶的特征和物品的特征,給用戶推薦相似度較高的物品.基于內容的推薦算法保護了用戶之間的獨立性,并且能很好的解決物品的冷啟動問題.
基于內容的推薦算法可以充分將項目內容和用戶本身的諸多特征聯系起來,比如一部電影的演員、導演、類型,用戶的性別、年齡、職業等.
其根據用戶歷史行為構造出用戶偏好文檔,計算所推薦的項目與用戶偏好文檔的相似度,選擇最相似的項目推薦給用戶.首先為每個物品構建一個物品的屬性資料,然后為每個用戶建立其一個喜歡的物品集,最后計算其和物品屬性資料的相似度.相似度高意味著用戶可能喜歡這個物品,相似度很低則意味著用戶會討厭這個物品[13].
基于標簽的推薦算法
標簽是一種無層次化結構的、用來描述信息的關鍵詞,可以描述物品的內涵特征.有很多網站都利用了標簽系統.比如:CiteULike論文書簽網站,它允許科研人員收藏自己喜歡的論文并給論文打上標簽[21].還有國內的豆瓣網站,豆瓣網允許用戶對電影以及圖書等打標簽,系統利用打標簽這個途徑可以獲悉圖書和電影的內容以及所屬類別.
系統實現算法介紹
基于用戶的協同過濾算法
假設給定用戶 u 和用戶 v,令 N(u)表示用戶 u 曾經評價過的電影集合,令
N(v)表示用戶 v 曾經評價過的電影集合.通過余弦相似度計算用戶 u 和 v
的興趣相似度:
| N (u) || N (v) |
| N (u) ? N (v) |
(2-1)
但是上述公式過于粗糙,本系統采用的計算相似度的公式是 John S.Breese
在論文[14] 中提出的下列計算興趣相似度的公式:
?i ? N (u) ? N (v) 1
w uv
???log(1? | N (i) |)
| N (u) || N (v) |
(2-2)
該改進過的基于用戶的協同過濾算法記為 UserCF-IIF[14].式(2-2)通過
1 懲
log(1? | N (i) |)
罰了兩個用戶的興趣列表中包含熱門電影而對他們相似度產生的影響.這樣得到用戶之間的相似度之后,推薦算法會給用戶推薦與他興趣最相似的
K 個用戶喜歡的電影,下列公式計算了用戶 u 對電影 j 的興趣度.
pui ?
? wuv rvi
v?I (i )?S (u ,k )
(2-3)
式(2-3)中的 I(i)是對電影 i 打過分的用戶集合. S?u, k ?是和用戶 u
有著相似興趣愛好的 k 個用戶的集合, wuv 表示用戶 u 和用戶 v 之間的相似度,
rvi 衡量了用戶 v 對電影 i 的興趣度,在本系統里是指用戶 v 對電影 i
的評分.最后按對電影的興趣度從高到低排序,推薦前 N 部電影給用戶 u,屬于 Top-N
推薦.
基于物品的協同過濾算法
基于物品的協同過濾算法是計算物品之間的相似度,然后根據用戶之前喜歡的物品來推薦用戶可能喜歡的物品.
| N (i) || N ( j) |
| N (i) ? N ( j) |
(2-4)
式(2-4)為計算物品相似度的公式,它懲罰了物品 j
的權重,運用到本系統中可以有效避免某一熱門電影和很多其他多數電影都產生較大的相似度.
在基于物品的協同過濾算法中,兩個物品之間有相似度是因為它們存在于很多用戶的興趣列表中.但是每個用戶的貢獻都不相同.活躍用戶對物品相似度的貢獻應該小于不活躍的用戶.所以本系統采用下列改進過的計算物品相似度的公式:
?u ? N (i) ? N ( j) 1
wij
???log(1? | N (u) |)
| N (i) || N ( j) |
(2-5)
式(2-5)中的
1
log(1? | N (u) |)
也懲罰了活躍用戶對物品相似度的貢獻.之后通過下列公
式計算來用戶 v 對物品 j 的興趣度.
pvj ?
? wji rvi
i?I (v)?S ( j ,k )
(2-6)
式(2-6)中的 I(v)表示用戶 v 喜歡的或者曾經產生過行為的物品集合, S ? j,
k ?表示和物品 j 最相似的 k 個物品的集合, rvi 是用戶 v 對物品 i
的興趣度, w ji 為物品 j 和物品 i 之間的相似度,在本系統中取用戶 v 對電影 i
的評分.改進過的基于物品的協同過濾算法記為
ItemCF-IUF[14].
相似度計算
在協同過濾算法中,相似度的計算至關重要.只有計算了用戶或者物品之間的相似度才能得出推薦列表.常用的相似度計算方法有以下幾種:
余弦相似度
在 n 維空間中,任意兩個向量之間的夾角的余弦值大小即代表這兩個向量的相似程度.
余弦值的取值范圍為[-1,1].
假設 n 維空間中存在向量 i 和向量 j,式(2-7)為計算其余弦相似度的公式.
?
?
? ?
Sim(i,j) = cos( i , j ) =
i ? j (2-7)
歐式距離
|| i || * || j ||
歐式距離也稱為歐幾里得度量,是指在 n
維向量空間中,任意兩個向量之間的自然長度.同樣的,假設存在向量 M 和
N,則歐式距離表達公式如式(2-8)所示.
?
i?1
n
(m ? n )
2
i i
皮爾遜(Pearson)相關系數
如果一個推薦算法使用的是皮爾森相關系數來計算相似度,那么該算法將會比使用余弦相似度公式計算相似度的算法的精確度更高[19].然而這是要建立在兩個用戶擁有較多共同評分項目的基礎上,如果兩個用戶之間共同評分項目很少[19],使用皮爾森相關系數進行計算無法反映出真實的相似度.
?(J ? J )(K ? K )
?(J ? J )2 ?(K ? K )2
曼哈頓距離
?J ,K ?
(2-9)
在平面上,坐標( x1 , y1 )與坐標( y1 , y2 )的曼哈頓距離為:
Sim(x,y) =
| x1 - x 2 | ? | y1 - y2 |
(2-10)
推薦算法評測指標
評分預測
| T |
u ,i?T
(r ? r? )2
ui ui
RMSE ?
(2-11)
式(2-11)中的 T 表示實驗數據集的數量,rui 表示的是用戶 u 對物品 i
的真實評分,r?ui表示的是用戶 u 對物品 i 的預測評分[14].
MAE ?
1
| T |
?u,i?T
| rui
-
r?ui* |
(2-12)
TopN 推薦
通常,網站在提供預測服務時會選擇為用戶生成推薦列表,這種推薦就叫 Top-N
推薦, 這種預測準確率一般是通過準確率或者召回率測量[14].
推薦結果的準確率定義為:
Precision ? ?u?U | R(u) ? T (u) |
?u?U | R(u) |
(2-13)
推薦結果的召回率定義為:
Recall ? ?u?U | R(u) ? T (u) |
?u?U | T (u) |
(2-14)
式(2-14)中的 R(u)為算法根據用戶的訓練集給出的推薦列表,T(u)是用戶測試集列
表.
本章小結
本章節主要闡述了推薦系統實現所需的算法基礎、技術平臺以及一些開發工具,主要介紹了協同過濾算法及常用的評測指標,同時簡述了相似度的計算公式.
第 3 章 實驗設計及系統實現相關技術的研究
實驗設計及結果分析
本節將設計三個實驗對第2 章第2
節介紹的改進后的兩種算法與原始的協同過濾算法進行性能對比,并分析得出結論.
實驗環境
對比實驗使用的環境如表 3-1 所示:
表 3-1 實驗環境
處理器 Intel? Core? i5-7200U 2.5GHz
內存 4.00GB
運行環境 Windows 10
軟件 Sublime Text3, MYSQL,Pycharm
編程語言 Python
實驗設計
將數據集隨機分為 10 份,其中的 7 份為訓練集,另外的 3
份為測試集.在訓練集上建立用戶行為數據模型,在測試集上進行實驗測評,并統計測評結果.由于本系統采用的是Top-N
推薦,故使用準確率、召回率以及流行度來對算法進行評測.
-
實驗一:對 UserCF 和 UserCF-IIF
算法分別取不同的推薦電影數目(N)計算準確率和召回率的值,得出 N
取多少時推薦算法的性能相對最好.分別取推薦電影資源個數為 5,10,15,20 對 UserCF
算法進行對比實驗,得到的結果數據如表 3-2 所示.
表 3-2 UserCF 算法的準確率和召回率
| 5 | 0.3768 | 0.0421 |
| 10 | 0.3244 | 0.0724 |
| 15 | 0.2881 | 0.0965 |
| 20 | 0.2629 | 0.1174 |
分別取推薦電影資源個數為 5,10,15,20 對 UserCF-IIF
算法進行對比實驗,得到的結果數據如表 3-3 所示.
表 3-3 UserCF-IIF 算法的準確率和召回率
| 5 | 0.3782 | 0.0422 |
| 10 | 0.3264 | 0.0729 |
| 15 | 0.2925 | 0.0980 |
| 20 | 0.2660 | 0.1188 |
將上述兩張表的數據畫成折線圖分別對比兩個算法的準確率和召回率,如圖 3-1 和圖
圖 3-1 UserCF 和 UserCF-IIF 準確率對比
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-WQbXUD96-1617337753463)(media/3a58adb53752204d8d82e2cd9b4626ea.jpeg)]
圖 3-2 UserCF 和 UserCF-IIF 召回率對比
由圖知,準確率隨著推薦數目的增加呈遞減趨勢,召回率隨著推薦數目的增加呈遞增趨勢.結合實際的推薦情況,選擇
N=10 推薦效果最好.
并且改進之后的基于用戶的協同過濾算法的準確率和召回率都比傳統的算法略高.
-
實驗二:對 ItemCF 和 ItemCF-IUF 算法也進行準確率和召回率的計算和對比.
通過圖 3-3 和圖 3-4 可以得出推論,ItemCF-IUF
算法的準確率和召回率都明顯高于傳統的 ItemCF 算法.
圖 3-3 ItemCF 和 ItemCF-IUF 準確率對比
圖 3-4 ItemCF 和 ItemCF-IUF 召回率對比
-
實驗三:綜合準確率、召回率、流行度的平均值對比 UserCF-IIF 和 UserCF 以及
ItemCF-IUF 和 ItemCF 算法性能.
分別計算出四個算法在 N 取 5、10、15、20
的準確率、召回率、流行度的值,并取平均數.如表 3-4 所示,UserCF-IIF 在準確率和召回率上和 UserCF
算法相近,降低了推薦結果的流行度.如表 3-5 所示,ItemCF-IUF
在準確率和召回率上明顯優于 ItemCF
算法,同樣降低了推薦結果的流行度.這說明在計算物品相似度時考慮用戶的活躍程度可以提升推薦結果的質量.且對于本數據集,基于用戶的協同過濾算法性能優于基于物品的協同過濾算法.
表 3-4 基于用戶的協同過濾算法對比
算法 準確率 召回率 流行度
UserCF 0.3130 0.0821 4.8831
UserCF-IIF 0.3158 0.0830 4.8637
表 3-5 基于物品的協同過濾算法對比
算法 準確率 召回率 流行度
ItemCF 0.2660 0.0829 4.0427
ItemCF-IUF 0.2952 0.0831 4.0316
系統實現相關技術的研究
論文中推薦系統的開發與實現主要包括 web
前端技術、數據處理技術、推薦算法實現,系統開發所需技術如表 3-6 所示.
表 3-6 系統所需技術
技術類型 技術名稱
推薦算法開發語言 Python3
前端開發語言 Html5、CSS3、Jquery
web 框架 Django
數據庫 MySQL
Python 語言研究
Python 是由 Guido van Rossum
在八十年代末和九十年代初,在荷蘭國家數學和計算機科學研究所設計出來的[16],[21].是一個高層次的結合了解釋性、編譯性、互動性和面向對象的腳本語言[21].相比于
C 或者 Java 等其他編程語言,Python
能讓開發者很輕松的用幾行代碼就能實現一個功能完善的程序.
詳細說來,Python 語言的優勢有以下幾點:
易于學習:Python 相對其他語言比如
C++來說關鍵字較少,并且語法簡單,這種特性可以讓開發者輕而易舉的上手.
易于閱讀:Python 嚴格控制代碼縮進,使讀者能夠更加清晰的閱讀代碼.
面向對象:Python 和 Java
類似,存在一個介于源代碼文件和二進制代碼文件之間的字節碼文件,更有利于項目在不同的平臺間移植.
豐富的庫:Python
擁有大量且豐富的標準庫,可以減少很多不必要的代碼,也可以更高效的對數據、圖像進行處理.
跨平臺且開源.Python 可以跨平臺運行,并且開放源碼超過 20
年,能讓開發者更加深入的了解 Python 的機制.
Django 框架研究
Django 是一個基于 Python 的 Web 框架,可以用來開發交互式網站.Django 采用的是
MTV
框架模式,即模型(Model),模板(Template)和視圖(Views).它們各自的職責如表
3-7
所示.
由于 Django 是免費的,且公布了其源碼,又擁有豐富的文檔,所以使用的人員很多.
其具體有以下幾個優點:
通用性:Django 可以和任何客戶端框架一起工作,并且可以提供幾乎任何格式的內容.
安全性:Django 提供一種安全的方式管理用戶的賬戶和密碼,其 cookies
只包括一個秘鑰,而實際數據存儲在數據庫中.并且 Django
可以防范許多漏洞,大大提高了網站的安全性.
靈活性:由于 Django 是用 Python 語言所編寫的,所以它不受服務器平臺的限制.
比如在 Linux 系統、Windows 系統或者 Mac 系統上都能運行程序.
表 3-7 MTV 各自職責
層次 職責
模型,即數據存取層 處理與數據相關的事物,比如存取數據、驗證數據合法性
模板,即業務邏輯層 一般包含前端所有代碼以及調用的圖片
視圖,即表現層 是模型與模板之間的橋梁
Django 的 MTV 各個組織之間的協作如圖 3-5 所示.
圖 3-5 MTV 協作流程圖
MySQL 數據庫研究
數據庫是一種用于存儲數據集合的獨立應用程序.每種數據庫都會有一個或多個獨特的
API,用來創建、訪問、管理、搜索或復制數據庫中保存的數據.關系數據庫是建立在關系模型基礎上的數據庫,其所有數據都存儲在不同的表中,表之間的關系由主鍵或者外鍵等連接.
MySQL 數據庫就是一種快速易用的關系型數據庫管理系統(RDBMS),是瑞典的MySQL
AB
公司開發的一個可用于各種流行操作系統平臺的關系數據庫系統,并且是一種免費的數據庫管理系統.
MySQL 語言由
DDL(數據定義語言)、DML(數據操縱語言)、DCL(數據控制語言)組成.相比于其他的關系型數據庫,MySQL
具有許多吸引人之處:
比較容易使用.MySQL
是一個高性能并且相對很多其他數據庫來說是比較簡單的數據庫系統.
全面支持查詢語言.MySQL
可以利用結構化查詢語言,并且支持聚合函數,程序員可以在同一個查詢中混合來自不同數據庫的表.
連接性和安全性.完全支持網絡化,其數據庫可以在 Internet 上的任何地方訪問,
不會有限制.
MySQL
是客戶端/服務器架構的服務器,為客戶端提供了不同的程序接口和連接庫,且是多線程的[24].
支持大型的數據庫,可以方便的支持上千萬條記錄的數據庫.
3.3 本章小結
本章簡要介紹了系統所需實驗環境,設計了三個實驗對算法進行比較,第一個實驗比較
UserCF-IIF 和 UserCF 算法的性能,第二個實驗比較 ItemCF-IUF 和 ItemCF
算法的性能,
第三個實驗從準確率、召回率、流行度三個方面對基于用戶的協同過濾算法和基于物品的協同過濾算法進行了比較,得出在本數據集的基礎上,基于用戶的協同過濾算法性能更優一些的結論.最后對系統所用的技術進行了研究,詳細介紹了
Python 語言的優勢、Django 框架和 MySQL 數據庫的優點.
第 4 章 推薦系統的設計與實現
本章將改進后的基于用戶的協同過濾算法和基于物品的協同過濾算法相結合應用到實際中,做出了個性化的電影推薦系統.本章首先對國內外的主流視頻網站進行了調研,然后講解系統的需求分析,介紹系統架構以及數據庫,最后展示系統界面.
國內外主流視頻網站推薦效果調研
國內視頻網站調研
調研了作為國內第一大視頻網站的優酷網.圖 4-1 為優酷視頻網站首頁的“優酷懂你”
板塊為某用戶給出的推薦列表[17],圖 4-2 為該用戶的觀看記錄.
對比觀察用戶的觀看記錄和優酷給出的推薦列表,發現該用戶比較偏向看綜藝、日劇以及恐怖片.但是推薦列表中的視頻基本都與用戶的喜好不同.其實優酷網的這個版塊只是推薦了一些熱門視頻,缺乏個性化和針對性,推薦效果很差,既浪費用戶時間也降低了用戶的體驗.
圖 4-1 “優酷懂你”給出的推薦
圖 4-2 用戶觀看記錄
國外視頻網站調研
調研了在全世界都著名的 Youtube
視頻網站.用戶登錄后進入首頁就有“推薦視頻”板塊,如圖 4-3
所示.其中推薦的視頻都是根據用戶的歷史看過的視頻分析所得,而且每個視
頻下方還有上傳網站的時間.該用戶的歷史記錄所看的視頻節選如圖 4-4 和圖 4-5
所示.
圖 4-3 Youtube 首頁的推薦板塊
圖 4-4 用戶歷史記錄節選 1
圖 4-5 用戶歷史記錄節選 2
需求分析
隨著電影市場的迅速發展,每天都有大量電影上映.人們都希望可以高效的在海量電影庫中找到自己可能會喜歡的電影,以節省尋找電影的時間[22].電影推薦系統能給用戶帶來便利.本文要實現的是一個面向用戶的個性化電影推薦系統,根據
movielens
數據集里面大量用戶對電影的評分數據,通過計算用戶相似性、電影相似性,實現為用戶推薦符合其興趣的電影.
本文實現的個性化電影推薦系統有以下幾點基本需求:
數據集:每個用戶所評電影數量要多,盡量廣泛涉及大量電影
推薦算法:推薦效果要良好
包括用戶注冊登錄在內的整個 web 系統
系統要易于擴展和維護
用戶功能需求
如圖 4-6 是系統中用戶的用例圖,有 5
個用例,分別是注冊、登錄、注銷、評分、查看推薦結果.
圖 4-6 用戶的用例圖
系統設計
系統總體架構
本文從互聯網上下載 movielens
數據集,經過數據重組和篩選,基于兩種推薦算法得出推薦結果保存至MySQL
數據庫中,并通過 Django
框架進行前端展示.本系統采用B/S(瀏覽器/服務器)體系結構,用戶通過瀏覽器就能和網站上的內容交互.
實現本系統主要需要以下幾種編程語言:
Python:進行后臺開發,寫推薦算法,和 MySQL
數據庫交互,將用戶的數據存儲到數據庫中,又將生成的推薦列表展示到前端頁面.
Html5:進行前端頁面的開發.
Css3:美化前端頁面,特別是對電影分類板塊做處理.
Jquery:實現提交表單和首頁中的星星評分效果.
系統的總體架構設計圖如圖 4-7 所示.
圖 4-7 系統架構圖
一個良好的推薦系統,必須要有一個良好的用戶交互界面和用戶行為數據[16].其之間的關系如圖
4-8 所示.
圖 4-8 推薦系統和日志系統之間的聯系
系統功能模塊簡述
本系統以改進后的用戶協同過濾和物品協同過濾算法為依據,采用 django 重量級 Web
框架設計并實現.包括了數據集處理模塊、注冊登錄模塊、電影分類模塊、用戶評分反饋模塊、推薦算法模塊和推薦電影展示模塊.
① 數據集處理模塊
本文設計的推薦系統的源數據集來源于 movielens 的 ml-latestl-small,其中包含
671 個用戶的 10 萬條評分數據.對數據集里面的 ratings.csv 和 links.csv
文件進行連接處理,只保留 userId、imdbId、rating
三個字段存入數據庫中新建好的數據表 users_resulttable 中.
② 注冊登錄模塊
用戶只有先注冊并且登錄系統之后才能提交對電影的評分.注冊界面含用戶名、電子郵箱地址以及密碼.注冊和登錄界面如圖
4-9 所示.
圖 4-9 注冊和登錄界面
用戶注冊界面的核心代碼如下:
@register.html
<div class=“unit-1-2 unit-1-on-mobile”>
<h3>注冊</h3>
<form class=“form” action="{% url ‘users:register’ %}" method=“post”>
{% csrf_token %}
{% for field in form %}
{{ field.label_tag }}
{{ field }}
{{ field.errors }}
{% if field.help_text %}
<p class=“help text-small text-muted”>{{ field.help_text|safe }}</p>
{% endif %}
{% endfor %}
<button type=“submit” class=“btn btn-primary btn-block”>注冊</button>
</form>
<div class=“flex-center top-gap text-small”>
<a href=“login.html”>已有賬號登錄</a>
</div>
</div>
用戶登錄界面的核心代碼如下:
@login.html
<div class=“unit-1-2 unit-1-on-mobile”>
<h3>登錄</h3>
<form class=“form” action="{% url ‘login’ %}" method=“post”>
{% csrf_token %}
{{ form.non_field_errors }}
{% for field in form %}
{{ field.label_tag }}
{{ field }}
{{ field.errors }}
{% if field.help_text %}
<p class=“help text-small text-muted”>{{ field.help_text|safe }}</p>
{% endif %}
{% endfor %}
<button type=“submit” class=“btn btn-primary btn-block”>登錄</button>
<input type=“hidden” name=“next” value="{{ next }}"/>
</form>
<div class=“flex-left top-gap text-small”>
<div class=“unit-2-3”><span>沒有賬號?<a href="{% url ‘users:register’
%}">立即注冊</a></span></div>
</div>
</div>
③ 電影分類模塊
系統首頁一共有 8 種類型的電影,如 4-10 所示.
從左到右依次是動作片、恐怖片、喜劇片、動畫片、科幻片、犯罪片、愛情片以及劇情片.
圖 4-10 系統首頁
圖 4-11 是愛情片的展示界面.
圖 4-11 愛情片展示界面
實現分類效果的部分代碼如下:
@index.html
<div>
<hr />
<ul class=“nav nav-tabs nav-justified” id=“index”>
<li class=“active”><a href="#tab0" data-toggle=“tab”>動作</a></li>
<li><a href="#tab1" data-toggle=“tab”>恐怖</a></li>
<li><a href="#tab2" data-toggle=“tab”>喜劇</a></li>
<li><a href="#tab3" data-toggle=“tab”>動畫</a></li>
<li><a href="#tab4" data-toggle=“tab”>科幻</a></li>
<li><a href="#tab5" data-toggle=“tab”>犯罪</a></li>
<li><a href="#tab6" data-toggle=“tab”>愛情</a></li>
<li><a href="#tab7" data-toggle=“tab”>劇情</a></li>
</ul>
</div>
每一部電影包括電影海報、電影名字、imdb 網站的超鏈接以及星星評分.代碼如下:
@index.html
<li class=“list_item” data-trigger-class=“list_item_hover”>
<a _boss=“film” target="_blank" class=“figure” tabindex="-1">
<img src="{% static ‘img/action/103776.jpg’ %}" alt=“蝙蝠俠歸來”>
</a>
<strong class=“figure_title”>
<a _boss=“film”
href="http://www.imdb.com/title/tt0103776/"
target="_blank"
title=“蝙蝠俠歸來”>蝙蝠俠歸來(8.1 分)</a>
<div class=“evaluate”>
<div class=“starts” id = “103776”></div>
</div>
</strong>
</li>
點擊電影名字會鏈接到 imdb 網站,用戶可以瀏覽電影的詳情頁.圖 4-12
是電影《千與千尋》的 imdb 網站的展示頁面.
圖 4-12 《千與千尋》的 imdb 網站詳情頁
④ 用戶評分反饋模塊
系統利用了 jquery-raty
評分插件,收集用戶對每一部電影的評分.用戶通過點擊‘提交評分’按鈕將評分數據提交到
MySQL 中的 users_resulttable 表中,插入到源數據集末尾.
圖 4-13 用戶對動作片評分
圖 4-14 用戶對恐怖片評分
圖 4-13 和圖 4-14 分別是某用戶對電影分類模塊中的動作片和恐怖片的評分圖.
實現星星評分效果的核心代碼如下:
@index.html
$(".starts").raty({
number : 5,//星星個數
{#score :3,#}
path : ‘{% static ‘img’ %}’,//圖片路徑
{#target : ‘#grade’,//#}
{#hints : [‘0.5’,‘1’,‘1.5’,‘2’,‘2.5’,‘3’,‘3.5’,‘4’,‘4.5’,‘5’],#}
hints : [‘不喜歡’,‘不喜歡’,‘一般’,‘喜歡’,‘推薦’],
starHalf:‘star-half-big.png’,
half:true, round:{down:.26,full:.7,up:.9}, click : function(score, evt) {
if((score<0.5)) result = 0.5;
else if((score>0.51)&&(score<1.0)) result = 1.0; else
if((score>1.1)&&(score<1.5)) result = 1.5; else
if((score>1.5)&&(score<2)) result = 2.0; else
if((score>2.0)&&(score<2.5)) result = 2.5; else
if((score>2.5)&&(score<3.0)) result = 3.0; else
if((score>3.0)&&(score<3.5)) result = 3.5; else
if((score>3.5)&&(score<4.0)) result = 4.0; else
if((score>4.0)&&(score<4.5)) result = 4.5; else result = 5.0;
$("#rating").val(result.toFixed(1));
{#alert(result.toFixed(1));#}
}
});
提交用戶對電影的評分相關代碼如下:
@index.html
<form action="/insert" method=“get” target=“nm_iframe”>
<input type=“hidden” name=“userId” id = “userId”> <br>
評分: <input type=“text” name=“rating” id = “rating”> <br>
電影 ImdbId: <input type=“text” name=“imdbId” id = “imdbId”> <br>
<input type=“submit” value=“提交評分”>
</form>
<iframe id=“id_iframe” name=“nm_iframe” style=“display:none;”></iframe>
<script type=“text/javascript”>
$(document).ready(function(){
$(".starts").click(function(){
$("#imdbId").val(this.id);
$("#userId").val({{ user.id}});
});
</script>
def insert(request): global USERID
USERID = int(request.GET[“userId”])+1000 RATING =
float(request.GET[“rating”]) IMDBID = int(request.GET[“imdbId”])
Resulttable.objects.create(userId=USERID, rating=RATING,imdbId=IMDBID)
return HttpResponseRedirect(’/’)
⑤ 用戶評分記錄模塊
用戶登錄系統后點擊自己的昵稱,將跳轉頁面顯示自己曾經評價過的電影列表.如圖4-15
所示.
圖 4-15 某用戶評價過的電影列表
相關代碼如下:
@views.py
def showmessage(request): usermovieid = [] usermovietitle = []
data=Resulttable.objects.filter(userId=1001) for row in data:
usermovieid.append(row.imdbId) try:
conn = get_conn() cur = conn.cursor()
#Insertposter.objects.filter(userId=USERID).delete() for i in usermovieid:
cur.execute(‘select * from moviegenre3 where imdbId = %s’,i) rr =
cur.fetchall()
for imdbId,title,poster in rr: usermovietitle.append(title) print(title)
finally:
conn.close()
return render(request, ‘users/message.html’, locals())
@message.html
<html lang=“en”>
<head>
<meta charset=“UTF-8”>
<title>用戶評過的電影</title>
<style> h2{
}
li{
}
text-align: center;
font-family: Georgia, serif; font-weight: bold
list-style: none; text-align: center;
{#display: inline-block;#}
</style>
</head>
<body>
<h2>您評價過下列電影:</h2>
<br/>
{% for dd in usermovietitle %}
<li>
<p>{{ dd }}</p>
</li>
{% endfor %}
</body>
</html>
⑥ 推薦算法模塊
本模塊是整個系統的核心組成部分,當用戶登錄進入系統并對電影進行評分之后,系統就記錄下了該用戶的
id
號,當用戶再次登入系統時,系統會將源數據集和該用戶之前的評分數據整合成新的數據表作為推薦的依據.
整個推薦過程流程圖如圖 4-16
所示.
圖 4-16 系統推薦流程圖
算法生成推薦電影的 imdbId 號之后存入 matrix 全局變量列表中,并在 moviegenre
數據表中查詢到相關的電影名稱以及電影海報的鏈接,將 userId、title、poster
數據插入到
users_insertposter
數據表中,此表即為所有登錄用戶的電影推薦列表集.得出用戶的電影推薦結果并插入數據表中的核心代碼如下:
@views.py
def recommend(self, user): matrix.clear()
K = self.n_sim_user N = self.n_rec_movie rank = dict()
watched_movies = self.trainset[user]
for similar_user, similarity_factor in sorted(user_sim_mat[user].items(),
key=itemgetter(1),
reverse=True)[ 0:K]:
for imdbid in self.trainset[similar_user]: if imdbid in watched_movies:
continue rank.setdefault(imdbid, 0) rank[imdbid] += similarity_factor
rank_ = sorted(rank.items(), key=itemgetter(1), reverse=True)[0:N] for
key,value in rank_:
matrix.append(key) #matrix 為存儲推薦的 imdbId 號的數組
return matrix
def recommend1(request): Insertposter.objects.filter(userId=USERID).delete()
read_mysql_to_csv(‘users/static/users_resulttable.csv’,USERID)
#追加數據,提高速率ratingfile2 = os.path.join(‘users/static’,
‘users_resulttable.csv’)
usercf = UserBasedCF() userid = str(USERID) print(userid)
usercf.generate_dataset(ratingfile2) usercf.calc_user_sim()
usercf.recommend(userid)
try:
conn = get_conn() cur = conn.cursor() for i in matrix:
cur.execute(‘select * from moviegenre3 where imdbId = %s’,i) rr =
cur.fetchall()
for imdbId,title,poster in rr: if(Insertposter.objects.filter(title=title)):
continue
else:
Insertposter.objects.create(userId=USERID, title=title, poster=poster)
finally:
Conn.close()
results = Insertposter.objects.filter(userId=USERID)
return render(request, ‘users/movieRecommend.html’,locals())
⑦ 顯示推薦模塊
根據登錄用戶對電影的評分反饋,通過基于用戶的協同過濾和基于物品的協同過濾算法給出圖
4-17 和圖 4-18 兩種推薦結果.
圖 4-17 基于用戶的推薦結果
圖 4-18 基于物品的推薦結果
算法從 users_insertposter
數據表中獲取相應登錄用戶的推薦電影列表相關內容展示到前端界面.上述過程的核心代碼如下:
@movieRecommend.html
{% for result in results %}
<li>
<p>{{ result.title }}</p>
<img src="{{ result.poster }}" alt="">
</li>
{% endfor %}
數據庫介紹與設計
實驗數據集介紹
本實驗采用的數據集是由 GroupLens 科研小組從電影網站 MovieLens 上統計的
ml-latest-small 數據集,該數據集包含了從 1995 年到 2016 年 10 月內 671
名用戶對 9125 部
電影的評分記錄,一共 100004
條電影評分.里面的每一名用戶評價的電影數量都不少于 20 部.該 ml-latest-small
數據集由四個 csv 文件組成,分別是 ratings.csv、movies.csv、links.csv 以及
tags.csv[25].下面將一一介紹.
ratings.csv 是用戶評分信息表,第一行是 4 個 title:userId(用戶 id)、電影
id(movieId)、用戶評分(rating)以及 timestamp(時間戳),其中用戶評分區間為 0.5
分-5 分.表 4-1 即為
ratings.csv 文件的節選.movies.csv 是電影屬性表,包含三個字段,分別是
movieId(電影的 id
號)、title(電影名稱)、genre(電影的題材),表 4-2 即為 movies.csv
文件的節選.
表 4-1 ratings.csv 內容節選
| 1 31 | 2.5 | 1260759144 |
| 1 1029 | 3 | 1260759179 |
| 1 1061 | 3 | 1260759182 |
| 2 10 | 4 | 835355493 |
| 2 17 | 5 | 835355681 |
| 2 39 | 5 | 835355604 |
表 4-2 movies.csv 內容節選
movieId title genres
Toy Story (1995) Adventure|Animation|Children|C omedy|Fantasy
Jumanji (1995) Adventure|Children|Fantasy
Grumpier Old Men (1995) Comedy|Romance
Waiting to Exhale (1995) Comedy|Drama|Romance
Father of the Bride Part II (1995) Comedy
links.csv 包含 movieId、imdbId、tmdbId 三個字段.其中 imdbId
是該電影在電影網站
imdb 的編號,tmdbId 是該電影在電影網站 The Movie Database
的編號,都可以用來唯一識別某部電影.tags.csv
主要包括電影的標簽,適合做基于標簽的推薦系統,本系統沒有用到該文件中的內容.表
4-3 和表 4-4 分別是 links.csv 文件和 tags.csv 文件的內容節選.
表 4-3 links.csv 內容節選
movieId imdbId tmdbId
1 0114709 862
| 3 | 0113228 | 15602 |
| 4 | 0114885 | 31357 |
5 0113041 11862
6 0113277 949
表 4-4 tags.csv 內容節選
| 15 | 339 | sandra ‘boring’ bullock | 1138537770 |
| 15 | 1955 | dentist | 1193435061 |
| 15 | 7478 | Cambodia | 1170560997 |
| 15 | 32892 | Russian | 1170626366 |
| 15 | 34162 | forgettable | 1141391765 |
| 15 | 35957 | short | 1141391873 |
另外數據庫中還有 moviegenre 數據表, 里面包含 imdbId、title( 電影名字)、imdb
score(imdb 網站的電影評分)、poster(電影海報鏈接),通過查詢電影 imdbId
可以得到該電影的名字和海報圖展示到前端.
數據庫邏輯結構設計
本節歸納了用戶、電影、推薦列表、用戶評分數據表之間的關系.
用戶實體屬性如圖 4-19
所示.每個用戶注冊系統的時候都必須填寫用戶名、郵箱地址,
設置用戶密碼,并且系統會自動為其分配一個 id 號.
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-vIqJtup3-1617337753545)(media/37ea25e2cae0a1bc3fc6f2e491a7951e.png)]
圖 4-19 用戶 E-R 圖
每部電影信息的實體屬性如圖
4-20 所示.
圖 4-20 電影 E-R 圖
推薦結果列表信息的實體屬性如圖 4-21
所示.推薦結果列表中包含電影的海報圖地址,這樣推薦頁面就會展示出電影海報,增加系統美觀的同時也提高了用戶的可閱讀性.
圖 4-21 推薦結果 E-R 圖
用戶對電影的評分實體屬性如圖 4-22 所示.
圖 4-22 用戶評分 E-R 圖
系統 E-R 圖
數據庫模型通常包括層次模型、網狀模型、關系模型以及 ER
圖(實體-聯系圖).系統的 E-R 圖如圖 4-23 所示.
圖 4-23 系統 E-R 圖
系統數據表設計
本系統采用 MySQL
數據庫,數據庫中包括用戶信息表、電影屬性表、電影評分表、電影推薦列表.下面將介紹主要的存儲表的結構.
電影屬性表
電影屬性表用來保存系統中每部電影的一些屬性,包括電影的 imdbId
號、電影名字、電影的海報鏈接三個字段,數據表的名字為 moviegenre.表 4-5 即為
moviegenre 表.
表 4-5 電影屬性表
| imdbId title | int(11) varchar(300) | imdb 網站上電影的編碼 電影名字 | 主鍵 |
| poster | varchar(300) | 電影海報圖的鏈接地址 |
電影評分表
該表所存內容來自 movielens 的 ratings.csv 和 links.csv
文件,這兩個文件所含內容已經在 4.5.1 節說明,這里略過.用 mysql 語句將
ratings.csv 和 links.csv 連接,只保留 userId、
imdbId、rating 并存入已經建好的空數據表 users_resulttable
中.這個數據表里的數據就是推薦算法得出推薦結果的依據.算法只有遍歷這個數據表,才能計算出登錄用戶和該表中的哪些用戶相似度較高,從而給出推薦結果.電影評分表如表
4-6 所示.
| 字段名稱 | 字段類型 | 含義 | 備注 | |
| userId imdbId rating | int(11) int(11) decimal(3,1) | 用戶的 id 號 imdb 網站上電影的編碼用戶的電影評分 | ||
| id | int(11) | 主鍵 |
電影推薦列表
推薦算法遍歷 users_resulttable 表之后,會生成目標用戶的推薦的電影的 imdbID
號, 然后在電影屬性表 moviegenre
中查詢出電影的名字和海報鏈接并插入電影推薦列表中.存海報鏈接是為了展示頁面既有電影名也有電影的海報圖,這樣就生成了屬于登錄用戶專屬的電影推薦列表,表名為
users_insertposter.
系統給出的電影推薦列表包含字段如表 4-7 所示.
| 字段名稱 | 字段類型 | 含義 | 備注 | |
| id | int(11) | 主鍵 | ||
| userId title | int(11) varchar(60) | 用戶的 id 號 電影名字 | ||
| poster | varchar(400) | 電影海報地址 |
表 4-8 為 users_insertposter 數據表部分內容節選.
表 4-8 users_insertposter 數據表內容節選
| 1 | 1002 | Pitch Black (2000) | https://images-na.ssl-images-amazon.com/images/M/ |
| MV5BNTNmYzE1OWYtZDdjNC00OTdhLTg1YjU | |||
| tYWJlZTVkMzkzNmVkXkEyXkFqcGdeQXVyMT | |||
| QxNzMzNDI@.V1_UX182_CR0,0,182,268_AL.j | |||
| pg | |||
| 2 | 1002 | The Transporter (2002) | https://images-na.ssl-images-amazon.com/images/M/ |
| MV5BMTk2NDc2MDAxN15BMl5BanBnXkFtZTY | |||
| wNDc1NDY2.V1_UY268_CR2,0,182,268_AL.jp | |||
| g | |||
| 3 | 1002 | Big Hero 6 (2014) | https://images-na.ssl-images-amazon.com/images/M/ |
| MV5BMDliOTIzNmUtOTllOC00NDU3LWFiNjYt | |||
| MGM0NDc1YTMxNjYxXkEyXkFqcGdeQXVyNT | |||
| M3NzExMDQ@._V1_UY268_CR3,0,182,268_AL_ | |||
| .jpg | |||
| 4 | 1002 | Donnie Darko (2001) | https://images-na.ssl-images-amazon.com/images/M/ |
| MV5BZWQyN2ZkODktMTBkNS00OTBjLWJhOG | |||
| YtNGU4YWVkNTY0ZDZkXkEyXkFqcGdeQXVy | |||
| NjU0OTQ0OTY@._V1_UY268_CR0,0,182,268_A | |||
| L_.jpg |
本章小結
本章首先深刻分析了系統的需求分析,接著介紹了整個推薦系統的架構和各個功能模塊的設計與實現,不僅展示了系統的注冊登錄界面、電影首頁、電影評分板塊以及電影推
薦界面,還給出了實現每個功能的核心代碼.
同時,本章節也詳細介紹了系統數據庫的設計,數據庫總共包含了用戶信息表、電影屬性表、電影評分表、電影推薦列表
4 張數據表,展示了各個表所含內容.并且以 ER
圖的形式展示了各個數據表的屬性以及其內在聯系.
第 5 章 總結與展望
總結
隨著互聯網的飛速發展,關于推薦系統的研究工作也蒸蒸日上.本文主要研究了實現推薦系統所需的技術,研究了推薦算法以及推薦系統的一些國內外現狀.并以電影推薦系統為實例,對整個推薦系統的架構以及所有功能做了詳盡的闡述與分析.從系統的需求分析出發,剖析了用戶對功能的需求,然后介紹了系統的各個功能模塊,最后充分展示了系統數據庫的設計以及數據表的內容.
設計的系統包含用戶信息模塊、電影展示模塊、用戶評分模塊、推薦結果模塊.每個模塊的介紹都有流程圖或者系統截圖.數據庫中的核心數據表也充分對所存內容、每個字段的類型進行了闡述.
本系統采用改進過的兩種協同過濾算法:基于用戶的協同過濾和基于物品的協同過濾,使用戶能從兩種不同角度獲得推薦,提高用戶的可選擇性.并且利用準確率、召回率以及流行度三個指標對算法進行評測.實驗表明,基于本系統所用數據集,UserCF-IIF
算法的性能要優于 ItemCF-IUF 算法.
核心的推薦算法工作完成后,本文結合現有的較熱門的 Web 重量級框架 Django,利用
Django 內置的用戶注冊表單實現用戶注冊,編寫視圖代碼進行電影推薦結果的 UI
前端展示.利用 CSS3
語言對網頁進行排版、美化,使系統看上去更加簡潔和美觀,增加用戶的體驗.
不足之處及未來展望
本文工作完成了一個簡單的個性化電影推薦系統,仍然還有很多地方不足需要進一步完善,主要有以下幾個方面:
采用的算法效率不夠高.當前使用的兩種算法依舊是上個世紀提出的算法,所以系統運行效率不高,速度很慢,推薦的物品準確率不高.后期可以考慮拋棄古老的推薦算法,
采用更新、效率更高的推薦算法,并結合基于標簽和基于內容的推薦算法進行推薦.可以在用戶注冊時就填寫年齡、性別、職業等信息先進行初步的分類給出推薦,再根據評分精準推薦,效果會更好.
本系統使用的是用戶對電影的歷史評分數據,這些數據都存在一定的稀疏性.登錄用戶看過的電影可能很少,這樣就導致他和數據庫中所存用戶評過分的電影有較少的交叉項目,使得計算出的相似度很不準確.如何減少數據稀疏帶來的困擾是提高推薦系統準確度的又一個出發點.系統采用的是
movielens 網站的較小的數據集,整個數據集壓縮之后只有
897kb,所以包含的電影數目也不是很多,推薦的效果大打折扣.之后可以用更大的數據集,
考慮遍歷百萬條評分數據來進行推薦.
本系統電影首頁的分類模塊,只針對數據集中含有的電影的 8
個類別分別挑選了
16
部電影,導致用戶能進行評分的電影數量有限.且沒有設計電影搜索功能,用戶不能針對性的對自己看過的電影進行評分.
參考文獻
Pilli L E, Mazzon J A. Information overload, choice deferral, and moderating
role of need for cognition: Empirical evidence[J]. Revista De Administracao
Publica, 2016, 51(1):36-55.
朱杰. 基于標簽和協同過濾的圖片推薦系統[D]. 天津師范大學,2014.
王國霞,劉賀平. 個性化推薦系統綜述[J]. 計算機工程與應用,2012:66-76.
[4] 許海玲,吳瀟,李曉東,等 互聯網推薦系統比較研究[J]. 軟件學報. 2009,
20(2): 350-362.
Hofmann T. Latent semantic models for collaborative filtering[J].ACM
Transactions on Information Systems, 2004, 22(1):89-115.
楊杰. 個性化推薦系統應用及研究[D].中國科學技術大學,2009.
Ungar L H, Foster D P. Clustering methods for collaborative
filtering[C].Proceedings of the AAAI Workshop on Recommendation
Systems,Madison, USA, Jul 26-27, 1998. Menlo Park, CA, USA: AAAI, 1997:
114-129 .
Tan Xueqing, He Shan. Research Review on Music Personalized Recommendation
System[J]. New Technology of Library and Information Service, 2014, 30(9):
22-32.
Wang X, Rosenblum D, Wang Y. Context-Aware Mobile Music Recommendation for
Daily Activities [C]. In: Proceedings of the 20th ACM International
Conference on Multimedia. ACM, 2012: 99-108.
徐晨. 基于二部網絡分析的推薦算法研究及其應用[D]. 揚州大學,2017.
李小浩.協同過濾推薦算法稀疏性與可擴展性問題研究[D].重慶大學,2015.
[12]X. Su, T.M. Khoshgoftaar, A survey of collaborative filtering
techniques, Adv. Artif. Intell. 2009 (2009) .
喜晶. 個性化推薦技術的分析和比較[J]. 軟件研發與應用,2016:39.
Breese J S, Heckerman D, Kadie C. Empirical analysis of predictive
algorithms for collaborative filtering[J]. Uncertainty in Artificial
Intelligence, 2013, 98(7):43-52.
項亮.推薦系統實踐[M].北京:人民郵電出版社,2012 :26.
馮阿敏. 基于用戶協同過濾算法的推薦系統的設計與實現[D]. 西安電子科技大學,
張明珺. 基于用戶的個性化影視推薦系統的研究與實現[D]. 電子科技大學,2017.
陳諾言. 基于個性化推薦引擎組合的推薦系統的設計與實現[D]. 華南理工大學,2012.
Pazzani M J,J Muramatsu,D Billsus. Syskill & Webert:Identifying interesting
web sites[C]. Proceedings of the national conference on artificial
intelligence,1996:54-61.
尤方圓. 電影推薦系統的設計與實現[D]. 華中科技大學,2013.
張兵. 空氣質量模型的研究與應用[D]. 中國地質大學(北京),2017.
范永全,劉艷,陸園. 社會化推薦系統的研究進展綜述[J]. 現代計算機,2014:30-31.
王玉業. 基于協同過濾的個性化推薦研究[D]. 江蘇大學,2017.
余文麗. 基于 Android 的教學信息管理系統的設計與實現[D]. 華中師范大學,2015.
張瓊林. 針對冷啟動的分布式協同過濾推薦系統的研究[D]. 湖南工業大學. 2015.
致 謝
從 17 歲的雨季到 21
歲的花季,我在江南大學度過了我人生中最青春的四年.轉眼間,
這四年的本科生生活就要結束了,我希望能給它畫上一個圓滿的句號.
在這四年的時光里,我得到許多老師以及同學的幫助.在論文完稿之際,我想借此機會向所有給予我支持和鼓勵的人表達我的謝意.
首先,我要感謝我的導師詹千熠老師對我的指導.從開題報告、中期答辯到現在的定稿,
詹老師都認真負責,全心全意的輔導我,提出改進意見.詹老師的敬業態度以及對學術的鉆研精神,是值得我學習的榜樣.
其次,我要感謝我的父母,是他們一直在背后默默支持我,鼓勵我,才能讓我更加安心的投入到學習中,才能順利完成本科生學業.
同時,我還要感謝同窗四年的大學同學所給予我生活和學習上的幫助,正是有你們的幫助,才使我在陌生的環境中有了家的歸屬感.
最后,我要感謝數字媒體學院的全體老師,感謝他們的辛勤付出,使我學習到很多知識,夯實了專業技能.
感謝各位評審老師,感謝你們在百忙之中對我的論文進行評審.
附錄 A: 作者在校期間發表的論文
伍靜,劉德豐,張松等.智能摔倒檢測監控系統設計[J].計算機技術與發展,2018:
6-10.
附錄B: 代碼
@views.py
def get_conn():
conn = pymysql.connect(host=‘127.0.0.1’, port=3307, user=‘root’,
passwd=‘aptx4869.’, db=‘haha’, charset=‘utf8’)
return conn
def read_mysql_to_csv(filename,user):
with codecs.open(filename=filename, mode=‘w’, encoding=‘utf-8’) as f: write
= csv.writer(f, dialect=‘excel’)
conn = get_conn() cur = conn.cursor()
cur.execute(‘select * from users_resulttable’) rr = cur.fetchall()
for result in rr:
write.writerow(result[:-1])
def register(request):
# 只有當請求為 POST 時,才表示用戶提交了注冊信息
if request.method == ‘POST’:
form = RegisterForm(request.POST)
# 驗證數據的合法性
if form.is_valid():
# 如果提交數據合法,調用表單的 save 方法將用戶數據保存到數據庫
form.save()
# 注冊成功,跳轉回首頁
return redirect(’/’)
else:
# 請求不是 POST,表明用戶正在訪問注冊頁面,展示一個空的注冊表單給用戶form =
RegisterForm()
return render(request, ‘users/register.html’, context={‘form’: form})
def index(request):
return render(request, ‘users/…//index.html’)
def recommend1(request): Insertposter.objects.filter(userId=USERID).delete()
#selectMysql()
read_mysql_to_csv(‘users/static/users_resulttable.csv’,USERID)
#追加數據,提高速率ratingfile2 = os.path.join(‘users/static’,
‘users_resulttable.csv’)
usercf = UserBasedCF() #userid = ‘1001’
userid = str(USERID)#得到了當前用戶的 id print(userid)
usercf.generate_dataset(ratingfile2) usercf.calc_user_sim()
附錄usercf.recommend(userid) #得到 imdbId 號try:
conn = get_conn() cur = conn.cursor()
#Insertposter.objects.filter(userId=USERID).delete() for i in matrix:
cur.execute(‘select * from moviegenre3 where imdbId = %s’,i) rr =
cur.fetchall()
for imdbId,title,poster in rr:
#print(value) #value 才是真正的海報鏈接
if(Insertposter.objects.filter(title=title)): continue
finally:
else:
Insertposter.objects.create(userId=USERID, title=title, poster=poster)
conn.close()
results = Insertposter.objects.filter(userId=USERID)
return render(request, ‘users/movieRecommend.html’,locals())
def recommend2(request): Insertposter.objects.filter(userId=USERID).delete()
read_mysql_to_csv(‘users/static/users_resulttable2.csv’,USERID)
#追加數據,提高速率ratingfile2 = os.path.join(‘users/static’,
‘users_resulttable2.csv’)
itemcf = ItemBasedCF()
userid = str(USERID)#得到了當前用戶的 id print(userid)
itemcf.generate_dataset(ratingfile2) itemcf.calc_movie_sim()
itemcf.recommend(userid) #得到 imdbId 號try:
conn = get_conn() cur = conn.cursor()
#Insertposter.objects.filter(userId=USERID).delete() for i in matrix:
cur.execute(‘select * from moviegenre3 where imdbId = %s’,i) rr =
cur.fetchall()
for imdbId,title,poster in rr:
#print(value) #value 才是真正的海報鏈接
if(Insertposter.objects.filter(title=title)): continue
finally:
else:
Insertposter.objects.create(userId=USERID, title=title, poster=poster)
conn.close()
results = Insertposter.objects.filter(userId=USERID)
Insertposter.objects.all()
return render(request, ‘users/movieRecommend2.html’,locals())
總結
以上是生活随笔為你收集整理的基于python实现的电影推荐系统的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 美国团购网站Groupon的盈利模式
- 下一篇: 话说Python:非主流编程语言