R语言数据挖掘实践——电影推荐系统综合实例(二)
我们结合movieLens数据集,对User-based kNN进行实现,Item-based kNN同理可得。首先,我们来简要说明
本次应用User-based kNN算法探究MovieLens数据集的整体思路。
目的:预测某位用户(其用户ID记为U0)对某部电影(其电影ID记为M0)的评分。
步骤1:选择用户U0已经给出评分的若干电影,假设选择n部,并获取其电影ID,记为M1~Mn;
步骤2:再找出对电影M0已经进行过评分的用户,假设有m位符合得用户,并获取其用户ID,记为U1~Um;
步骤3:利用以上获取的三组ID,构造训练集data_train和训练集data_test,结构如下图:
步骤4:将相应的训练集与测试集按顺序放入knn()函数,即可预测出用户U0对电影M0的评分值。
数据集信息
下面我们使用R语言来实现,首先要做的就是读取数据和查看数据基本信息,代码如下:
>#读取数据
>data <- read.table(\"ml-100k/u.data\")
>#删除其中不需要使用的第4列,即时间戳(timestamp)变量
> data <- data[,-4]
>#命名data的各变量名
> names(data) <- c(\"userid\
> head(data)
userid itemid rating
1 196 242 3
2 186 302 3
3 22 377 1
4 244 51 2
5 166 346 1
6 298 474 4
>#显示维度
> dim(data)
[1] 100000 3
从输出结果看,我们知道该数据集data共有3个变量,正如上一章介绍的,分别为用户ID、电影ID,及评分,且共计10万条数据。
MovieLens_KNN函数的输入输出
为了使程序可反复使用,我们来动手编写一个专门用于实现“预测某位用户U0对某部电影M0评分值”的函数——MovieLens_KNN()。
下面先展示出函数的参数设置及运行结果,有一个输入到输出的直观印象后,我们再来逐步讲解实现这一过程的函数代码。
> MovieLens_KNN(Userid=1,Itemid=61,n=50,K=10)
......
$`True Rating:`
[1] 4
$`Predict Rating:`
[1] 3
Levels: 1 2 3 4 5
$`User ID:`
[1] 1
$`Item ID:`
[1] 61
如上,我们首先来看4个参数,其中Userid为想要预测的那位用户的ID,即U0;Itemid为想要预测的电影ID,即M0;而n为我们想要选择的用户U0已给出评分电影的个数;K为kNN算法中参与判别最近邻样本的个数。
上面的输出结果就是有Userid=1,Itemid=61,n=50,K=10的参数设置得到的,即以预测用户1对电影61的评分为目的,且选择了50部用户1已给出评分的电影,K的值为10。
现在来看输出结果,其有data_all,True Rating、Predict Rating、User ID及Item ID这5项。其中data_all是根据原数据文件u.data以及参数设定值在函数中新构造的数据集,它的结构与上面图片中的结构是一直的。第一行数据为待评分用户,这里即为用户1的用户ID(userid)、对待评分电影61的实际评分值(unknown_itemid_61)以及对电影94(itemid_94)、40(itemid_40)等50部电影的评分值。从第二行起到最后,为对电影61已经评分的m位用户的相应信息,而这里的m即为58。最终放入knn()函数中的训练集、测试集都来自该data_all数据集。按照图中的表结构划分所得。
而True Rating、Predict Rating则分别存放了待预测评分值的真实值和knn()函数所得的预测值,在上面的一次实现中,两者都为4,即预测值与真实值相同,用户1对电影61的评分是4分,是比较喜欢的。
MovieLens_KNN函数的编写
我们首先将各参数单独设定如下,然后逐步查看函数各部分的输出结果。
>Userid=1;Itemid=61;n=50;K=10
接着最重要的就是给出函数的名称MovieLens_KNN,及各参数名称和输入顺序,代码如下:
MovieLens_KNN <- function(Userid,Itemid,n,K){
#所有代码逻辑在这里继续
}
我们先执行整体思路的步骤1,来分别获取U0、M0及M1-Mn。对于程序代码,我们得到sub,表示待预测用户U0在数据集中各条信息所在的行标签;sub_n表示随机抽出的n个U0已评分电影M1-Mn的行标签;known_itemid表示U0已评分电影M1-Mn的电影ID;unknown_itemid表示待预测电影M0的ID号。
>#获取待预测用户U0在数据集中各条信息所在的行标签,存于sub
> sub <- which(data$userid==Userid)
> #获取随机抽出的n个U0已评分电影M1-Mn的行标签,存于sub_n
> if(length(sub) >=n) sub_n <- sample(sub,n)
> if(length(sub) < n) sub_n <- sample(sub, length(sub))
> #获取U0已评分电影M1-Mn的电影ID
> known_itemid <- data$itemid[sub_n]
> #获取待预测电影M0的ID号
> unknown_itemid <- Itemid
然后执行步骤2,找出已经对电影M0做出评分的古董用户,即前面所说的U1-Um,在程序中,我们将这m位用户的ID存于user中。
> #获取已评价电影M0的用户ID,存于user
> unknown_sub <- which(data$itemid==unknown_itemid)
> user <- data$userid[unknown_sub[-1]]
接着,我们开始构造最重要的data_all数据集。
> #设置data.all的行数、列数,所有值暂取0
> data_all <- matrix(0,1+length(user),2+length(known_itemid))
> data_all <- data.frame(data_all)
> #对data.all的各变量进行命名
> names(data_all) <-
c(\"userid\
> item <- c(unknown_itemid,known_itemid)
> #对data.all中的userid变量赋值
> data_all$userid <- c(Userid,user)
基本框架有了之后,最重要的就是对data_all数据集的主体部分进行赋值,这里通过
两层循环实现。
考虑到并不是我们所选出的对电影M0已评分的m位用户都对M1-Mn这n部电影同样做出了评分,即data_all中部分数据很可能是缺失的。因此,需要加一条判断语句,仅对data_all中有对应取值的位置赋值,缺失的位置则取0。
> #对data_all按行进行外层循环
>for(i in 1:nrow(data_all)) {
+ data_temp <- data[which(data$userid==data_all$userid[i]),]
+ #对data_all按列进行内层循环
+ for(j in 1:length(item)) {
+ #判断该位置是否有取值
+ if(sum(as.numeric(data_temp$itemid==item[j])) !=0) {
+ data_all[i,j+1] <- data_temp$rating[which(data_temp$itemid==item[j])]
+ }
+ }
+ }
然后根据data_all,从中分割出用于knn()参数设置的训练集与测试集。
> #获取测试集的已知部分
> data_test_x <- data_all[1,c(-1,-2)]
> #获取测试集的待预测值
> data_test_y <- data_all[1,2]
> #获取训练集的已知部分
> data_train_x <- data_all[-1,c(-1,-2)]
> #获取训练集的待预测值
> data_train_y <- data_all[-1,2]
> dim(data_test_x)
> length(data_test_y)
> dim(data_train_x)
> length(data_train_y)
最后,就是将相应部分一一放入knn()函数中,并将MovieLens_KNN()中参数K的值赋给knn()中的参数k。
> #进行knn判别
> fit <- knn(data_train_x,data_test_x,cl=data_train_y,k=K)
> #设置各项输出结果
> list(\"data_all:\"=data_all,\"True Rating:\"=data_test_y,\"Predict Rating:\"=fit,\"User ID:\"=Userid,\"Item ID:\"=Itemid)
至此,函数编写完毕,每次运行仅需以MovieLens_KNN (Userid,Itemid,n,K)格式给出4个参数的取值即可得到相应的结果。
下面,我们简单利用MovieLens_KNN()函数来看一看用户1对电影1至电影20这20部电影的评分情况。
通过u.item文件,我们知道这20部电影依次为Toy Story(玩具总动员)、GoldenEye(黄金眼)、Four Rooms(疯狂终结者)等。
> user1<-NULL
> for(Item in 1:20){
+ user1 <- c(user1, MovieLens_KNN(Userid=1,Itemid=Item, n=50, K=10)$'True Rating:')
> }
> user1
[1] 5 3 4 3 3 5 4 1 5 3 2 5 5 5 5 5 3 4 5 4
运行结果,我们预测出了对这20部电影,用户1可能给出的评分情况,且由下面这条代码,我们知道该用户喜欢第1、6、9、12、13~16、19这9部电影。
> which(user1==5)
[1] 1 6 9 12 13 14 15 16 19
另外,MovieLens_KNN()函数仅是出于最简单直观的方式实现了运用kNN原理对数据集MovieLens进行探究。我们也可以将u.item及u.user文件纳入考虑,比如加入用户的北京变量(性别、年龄)、电影的北京变量(类型、上映年份)等;又或者在结果形式上更优,输出某用户所偏好的背景信息,如下载地址、相关电影推荐等项目。
因篇幅问题不能全部显示,请点此查看更多更全内容
Copyright © 2019- huatuoyibo.net 版权所有 湘ICP备2023021910号-2
违法及侵权请联系:TEL:199 1889 7713 E-MAIL:2724546146@qq.com
本站由北京市万商天勤律师事务所王兴未律师提供法律服务