分类算法——K近邻算法及其R实现

原理:已知样本集中每一个数据与所属分类的对应关系,输入没有标签的新数据后,将新数据与训练集的数据对应特征进行比较,找出“距离”最近的k(通常k<20)数据,选择这k个数据中出现最多的分类作为新数据的分类。

算法描述:(1)计算已知类别数据及中的点与当前点的距离;

2)按距离递增次序排序

3)选取与当前点距离最小的k个点

4)确定前K个点所在类别出现的频率

5)返回频率最高的类别作为当前类别的预测

距离计算方法有"euclidean”(欧氏距离), “wski”(明科夫斯基距离),"maximum"(切比雪夫距离), "manhattan"(绝对值距离),"canberra"(兰式距离), "minkowski"(马氏距离)等。

最常见以欧氏距离作为衡量标准,下文例子也以欧式距离为标准。

R实现:

以鸢尾花数据集为例来说明K-近邻算法:

鸢尾花数据集包含150个数据,测量变量为花瓣的长度与宽度,花萼的长度与宽度,以及种类分类为setosa, versicolor,virginica

分类算法——K近邻算法及其R实现

1)为了了解数据,应先通过作图分析,相关分析来看看数据分类指标的合理性,这一点十分重要,有助于减少分类指标中的噪声。

分类算法——K近邻算法及其R实现

分类算法——K近邻算法及其R实现

代码为: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为例,运行代码:(k5)

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])

结果如下:

分类算法——K近邻算法及其R实现

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)

运行结果为:

分类算法——K近邻算法及其R实现

 

原文:http://blog.csdn.net/yujunbeta/article/details/14648343

发布了76 篇原创文章 · 获赞 26 · 访问量 19万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章