原理:已知样本集中每一个数据与所属分类的对应关系,输入没有标签的新数据后,将新数据与训练集的数据对应特征进行比较,找出“距离”最近的k(通常k<20)数据,选择这k个数据中出现最多的分类作为新数据的分类。
算法描述:(1)计算已知类别数据及中的点与当前点的距离;
(2)按距离递增次序排序
(3)选取与当前点距离最小的k个点
(4)确定前K个点所在类别出现的频率
(5)返回频率最高的类别作为当前类别的预测
距离计算方法有"euclidean”(欧氏距离), “wski”(明科夫斯基距离),"maximum"(切比雪夫距离), "manhattan"(绝对值距离),"canberra"(兰式距离), "minkowski"(马氏距离)等。
最常见以欧氏距离作为衡量标准,下文例子也以欧式距离为标准。
R实现:
以鸢尾花数据集为例来说明K-近邻算法:
鸢尾花数据集包含150个数据,测量变量为花瓣的长度与宽度,花萼的长度与宽度,以及种类分类为setosa, versicolor, 和 virginica。
(1)为了了解数据,应先通过作图分析,相关分析来看看数据分类指标的合理性,这一点十分重要,有助于减少分类指标中的噪声。
代码为:plot(Sepal.Width,Sepal.Length,col=Species)
plot(Petal.Width,Petal.Length,col=Species)
从上图可以看出,Petal的长度和宽度2个变量大致是可以把鸢尾花分类的,也就是说分类的特征变量选择是合理的,而Sepal的长度和宽度分类效果不如Petal,但大致上还是能区分的,当然也可以选择计算相关系数来看特征变量的合理性。
(2)数据归一化处理
容易发现,数值差最大的属性对距离的影响最大,所以在特征值等权重的假定下,我们先得归一化特征值,计算公式为:
Newvalue=(oldvalue-min)/(max-min)
代码为:
autonorm<-function(data){
min<-min(data)
max<-max(data)
for(i in 1:length(data))
data[i]<-(data[i]-min)/(max-min)
return(data)
}
data<-apply(as.matrix(iris[,1:4]),2,autonorm)
(3)计算距离。
在这里取三个数据作为验证集来看看分类的效果,首先将验证集归一化:
x<-iris[13,1:4]
y<-iris[79,1:4]
z<-iris[100,1:4]
x<-(x-apply(iris[c(-13,-79,-100),1:4],2,min))/(apply(iris[c(-13,-79,-100),1:4],2,max)-apply(iris[c(-13,-79,-100),1:4],2,min))
y<-(y-apply(iris[c(-13,-79,-100),1:4],2,min))/(apply(iris[c(-13,-79,-100),1:4],2,max)-apply(iris[c(-13,-79,-100),1:4],2,min))
z<-(z-apply(iris[c(-13,-79,-100),1:4],2,min))/(apply(iris[c(-13,-79,-100),1:4],2,max)-apply(iris[c(-13,-79,-100),1:4],2,min))
计算距离,仅以Z为例,运行代码:(k取5)
dis<-rep(0,length(data[,1]))
for(i in 1:length(data[,1]))
dis[i]<-sqrt(sum((z-data[i,1:4])^2))
table(iris[order(dis)[1:5],5])
结果如下:
从x,y,z的输出结果可以看到,分类完全正确,没有错误分类。
值得一提的是,我们用同样的办法计算K=3时的情形,会发现没有出现误分类。这也就引出了一个值得思考的问题:k应该如何选取?k过小,噪声对分类的影响就会变得非常大,K过大,那么包含错误就理所当然,误分类也不足为奇。虽然这里我们对K的取值并未进行讨论,但在实际中,我们应该通过交叉验证的办法来确定k值。
R语言内置函数kknn简介
R语言里的kknn包也可以实现最邻近算法——使用kknn函数。
kknn(formula = formula(train),train, test, na.action = na.omit(), k= 7, distance = 2, kernel = "optimal", ykernel = NULL, scale=TRUE, contrasts= c('unordered' = "contr.dummy", ordered ="contr.ordinal"))
参数解释:
formula 一个回归模型,具体为:分类变量~特征变量
train 训练集
test 测试集
na.action 缺失值处理,默认为去掉缺失值
k k值选择,默认为7
distance 这个是明科夫斯基距离,p=2时为欧氏距离
其他参数 略
上面的鸢尾花例子使用kknn包可以实现(k=5):
library(kknn)
data(iris)
m <- dim(iris)[1]
val <- sample(1:m, size =round(m/3), replace = FALSE,prob= rep(1/m, m))
iris.learn <- iris[-val,]
iris.valid <- iris[val,]
iris.kknn <- kknn(Species~.,iris.learn, iris.valid, distance = 5,kernel= "triangular")
summary(iris.kknn)
fit <- fitted(iris.kknn)
table(iris.valid$Species, fit)
运行结果为: