1 初始准备

清理数据,重命名列名

######### Douban Ranking ##############
 ######### User based CF ##############Sys.setlocale(category = “LC_ALL”, locale = “Chinese”)
clean up
rm(list=ls())
library(arules)
##建立模型矩阵
 data <- read.csv(‘testCF.csv’,header = FALSE)
 ##增加列名
 names(data) <- c(“uid”,“iid”,“pref”)

使用数据索引代替原名称,相应的Index和评分结合起来,以便在矩阵中找到相应位置填充

计算用户数

user <- unique(dataKaTeX parse error: Expected 'EOF', got '#' at position 6: uid) #̲#计算产品数 (将用户和产品转…iid))
 uidx <- match(dataKaTeX parse error: Expected 'EOF', got '#' at position 12: uid, user) #̲Index 化 iidx <-…iid, item) #Index 化
 ##定义存储矩阵
 M <- matrix(0, length(user),length(item))
 i <- cbind(uidx, iidx, pref=data$pref) #将相应的Index和评分结合起来,以便在矩阵中找到相应位置填充

协同过滤算法Python代码import 协同过滤算法源码_数据分析


dimnames(M)[[2]] <- item

##返回矩阵值

M

协同过滤算法Python代码import 协同过滤算法源码_推荐算法_02

2 相似度算法

欧式距离相似度算法

row <- nrow(M)
#用户相似度矩阵

s <- matrix(0,row,row)

for(z1 in 1:row){
  for(z2 in 1:row){
    if(z1 < z2){
      ##可计算的列
      num <- intersect(which(M[z1,]!=0),which(M[z2,]!=0)) #在这里计算每一行和下一行,同时不为零的列
      
      sum <- 0
      for(z3 in num){
        sum <- sum+(M[z1,][z3] - M[z2,][z3])^2 #欧几里德距离的公式计算每一个产品和其他产品的相似度
      }
      
      s[z2,z1] <- length(num)/(1+sqrt(sum)) #求倒数,表示相关性,加1是为了防止0的出现
      
      ##对算法的阈值进行限制
      if(s[z2,z1] > 1) s[z2,z1] <- 1
      if(s[z2,z1] < -1) s[z2,z1] <- -1      
    }
  }
}

ts <- t(s) ##补全三角矩阵
w <- which(upper.tri(ts))
s[w] <- ts[w]
s ##返回用户相似度矩阵
s1<-s

协同过滤算法Python代码import 协同过滤算法源码_机器学习_03

3 用户近邻算法

##用户近邻算法
 Neighbor_num <- 2 ##取两个最大近邻
 row <- nrow(s1)
 neighbor <- matrix(0,row,Neighbor_num)
 for(z1 in 1:row){
 for(z2 in 1:Neighbor_num){
 m <- which.max(s1[,z1]) # 求每一个用户当中,相似度最大的在第几行(第几个客户)
 neighbor[z1,][z2] <- m #将该位置填写到相邻临近的用户表中
 s1[,z1][m]=0 #将该最大值设置为0,以便在第二次循环中找寻最大值
 }
 }
 neighbor

协同过滤算法Python代码import 协同过滤算法源码_推荐算法_04

4 推荐算法

在推荐中找到和用户1最相似第1个用户(两个最相似的分别是用户4和用户5),先取用户4.并且取用户1没有看过的,但是用户4看过的电影(intersept 取交集)。

row_num <- ncol(neighbor)
 col_num <- ncol(M)
 rcm <- matrix(0,row_num,col_num)ruid=1 #先找用户1
 N1 <- neighbor[ruid,]
 for(z1 in 1:length(N1)){
 num <- intersect(which(M[ruid,]==0),which(M[N1[z1],]!=0)) #在推荐中找到和用户1最相似第1个用户(两个最相似的分别是用户4和用户5),先取用户4.并且取用户1没有看过的,但是用户4看过的电影(intersept 取交集)。
 for(z2 in num){
 rcm[z1,z2] = M[N1[z1],z2]*s[ruid,N1[z1]] #用户4的对于第4个产品的评分×用户4与用户1的相似度
 }


}

##输出推荐矩阵
sum <- colSums(rcm)
s2 <- matrix(0,2,col_num)
for(z1 in 1:length(N1)){
  num <- intersect(which(colSums(rcm)!=0),which(M[N1[z1],]!=0))
  for(z2 in num){
    s2[1,][z2] <- s2[1,][z2]+s[ruid,N1[z1]] # 计算推荐矩阵中分母的部分
    s2[2,][z2] <- s2[2,][z2]+1 #防止出现0的情况
  }
} 
m
s2[,which(s2[2,]==1)]=10000 #防止只有一个用户与之相似的情况出现,避免了一个人多个账号产生的极高相似度的错误推荐。
s2 <- s2[-2,]

r2 <- matrix(0,n,2)
rr <- sum/s2
item <- dimnames(M)[[2]] #在dimnames(M)list 中取名字
str(dimnames(M))

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

协同过滤算法Python代码import 协同过滤算法源码_推荐算法_05