用R语言实现knn算法,步骤如下:
一、加载R包
library(kknn)
library(sampling)
library(class)
kknn是用来提供数据集和加权
knn算法函数的,
sampling是用来提供抽样算法函数的,
class是用来提供
knn算法函数的。
如果不能加载上面几个包请先下载。
二、准备数据
我用的数据是kknn包自带的数据集miete,可以通过几个不同的函数查看数据集miete的属性。
data(miete)
head(miete)
dim(miete)
str(miete)
先去掉第1、3、12列数据:
# 去掉第1、3、12列数据
miete = miete[, -c(1, 3, 12)]
需要用来做分类的列是miete$nmkat,通过函数table(miete$nmkat)可以看到,此列属性共分为5类,分别标记为1、2、3、4、5,每一类所包含的对象大概都是200多一点,如下图:
所以我们可以取三分之二的数据作为训练集,三分之一的数据作为测试集。所以五类数据每一类的数据各随机取三分之二,抽样为不放回抽样。
n = round(2 / 3 * nrow(miete) / 5)
sub_train = strata(miete,
stratanames = "nmkat",
size = rep(n, 5),
method = "srswor")
n是五类数据每一类应该抽取的数据个数,算出来是144个。
sub_train里的数据是需要抽取出来的列的序号,通过方法:
# 构造训练集
data_train = miete[sub_train$ID_unit, ]
# 构造测试集
data_test = miete[-sub_train$ID_unit, ]
分别取出训练集和测试集。
选取数据之前也可以对数据进行归一化处理:
# 函数归一化
normalize = function(x) {
return((x - min(x)) / (max(x) - min(x)))
}
ix = c(1, 8, 10)
miete[, ix] = as.data.frame(lapply(miete[, ix], normalize))
对数据集的第一列、第八列、第十列做归一化处理。
三、实现knn算法
fit_pre = knn(data_train[, -12], data_test[, -12], cl = data_train[, 12])
训练集和测试集用去掉第12列的其余属性作为分类依据,以训练集的第十二列作为分类的目标,获取测试集的分类结果fit_pre。
把得出来的训练集结果fit_pre和真实的训练集data_test做对比:
table(data_test$nmkat, fit_pre)
结果如下:
如果不够直观,还可以计算一下判断准确率:
correct = sum(as.numeric(fit_pre)==as.numeric(data_test$nmkat))/nrow(data_test)
得出准确率0.4751381。
这个准确率是k=1时的准确率,knn函数未设置k时,k的默认值是1,如果想测试不同k值得准确率,可以设置循环求k=1:20的准确率。
correct = rep(0,20)
for(i in 1:20){
fit_pre = knn(data_train[, -12], data_test[, -12], cl = data_train[, 12],k=i)
correct[i] = sum(as.numeric(fit_pre)==as.numeric(data_test$nmkat))/nrow(data_test)
}
四、实现有权重的knn算法(kknn)
fit_kknn = kknn(nmkat~.,data_train,data_test[,-12],k=1)
fit = fitted(fit_kknn)
table(data_test$nmkat,fit)
结果如下:
得出分类的准确率为0.5138122。
当然,也可以让k取不同的值观察分类准确率最高时,k的值为多少。
六、最后
以上,为knn算法的R语言实现过程,如果读者有什么疑问或者意见建议,欢迎留言。