一文深入理解協同過濾

2021-09-13 14:46:13 字數 4873 閱讀 6751

寫在之前…

從這篇文章開始,我的下乙個演算法職業生涯方向將專注於推薦演算法…

看了那麼多書和**,還是peter 的那本《機器學習實戰》最為經典,說實話很多中國人寫的書確實不怎麼樣…

那麼,開始吧.本文**從趙志勇的那本書上修改而來,估計趙志勇的那篇文章也是從《機器學習實戰》那本書修改而來,反正總是修改修改…

那就上**吧!,talk is cheap ,show me the code .

# coding:utf-8

'''date:20180624

@author: luogan

'''import numpy as np

import pandas

from numpy import mat,eye

from numpy import linalg

def fetch_data():

dat=mat([[4., 3., 0., 5., 0.],

[5., 0., 4., 4., 0.],

[4., 0., 5., 0., 3.],

[2., 3., 0., 1., 0.],

[0., 4., 2., 0., 5.]])

return dat

def cos_sim(x, y):

'''余弦相似性

input: x(mat):以行向量的形式儲存,可以是使用者或者商品

y(mat):以行向量的形式儲存,可以是使用者或者商品

output: x和y之間的余弦相似度

'''numerator = x * y.t # x和y之間的額內積

denominator = np.sqrt(x * x.t) * np.sqrt(y * y.t)

return (numerator / denominator)[0, 0]

def similarity(data):

'''計算矩陣中任意兩行之間的相似度

input: data(mat):任意矩陣

output: w(mat):任意兩行之間的相似度

'''m = np.shape(data)[0] # 使用者的數量

# 初始化相似度矩陣

w = np.mat(np.zeros((m, m)))

for i in range(m):

for j in range(i, m):

if j != i:

# 計算任意兩行之間的相似度

w[i, j] = cos_sim(data[i, ], data[j, ])

w[j, i] = w[i, j]

else:

w[i, j] = 0

return w

def user_based_recommend(data, w, user):

'''基於使用者相似性為使用者user推薦商品

input: data(mat):使用者商品矩陣

w(mat):使用者之間的相似度

user(int):使用者的編號

output: predict(list):推薦列表

'''m, n = np.shape(data)

interaction = data[user, ] # 使用者user與商品資訊

# 1、找到使用者user沒有互動過的商品

not_inter =

for i in range(n):

if interaction[0, i] == 0: # 沒有互動的商品

# 2、對沒有互動過的商品進行**

#print('not_inter=',not_inter)

predict={}

dd=np.array(data)

ww=np.array(w)

if len(not_inter)>0:

for i in not_inter:

#print('ww[:,user]=',ww[:,user])

#print('dd[:,i].t',dd[:,i].t)

predict[i]=ww[:,user]@dd[:,i].t

#print(predict)

return predict

def top_k(predict, k):

'''為使用者推薦前k個商品

input: predict(list):排好序的商品列表

k(int):推薦的商品個數

output: top_recom(list):top_k個商品

'''pp=pandas.series(predict)

pp1=pp.sort_values(ascending=false)

#top_recom =

len_result = len(predict)

if k>=len_result:

return pp1.iloc[:k]

else:

return pp1

def svd(data):

u,sigma,vt=linalg.svd(data)

sig3=mat(eye(3)*sigma[:3])

fea_mat=data.t*u[:,:3]*sig3.i

return fea_mat

def normalize(w):

w=np.array(w)

#print(w)

dim=len(w)

ww=for i in range(dim):

d=w[i]

m=for k in range(len(d)):

ssm=sum(m)

#print('ssm=',ssm)

for j in range(len(m)):

m[j]=d[j]/ssm

return mat(ww)

data = fetch_data()

print('僅僅採用協同過濾演算法')

print('only use collaborative')

w_initial=similarity(data)

# 3、利用使用者之間的相似性進行推薦

#print ("------------ 3. predict ------------" )

predict = user_based_recommend(data, w_initial, 0)

# 4、進行top-k推薦

#print ("------------ 4. top_k recommendation ------------")

top_recom = top_k(predict, 1)

print ('top_recom=',top_recom)

print('採用協同過濾演算法+相似度矩陣的歸一化')

print(' use collaborative and normalize')

w_initial=similarity(data)

w_initial_normal=normalize(w_initial)

predict = user_based_recommend(data, w_initial_normal, 0)

top_recom = top_k(predict, 1)

print ('top_recom=',top_recom)

print('採用協同過濾演算法+svd矩陣分解')

print('use collaborative and svd')

data1=svd(data)

w_svd= similarity(data1)

predict = user_based_recommend(data, w_svd, 0)

top_recom = top_k(predict, 1)

print ('top_recom=',top_recom)

print('採用協同過濾演算法+svd矩陣分解'+'相似度矩陣的歸一化')

print('use collaborative and svd and normalize')

data1=svd(data)

w_svd= similarity(data1)

w_svd_normal=normalize(w_svd)

predict = user_based_recommend(data, w_svd_normal, 0)

top_recom = top_k(predict, 1)

print ('top_recom=',top_recom)

僅僅採用協同過濾演算法

top_recom= 2 5.103039

4 2.224911

dtype: float64

採用協同過濾演算法+相似度矩陣的歸一化

top_recom= 2 2.592621

4 1.398861

dtype: float64

採用協同過濾演算法+svd矩陣分解

top_recom= 2 2.555181

4 1.241427

dtype: float64

採用協同過濾演算法+svd矩陣分解相似度矩陣的歸一化

top_recom= 2 1.687669

4 0.818257

dtype: float64

當我們僅僅採用協同過濾,不對結果採用任何處理時,第乙個使用者的第三的商品的推薦,結果是5.1,對比其他三種演算法,可以看出這個結果是有問題的,其他三種演算法的推薦值都在2左右.

svd 和相似度矩陣歸一化,在某種意義上是等價的,這段時間看了30多篇文獻, 協同過濾的變種和技巧方面還有很多種.下次繼續更....

結論:在用協同過濾做推薦時,必須採用歸一化或svd,或其他技巧…

posted on 2018-06-24 16:23收藏

再理解協同過濾演算法

協同過濾演算法是推薦系統中最古老,也是最簡單高效的推薦演算法。簡單說協同過濾就是根據以往的使用者產生的資料分析,對使用者的新行為進行匹配分析來給使用者推薦使用者最有可能感興趣的內容。協同過濾演算法是為了解決長尾現象,也就是說推薦系統是為了解決長尾現象而誕生的。因為在之前在有限的空間 如 書店的書架 ...

多執行緒安全問題 一文深入理解以及解決方案

執行緒同步 執行緒安全是多執行緒程式設計時的電腦程式 中的乙個概念。在擁有共享資料的多條執行緒並行執行的程式中,執行緒安全的 會通過同步機制保證各個執行緒都可以正常且正確的執行,不會出現資料汙染等意外情況。package thread.safe auther carroll date 2020 4 ...

深入理解REST(一)

1.什麼是 rest rest是representational state transfer的縮寫,於 r.fielding 的一篇博士 architectural styles and the design of network based software architectures rest...