1 Préparation initiale
Nettoyer les données, renommer les noms de colonnes
######### Classement Douban ##############
######### CF basé sur l'utilisateur ############# #
Sys.setlocale(category = "LC_ALL", locale = "Chinois")
nettoyer
rm(list=ls())
bibliothèque (règles)
##Construire des
données de matrice de modèle <- read.csv('testCF.csv',header = FALSE)
##Ajouter des noms de colonnes names
(data) <- c("uid","iid","pref")
Utilisez l'index de données au lieu du nom d'origine, l'index correspondant et le score sont combinés pour trouver la position correspondante dans la matrice à remplir
compter les utilisateurs
user <- unique(data KaTeX parse error: Expected 'EOF', got '#' at position 6: uid) #̲#Count the number of products (turn users and products to... iid))
uidx <- match( data KaTeX parse error : 'EOF' attendu, '#' obtenu en position 12 : uid, user) #̲Index iidx <-… iid, item) #Index
##Define storage matrix
M <- matrix(0, length(user) ,length (item))
i <- cbind(uidx, iidx, pref=data$pref) # Combinez l'index et le score correspondants pour trouver la position correspondante dans la matrice à remplir
dimnames(M)[[2]] <- item
##retourne la valeur de la matrice
M
2 Algorithme de similarité
Algorithme de similarité de distance euclidienne
ligne <- nrow(M) #matrice de
similarité utilisateur
s <- matrice(0,ligne,ligne)
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) ##Matrice triangulaire complète
w <- which(upper.tri(ts))
s[w] <- ts[w]
s ##Renvoyer la matrice de similarité utilisateur
s1<-s
Algorithme du voisin le plus proche à 3 utilisateurs
##Algorithme de voisinage utilisateur
Neighbor_num <- 2 ##Prenez les deux plus grands voisins
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]) # Trouver la ligne avec la plus grande similarité entre chaque utilisateur (le nombre de clients) neighbor[z1,][z2] <- m #This Remplir la position dans la table utilisateur adjacente s1[,z1][m]=0 #Définissez la valeur maximale à 0 pour trouver la valeur maximale dans la deuxième boucle } } voisin
4 Algorithmes de recommandation
Dans la recommandation, trouvez le premier utilisateur qui ressemble le plus à l'utilisateur 1 (les deux plus similaires sont l'utilisateur 4 et l'utilisateur 5), prenez d'abord l'utilisateur 4. Et prenez le film que l'utilisateur 1 n'a pas vu, mais que l'utilisateur 4 a regardé ( intersept prendre l'intersection).
row_num <- ncol(neighbor)
col_num <- ncol(M)
rcm <- matrix(0,row_num,col_num)
ruid=1 #Trouver l'utilisateur 1 en premier
N1 <- voisin[ruid,]
for(z1 in 1:length(N1)){ num <- intersect(which(M[ruid,]==0),which(M[N1 [z1],]!=0)) #Trouvez le premier utilisateur qui ressemble le plus à l'utilisateur 1 dans la recommandation (les deux plus similaires sont l'utilisateur 4 et l'utilisateur 5), prenez d'abord l'utilisateur 4. Et prenez l'utilisateur 1 qui n'a pas vu, mais les films regardés par l'utilisateur 4 (intersept). for(z2 in num){ rcm[z1,z2] = M[N1[z1],z2]*s[ruid,N1[z1]] #Note de l'utilisateur 4 pour le 4ème produit × Similitude de l'utilisateur 4 et de l'utilisateur 1 de } }
##输出推荐矩阵
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