基於pearson(皮爾遜)相似度的使用者推薦演算法
最近因為寫一些資料分析報告,把寫部落格的進度耽誤了一點,不過不要緊,我最近優化了一下做出的推薦演算法,用pearson相似度替換了歐氏距離相似度,優化了推薦演算法程式碼,另外將700多個使用者的推薦投資品迴圈計算了。
先說一下pearson相似度:
pearson相似度與歐式距離相似度的最大區別在於它比歐式距離更重視資料集的整體性;因為pearson相似度計算的是相對距離,歐式距離計算的是絕對距離。
就實際應用來說,有不同量綱和單位的資料集適合使用pearson相似度來計算,相同量綱和單位的資料集適合使用歐氏距離。
因為目前我使用的資料集都是投資者與投資品的匹配關係,量綱是相同的,所以使用pearson相似度計算的推薦結果與歐式距離計算的推薦結果是一致的。
好了,言歸正傳,我們來看一下pearson相似度的真面目吧,實際專案中程式碼如下:
#pearson相似度演算法,按行計算與其他使用者的相似度矩陣
PearsonDistanceSimilarity<-function(M){
row<-nrow(M)
s<-matrix(0, row, row)
for(z1 in 1:row){
for(z2 in 1:row)
try({if(z1!=z2){
s[z1,z2]<-cor(M[z1,],M[z2,])
}
else {s[z1,z2]<-0}
},silent = T)
}
s
}
因為之前的文章中,我們已經將投資者與投資品的喜好矩陣M搭建好了,所以這裡我直接呼叫了它。
然後我建立了一個行列均為使用者數(也就是row)的空矩陣用來放置我計算的相似度結果。
然後建立了一個for迴圈計算每一行與其他行的pearson相似度,並寫入對應的矩陣集,如第一行與第七行的相似度,直接寫入矩陣第一行第七列;其中如果計算本行與本行的相似度,直接取值為0,因為不能根據自己的投資行為給自己推薦投資品,如第二行與第二行計算相似度,直接設定為0。
在這裡我普及一下pearson相似度的計算方法:
在R裡面提供了cor函式可以直接計算該值。
然後我又優化了一下推薦演算法的程式碼,主要是去掉了多餘的程式碼,具體程式碼如下:
UserBasedRecommender<-function(uid,n,M,S,N){
row<-ncol(N)
col<-ncol(M)
r<-matrix(0, row, col)
N1<-N[uid,]
for(z1 in 1:length(N1)){
num<-intersect(which(M[uid,]==0),which(M[N1[z1],]!=0)) #可計算的列
# print(num)
for(z2 in num){
# print(paste("for:",z1,N1[z1],z2,M[N1[z1],z2],S[uid,N1[z1]]))
r[z1,z2]=M[N1[z1],z2]*S[uid,N1[z1]]
}
}
sum<-colSums(r)
s2<-matrix(0, 1, col)
for(z1 in 1:length(N1)){
num<-intersect(which(colSums(r)!=0),which(M[N1[z1],]!=0))
for(z2 in num){
s2[1,][z2]<-s2[1,][z2]+S[uid,N1[z1]]
}
}
r2<-matrix(0, n, 2)
rr<-sum/s2
item <-dimnames(M)[[2]]
for(z1 in 1:n){
w<-which.max(rr)
if(rr[w]>0.5){
r2[z1,1]<-item[which.max(rr)]
r2[z1,2]<-as.double(rr[w])
rr[w]=0
}
}
r2
}
相比上次說明的推薦演算法語句(具體請看:http://blog.csdn.net/qq_28887735/article/details/51985729),我去掉了s2矩陣的第二行。
好了,這次的推薦結果如何呢?我給大家截個圖:
使用歐式距離計算相似度,對本資料集來說,共有245個投資者可以找到有效的推薦產品;
其中5個投資者推薦了3個投資品,180個投資者推薦了2個投資品,60個投資者推薦了1個投資品;
使用皮爾遜相似度演算法,對本資料集來說,共有85個投資者可以找到有效的推薦產品;
其中51個投資者推薦了3個投資品,34個投資者推薦了2個投資品。
整體來說,在相同初始值下,歐氏距離計算相似度,可以增加推薦廣度;皮爾遜演算法計算相似度,可以增加推薦深度。
另外我的資料集量綱一致,可能會對此結果有部分影響,僅供參考,大家如果有新的想法可直接與我聯絡,一起實踐更容易獲得真知。