python實現(xiàn)協(xié)同過濾推薦算法完整代碼示例
測試數(shù)據(jù)
http://grouplens.org/datasets/movielens/
協(xié)同過濾推薦算法主要分為:
1、基于用戶。根據(jù)相鄰用戶,預測當前用戶沒有偏好的未涉及物品,計算得到一個排序的物品列表進行推薦
2、基于物品。如喜歡物品A的用戶都喜歡物品C,那么可以知道物品A與物品C的相似度很高,而用戶C喜歡物品A,那么可以推斷出用戶C也可能喜歡物品C。
不同的數(shù)據(jù)、不同的程序猿寫出的協(xié)同過濾推薦算法不同,但其核心是一致的:
1、收集用戶的偏好
1)不同行為分組
2)不同分組進行加權(quán)計算用戶的總喜好
3)數(shù)據(jù)去噪和歸一化
2、找到相似用戶(基于用戶)或者物品(基于物品)
3、計算相似度并進行排序。根據(jù)相似度為用戶進行推薦
本次實例過程:
1、初始化數(shù)據(jù)
獲取movies和ratings
轉(zhuǎn)換成數(shù)據(jù)userDict表示某個用戶的所有電影的評分集合,并對評分除以5進行歸一化
轉(zhuǎn)換成數(shù)據(jù)ItemUser表示某部電影參與評分的所有用戶集合
2、計算所有用戶與userId的相似度
找出所有觀看電影與userId有交集的用戶
對這些用戶循環(huán)計算與userId的相似度
獲取A用戶與userId的并集。格式為:{'電影ID',[A用戶的評分,userId的評分]},沒有評分記為0
計算A用戶與userId的余弦距離,越大越相似
3、根據(jù)相似度生成推薦電影列表
4、輸出推薦列表和準確率
#!/usr/bin/python3 # -*- coding: utf-8 -*- from numpy import * import time from texttable import Texttable class CF: def __init__(self, movies, ratings, k=5, n=10): self.movies = movies self.ratings = ratings # 鄰居個數(shù) self.k = k # 推薦個數(shù) self.n = n # 用戶對電影的評分 # 數(shù)據(jù)格式{'UserID:用戶ID':[(MovieID:電影ID,Rating:用戶對電影的評星)]} self.userDict = {} # 對某電影評分的用戶 # 數(shù)據(jù)格式:{'MovieID:電影ID',[UserID:用戶ID]} # {'1',[1,2,3..],...} self.ItemUser = {} # 鄰居的信息 self.neighbors = [] # 推薦列表 self.recommandList = [] self.cost = 0.0 # 基于用戶的推薦 # 根據(jù)對電影的評分計算用戶之間的相似度 def recommendByUser(self, userId): self.formatRate() # 推薦個數(shù) 等于 本身評分電影個數(shù),用戶計算準確率 self.n = len(self.userDict[userId]) self.getNearestNeighbor(userId) self.getrecommandList(userId) self.getPrecision(userId) # 獲取推薦列表 def getrecommandList(self, userId): self.recommandList = [] # 建立推薦字典 recommandDict = {} for neighbor in self.neighbors: movies = self.userDict[neighbor[1]] for movie in movies: if(movie[0] in recommandDict): recommandDict[movie[0]] += neighbor[0] else: recommandDict[movie[0]] = neighbor[0] # 建立推薦列表 for key in recommandDict: self.recommandList.append([recommandDict[key], key]) self.recommandList.sort(reverse=True) self.recommandList = self.recommandList[:self.n] # 將ratings轉(zhuǎn)換為userDict和ItemUser def formatRate(self): self.userDict = {} self.ItemUser = {} for i in self.ratings: # 評分最高為5 除以5 進行數(shù)據(jù)歸一化 temp = (i[1], float(i[2]) / 5) # 計算userDict {'1':[(1,5),(2,5)...],'2':[...]...} if(i[0] in self.userDict): self.userDict[i[0]].append(temp) else: self.userDict[i[0]] = [temp] # 計算ItemUser {'1',[1,2,3..],...} if(i[1] in self.ItemUser): self.ItemUser[i[1]].append(i[0]) else: self.ItemUser[i[1]] = [i[0]] # 找到某用戶的相鄰用戶 def getNearestNeighbor(self, userId): neighbors = [] self.neighbors = [] # 獲取userId評分的電影都有那些用戶也評過分 for i in self.userDict[userId]: for j in self.ItemUser[i[0]]: if(j != userId and j not in neighbors): neighbors.append(j) # 計算這些用戶與userId的相似度并排序 for i in neighbors: dist = self.getCost(userId, i) self.neighbors.append([dist, i]) # 排序默認是升序,reverse=True表示降序 self.neighbors.sort(reverse=True) self.neighbors = self.neighbors[:self.k] # 格式化userDict數(shù)據(jù) def formatuserDict(self, userId, l): user = {} for i in self.userDict[userId]: user[i[0]] = [i[1], 0] for j in self.userDict[l]: if(j[0] not in user): user[j[0]] = [0, j[1]] else: user[j[0]][1] = j[1] return user # 計算余弦距離 def getCost(self, userId, l): # 獲取用戶userId和l評分電影的并集 # {'電影ID':[userId的評分,l的評分]} 沒有評分為0 user = self.formatuserDict(userId, l) x = 0.0 y = 0.0 z = 0.0 for k, v in user.items(): x += float(v[0]) * float(v[0]) y += float(v[1]) * float(v[1]) z += float(v[0]) * float(v[1]) if(z == 0.0): return 0 return z / sqrt(x * y) # 推薦的準確率 def getPrecision(self, userId): user = [i[0] for i in self.userDict[userId]] recommand = [i[1] for i in self.recommandList] count = 0.0 if(len(user) >= len(recommand)): for i in recommand: if(i in user): count += 1.0 self.cost = count / len(recommand) else: for i in user: if(i in recommand): count += 1.0 self.cost = count / len(user) # 顯示推薦列表 def showTable(self): neighbors_id = [i[1] for i in self.neighbors] table = Texttable() table.set_deco(Texttable.HEADER) table.set_cols_dtype(["t", "t", "t", "t"]) table.set_cols_align(["l", "l", "l", "l"]) rows = [] rows.append([u"movie ID", u"Name", u"release", u"from userID"]) for item in self.recommandList: fromID = [] for i in self.movies: if i[0] == item[1]: movie = i break for i in self.ItemUser[item[1]]: if i in neighbors_id: fromID.append(i) movie.append(fromID) rows.append(movie) table.add_rows(rows) print(table.draw()) # 獲取數(shù)據(jù) def readFile(filename): files = open(filename, "r", encoding="utf-8") # 如果讀取不成功試一下 # files = open(filename, "r", encoding="iso-8859-15") data = [] for line in files.readlines(): item = line.strip().split("::") data.append(item) return data # -------------------------開始------------------------------- start = time.clock() movies = readFile("/home/hadoop/Python/CF/movies.dat") ratings = readFile("/home/hadoop/Python/CF/ratings.dat") demo = CF(movies, ratings, k=20) demo.recommendByUser("100") print("推薦列表為:") demo.showTable() print("處理的數(shù)據(jù)為%d條" % (len(demo.ratings))) print("準確率: %.2f %%" % (demo.cost * 100)) end = time.clock() print("耗費時間: %f s" % (end - start))
總結(jié)
以上就是本文關(guān)于python實現(xiàn)協(xié)同過濾推薦算法完整代碼示例的全部內(nèi)容,希望對大家有所幫助。感興趣的朋友可以繼續(xù)參閱本站:
python實現(xiàn)機械分詞之逆向最大匹配算法代碼示例
如有不足之處,歡迎留言指出。感謝朋友們對本站的支持!
相關(guān)文章
python實現(xiàn)將excel文件轉(zhuǎn)化成CSV格式
下面小編就為大家分享一篇python實現(xiàn)將excel文件轉(zhuǎn)化成CSV格式,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-03-03使用Pyinstaller轉(zhuǎn)換.py文件為.exe可執(zhí)行程序過程詳解
這篇文章主要介紹了使用Pyinstaller轉(zhuǎn)換.py文件為.exe可執(zhí)行程序過程詳解,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下2019-08-08在django view中給form傳入?yún)?shù)的例子
今天小編就為大家分享一篇在django view中給form傳入?yún)?shù)的例子,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2019-07-07python實現(xiàn)Scrapy爬取網(wǎng)易新聞
這篇文章主要介紹了python實現(xiàn)Scrapy爬取網(wǎng)易新聞,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2021-03-03深入解析PYTHON?虛擬機令人拍案叫絕的字節(jié)碼設(shè)計
這篇文章主要為大家介紹了PYTHON虛擬機中令人拍案叫絕的字節(jié)碼設(shè)計深入詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-04-04Python?turtle.right與turtle.setheading的區(qū)別講述
這篇文章主要介紹了Python?turtle.right與turtle.setheading的區(qū)別,本文以turtle.right為例給大家詳細介紹,需要的朋友可以參考下2022-03-03