Python實現基於使用者的協同過濾推薦

2021-10-25 17:49:59 字數 4446 閱讀 9083

協同過濾推薦系統在我們的日常生活之中無處不在,例如,在電子**購物,系統會根據使用者的記錄或者其他的資訊來推薦相應的產品給客戶,是一種智慧型的生活方式。之所以叫協同過濾,是因為在實現過濾推薦的時候是根據其他人的行為來做**的,基於相似使用者的喜好來實現使用者的喜好**。

舉例,如何協同過濾,來對使用者a進行電影推薦?

答:簡要步驟如下

具體實施步驟如何?

答:簡要步驟如下

(1)畫乙個大**,橫座標是所有的movie_id,縱座標所有的user_id,交叉處代表這個使用者喜愛這部電影

如上表:

橫座標,假設有10w部電影,所以橫座標有10w個movie_id,資料**自資料庫

縱座標,假設有100w個使用者,所以縱座標有100w個user_id,資料也來自資料庫

交叉處,「1」代表使用者喜愛這部電影,資料來自日誌

畫外音:什麼是「喜歡」,需要人為定義,例如瀏覽過,查詢過,點讚過,反正日誌裡有這些資料

(2)找到使用者a(user_id_1)的興趣愛好

如上表,可以看到,使用者a喜歡電影

(3)找到與使用者a(user_id_1)具有相同電影興趣愛好的使用者群體集合set

如上表,可以看到,喜歡的使用者,除了u1,還有

(4)找到該群體喜歡的電影集合set

如上表,具備相同喜好的使用者群裡,還喜好的電影集合是

畫外音:「協同」就體現在這裡。

具體實現步驟:

第一步:計算兩者之間的相似度

通常會先把二維**繪製在乙個圖中總,每個使用者資料表示乙個點。

度量相似度計算的方法:a.曼哈頓距離計算(計算迅速,節省時間)

b.歐氏距離計算(計算兩個點之間的直線距離)

資料預處理:

解壓讀取movies.csv和ratings.csv檔案

通過如下程式提取資料:

# -*- coding:utf-8 -*-

import pandas as pd

movies = pd.read_csv(r'e:\pycharmprojects\devtest\data\movies.csv')

ratings = pd.read_csv(r'e:\pycharmprojects\devtest\data\ratings.csv')

data = pd.merge(movies,ratings,on='movieid')

data[['userid','rating','movieid','title']].sort_values('userid').to_csv(r'e:\pycharmprojects\devtest\data\data.csv',index=false,header=none)

# -*- coding:utf-8 -*-

from math import sqrt

data = {}

with open(r'e:\pycharmprojects\devtest\data\data.csv', 'r', encoding='utf-8') as fi:

for line in fi:

item = line.strip().split(',')

if not item[0] in data.keys():

data[item[0]] =

else:

data[item[0]][item[3]] = item[1]

# print(data)

##皮爾遜相關係數

def pearson_sim(user1, user2):

user1_data = data[user1]

user2_data = data[user2]

distance = 0

common = {}

for key in user1_data.keys():

if key in user2_data.keys():

common[key] = 1

if len(common) == 0:

n = len(common) # 共同電影數目

# print(n, common)

##計算評分和

sum1 = sum([float(user1_data[movie]) for movie in common])

sum2 = sum([float(user2_data[movie]) for movie in common])

##計算評分平方和

sum1sq = sum([pow(float(user1_data[movie]), 2) for movie in common])

sum2sq = sum([pow(float(user2_data[movie]), 2) for movie in common])

##計算乘積和

psum = sum([float(user1_data[it]) * float(user2_data[it]) for it in common])

##計算相關係數

num = psum - (sum1 * sum2 / n)

den = sqrt((sum1sq - pow(sum1, 2) / n) * (sum2sq - pow(sum2, 2) / n))

if den == 0:

return 0

r = num / den

return r

##計算某個使用者與其他使用者的相似度

def top10_simliar(userid):

res =

for userid in data.keys():

#排除與自己計算相似度

if not userid == userid:

simliar = pearson_sim(userid, userid)

res.sort(key=lambda val: val[1])

return res[:4]

res = top10_simliar('1')

print(res)

##根據使用者推薦給其他人

def recommend(user):

top_sim_user = top10_simliar(user)[0][0]

items = data[top_sim_user]

recommendations =

for item in items.keys():

if item not in data[user].keys():

recommendations.sort(key=lambda val:val[1],reverse=true)

return recommendations[:10]

recommendations = recommend('1')

print(recommendations)

結果:

[('nutty professor ii: the klumps (2000)', '5'), ('"patriot', '5'), ('"silence of the lambs', '5'), ('titan a.e. (2000)', '5'), ('almost famous (2000)', '5'), ('dinosaur (2000)', '5'), ('mission: impossible 2 (2000)', '5'), ('star wars: episode i - the phantom menace (1999)', '5'), ('x-men (2000)', '5'), ('mission to mars (2000)', '5')]
##其他計算相似距離的

##歐式距離

def euclidean(user1,user2):

user1_data=data[user1]

user2_data=data[user2]

distance = 0

for key in user1_data.keys():

if key in user2_data.keys():

#注意,distance越大表示兩者越相似

distance += pow(float(user1_data[key])-float(user2_data[key]),2)

return 1/(1+sqrt(distance))#這裡返回值越小,相似度越大

參考:

協同過濾 基於使用者的協同過濾itemCF

基於使用者的協同過濾演算法也被稱為最近鄰協同過濾或knn k nearest neighbor,k最近鄰演算法 其核心思想就是,首先根據相似度計算出目標使用者的鄰居集合,然後用鄰居使用者評分的加權組合來為目標使用者作推薦。通常這些演算法都可以總結成三步 首先,使用使用者已有的評分來計算使用者之間的相...

基於使用者的協同過濾演算法

最近正在讀項亮博士的 推薦系統實踐 人民郵電出版社,這本書應當是目前國內為數不多的介紹推薦演算法的了。目前正在學習基於使用者的協同過濾演算法 usercf user based collaborative filtering 該演算法是推薦系統中最古老的演算法,標誌著推薦系統的誕生,該演算法在199...

基於使用者的協同過濾演算法

在乙個線上的個性化推薦系統中,當乙個使用者需要個性化推薦時,找到與使用者有相同的興趣愛好的使用者來進行推薦物品是乙個不錯的選擇。1 找到和目標使用者興趣相似的使用者集合。2 找到此相似集合中使用者沒有購買過,但是可能喜歡的商品進行推薦。步驟 1 對於相似使用者的查詢,就需要用乙個方法去衡量這個相似度...