python實(shí)現(xiàn)協(xié)同過濾推薦算法完整代碼示例
測試數(shù)據(jù)
http://grouplens.org/datasets/movielens/

協(xié)同過濾推薦算法主要分為:
1、基于用戶。根據(jù)相鄰用戶,預(yù)測當(dāng)前用戶沒有偏好的未涉及物品,計(jì)算得到一個(gè)排序的物品列表進(jìn)行推薦
2、基于物品。如喜歡物品A的用戶都喜歡物品C,那么可以知道物品A與物品C的相似度很高,而用戶C喜歡物品A,那么可以推斷出用戶C也可能喜歡物品C。
不同的數(shù)據(jù)、不同的程序猿寫出的協(xié)同過濾推薦算法不同,但其核心是一致的:
1、收集用戶的偏好
1)不同行為分組
2)不同分組進(jìn)行加權(quán)計(jì)算用戶的總喜好
3)數(shù)據(jù)去噪和歸一化
2、找到相似用戶(基于用戶)或者物品(基于物品)
3、計(jì)算相似度并進(jìn)行排序。根據(jù)相似度為用戶進(jìn)行推薦
本次實(shí)例過程:
1、初始化數(shù)據(jù)
獲取movies和ratings
轉(zhuǎn)換成數(shù)據(jù)userDict表示某個(gè)用戶的所有電影的評(píng)分集合,并對(duì)評(píng)分除以5進(jìn)行歸一化
轉(zhuǎn)換成數(shù)據(jù)ItemUser表示某部電影參與評(píng)分的所有用戶集合
2、計(jì)算所有用戶與userId的相似度
找出所有觀看電影與userId有交集的用戶
對(duì)這些用戶循環(huán)計(jì)算與userId的相似度
獲取A用戶與userId的并集。格式為:{'電影ID',[A用戶的評(píng)分,userId的評(píng)分]},沒有評(píng)分記為0
計(jì)算A用戶與userId的余弦距離,越大越相似
3、根據(jù)相似度生成推薦電影列表
4、輸出推薦列表和準(zhǔn)確率
#!/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
# 鄰居個(gè)數(shù)
self.k = k
# 推薦個(gè)數(shù)
self.n = n
# 用戶對(duì)電影的評(píng)分
# 數(shù)據(jù)格式{'UserID:用戶ID':[(MovieID:電影ID,Rating:用戶對(duì)電影的評(píng)星)]}
self.userDict = {}
# 對(duì)某電影評(píng)分的用戶
# 數(shù)據(jù)格式:{'MovieID:電影ID',[UserID:用戶ID]}
# {'1',[1,2,3..],...}
self.ItemUser = {}
# 鄰居的信息
self.neighbors = []
# 推薦列表
self.recommandList = []
self.cost = 0.0
# 基于用戶的推薦
# 根據(jù)對(duì)電影的評(píng)分計(jì)算用戶之間的相似度
def recommendByUser(self, userId):
self.formatRate()
# 推薦個(gè)數(shù) 等于 本身評(píng)分電影個(gè)數(shù),用戶計(jì)算準(zhǔn)確率
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:
# 評(píng)分最高為5 除以5 進(jìn)行數(shù)據(jù)歸一化
temp = (i[1], float(i[2]) / 5)
# 計(jì)算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]
# 計(jì)算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評(píng)分的電影都有那些用戶也評(píng)過分
for i in self.userDict[userId]:
for j in self.ItemUser[i[0]]:
if(j != userId and j not in neighbors):
neighbors.append(j)
# 計(jì)算這些用戶與userId的相似度并排序
for i in neighbors:
dist = self.getCost(userId, i)
self.neighbors.append([dist, i])
# 排序默認(rèn)是升序,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
# 計(jì)算余弦距離
def getCost(self, userId, l):
# 獲取用戶userId和l評(píng)分電影的并集
# {'電影ID':[userId的評(píng)分,l的評(píng)分]} 沒有評(píng)分為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)
# 推薦的準(zhǔn)確率
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("準(zhǔn)確率: %.2f %%" % (demo.cost * 100))
end = time.clock()
print("耗費(fèi)時(shí)間: %f s" % (end - start))
總結(jié)
以上就是本文關(guān)于python實(shí)現(xiàn)協(xié)同過濾推薦算法完整代碼示例的全部內(nèi)容,希望對(duì)大家有所幫助。感興趣的朋友可以繼續(xù)參閱本站:
python實(shí)現(xiàn)機(jī)械分詞之逆向最大匹配算法代碼示例
K-近鄰算法的python實(shí)現(xiàn)代碼分享
詳解K-means算法在Python中的實(shí)現(xiàn)
如有不足之處,歡迎留言指出。感謝朋友們對(duì)本站的支持!
相關(guān)文章
python實(shí)現(xiàn)將excel文件轉(zhuǎn)化成CSV格式
下面小編就為大家分享一篇python實(shí)現(xiàn)將excel文件轉(zhuǎn)化成CSV格式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2018-03-03
python二維碼操作:對(duì)QRCode和MyQR入門詳解
今天小編就為大家分享一篇python二維碼操作:對(duì)QRCode和MyQR入門詳解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2019-06-06
使用Pyinstaller轉(zhuǎn)換.py文件為.exe可執(zhí)行程序過程詳解
這篇文章主要介紹了使用Pyinstaller轉(zhuǎn)換.py文件為.exe可執(zhí)行程序過程詳解,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-08-08
在django view中給form傳入?yún)?shù)的例子
今天小編就為大家分享一篇在django view中給form傳入?yún)?shù)的例子,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2019-07-07
python實(shí)現(xiàn)Scrapy爬取網(wǎng)易新聞
這篇文章主要介紹了python實(shí)現(xiàn)Scrapy爬取網(wǎng)易新聞,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-03-03
深入解析PYTHON?虛擬機(jī)令人拍案叫絕的字節(jié)碼設(shè)計(jì)
這篇文章主要為大家介紹了PYTHON虛擬機(jī)中令人拍案叫絕的字節(jié)碼設(shè)計(jì)深入詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-04-04
Python?turtle.right與turtle.setheading的區(qū)別講述
這篇文章主要介紹了Python?turtle.right與turtle.setheading的區(qū)別,本文以turtle.right為例給大家詳細(xì)介紹,需要的朋友可以參考下2022-03-03

