class 包中的 knn 系列函数
函数功能
对测试集的每一行,去找训练集里欧式距离最近的 k 行,利用草根民主法,决定测试集该行的类别。
class 包中还有两个和 knn 相关的函数:knn1, knn.cv
这三个包处理的问题分别是:
- knn k-Nearest Neighbour Classification
- knn1 1-nearest neighbour classification
- knn.cv k-Nearest Neighbour Cross-Validatory Classification
函数参数说明
- knn 的函数形式是 knn(train, test, cl, k = 1, l = 0, prob = FALSE, use.all = TRUE)
重要的参数如下:
- train 训练集数据,可以是矩阵或者数据框类型
- test 测试集数据,可以是矩阵或者数据框类型
- cl 训练集对应的真实分类数据,应该是因子类型的向量
- k 选择的近邻个数
knn1 的函数形式是 knn1(train, test, cl),即 knn 中选择
k = 1
的情况,因此 knn1 是 knn 的一个退化情况knn.cv 的函数形式是 knn.cv(train, cl, k = 1, l = 0, prob = FALSE, use.all = TRUE),其使用的方法是 leave-one-out cross validation。即所有的样本点都算到训练集中去,不设置测试集。对每个训练集中的样本点,都使用剩余的样本点中的 k 个最近邻来进行投票,从而决定该样本点的分类。
函数返回值说明
该系列函数返回一个因子向量,是测试集对应的分类(在 knn.cv 中是训练集对应的分类)
函数使用示例
数据集情况
我们使用 R 自带的 iris3
数据集,先看看数据大致情况
1 | class(iris3) |
1 | ## [1] "array" |
1 | dim(iris3) |
1 | ## [1] 50 4 3 |
数据是以三维数组的形式存放,第三维度即3种鸢尾属植物,对于每一种植物,我们采集了4个特征,分别是
-Sepal.Length 花萼长度
-Sepal.Width 花萼宽度
-Petal.Length 花瓣长度
-Petal.Width 花瓣宽度
每种植物,我们采集了50个样本
数据集处理
我们对每种植物各选择25个样本,组成训练集,因此训练集的大小是75个样本
1 | train <- rbind(iris3[1:25,,1], iris3[1:25,,2], iris3[1:25,,3]) |
同样,每种植物剩下的25个样本,组合起来,作为测试集
1 | test <- rbind(iris3[26:50,,1], iris3[26:50,,2], iris3[26:50,,3]) |
再准备好训练集的分类数据向量,要求是因子类型,所以要转化一下
1 | cl <- factor(c(rep("s",25), rep("c",25), rep("v",25))) |
使用 knn 预测
最后,使用 knn 函数,选择最邻近的 3 个样本点来投票
1 | library(class) |
1 | ## [1] s s s s s s s s s s s s s s s s s s s s s s s s s c c v c c c c c v c |
我们可以看一下正确率如何
1 | 1 - sum(cl != final)/length(cl) |
1 | ## [1] 0.9333333 |
使用 knn1 预测
如果使用 knn1 函数进行预测,则选择的就是最近的一个样本点来直接做决定
1 | final1 <- knn1(train, test, cl) |
1 | ## [1] 0.9466667 |
可以看到,knn1 在本例中的正确率要高于 k = 3 时的 knn
使用 knn.cv 预测
由于在 knn.cv 中不设置测试集,所以要把所有的样本点都放到训练集中去,因此训练集共 150 个样本点
1 | train <- rbind(iris3[,,1], iris3[,,2], iris3[,,3]) |
同样,训练集对应的真实分类数据也是长度为 150 的向量
1 | cl.cv <- factor(c(rep("s",50), rep("c",50), rep("v",50))) |
最后,对训练集的每一行做预测,利用其余行的 3 个最近邻来投票
1 | final.cv <- knn.cv(train, cl.cv, k = 3) |
1 | ## [1] 0.96 |
可以看到,iris3 中对这三种方法的预测效果排序,knn.cv(k = 3) 优于 knn1 优于 knn(k = 3)