R语言与机器学习学习笔记(分类算法)(1)K-近邻算法
前言
最近在学习数据挖掘,对数据挖掘中的算法比较感兴趣,打算整理分享一下学习情况,顺便利用R来实现一下数据挖掘算法。
数据挖掘里我打算整理的内容有:分类,聚类分析,关联分析,异常检测四大部分。其中分类算法主要介绍:K-近邻算法,决策树算法,朴素贝叶斯算法,支持向量机,神经网络,logistic回归。
写这份学习笔记主要以学校data mining课程的课件为主,会参考一堆的baidu,一堆的google,一堆的blog,一堆的book以及一堆乱七八糟的资料,由于精力有限,恕不能一一列出,如果有认为有侵权行为欢迎与我联系,保证及时删除。
这篇文章是我博客数据挖掘系列的第一篇文章,介绍分类算法中最基本的算法——k近邻算法。
算法一:K-近邻算法
原理及举例
工作原理:我们知道样本集中每一个数据与所属分类的对应关系,输入没有标签的新数据后,将新数据与训练集的数据对应特征进行比较,找出“距离”最近的k(通常k<20)数据,选择这k个数据中出现最多的分类作为新数据的分类。
算法描述:
(1) 计算已知类别数据及中的点与当前点的距离;
(2) 按距离递增次序排序
(3) 选取与当前点距离最小的k个点
(4) 确定前K个点所在类别出现的频率
(5) 返回频率最高的类别作为当前类别的预测
距离计算方法有"euclidean"(欧氏距离),”minkowski”(明科夫斯基距离), "maximum"(切比雪夫距离), "manhattan"(绝对值距离),"canberra"(兰式距离), 或 "minkowski"(马氏距离)等.
分析学的知识告诉我们Rn上范数之间是等价的,所以我们也没必要太过纠结选谁,毕竟范数之间都是可以相互控制的。
这里我们使用最常见欧氏距离作为衡量标准,以鸢尾花数据集为例来说明K-近邻算法:
鸢尾花数据集包含150个数据,测量变量为花瓣,花萼的长度与宽度,分类变量为setosa, versicolor, 和 virginica。
准备数据:
为了了解数据,我们先通过作图分析,相关分析来看看数据分类指标的合理性,这一点十分重要,有助于减少分类指标中的噪声。
从上图可以看出,我们通过这2个变量大致是可以把鸢尾花分类的,也就是说分类的特征变量选择是合理的,(同理可以分析另外2个,分类效果不如这两个,但大致上还是能区分的)当然我们也可以选择计算相关系数来看特征变量的合理性。
我们很容易发现,数值差最大的属性对距离的影响最大,所以在特征值等权重的假定下,我们先得归一化特征值,计算公式为:
Newvalue=(oldvalue-min)/(max-min)
(注:网友@ reus123指出归一化的提法不太合适,也的确如此,我们这里将本文的“归一化”理解为一种“标准化”就好,感谢@ reus123的指正)
R代码:
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)
(之前的程序有误,已更正,感谢 @ reus123的指正)
得到了归一化后的数据集,下面计算距离。我们在这里取三个数据作为验证集来看看分类的效果,首先将验证集归一化:
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(iin 1:length(data[,1]))
dis[i]<-sqrt(sum((z-data[i,1:4])^2))
table(data[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)
这里我们的训练集选取更随机化,得到结果是:
fit
setosa versicolor virginica
setosa 12 0 0
versicolor 0 22 0
virginica 0 0 16
分类完全正确。
应用举例:手写数字识别
下面我们来做一个规模大一些的数据处理,利用k-近邻实现一下数字的模式识别。这个例子来自《机器学习实战》,具体数据集已上传至百度云盘(点击这里下载)。数据为了简单起见,仅提供0~9,10个数字的识别。需要识别的数字你可以看做是被图像处理软件处理为了32*32的黑白图像。尽管文本格式储存图片不能够有效地利用存储空间,但是为了方便理解还是提供了这个文本版的图片数据。至于图像版本的数据,你可以找到《手写数字的光学识别》一文(登载于2010年的UCI机器学习资料库中)的数据集合,并下载它。
完整的R实现:
setwd("D:/R/data/digits/trainingDigits")
names<-list.files("D:/R/data/digits/trainingDigits")
data<-paste("train",1:1934,sep="")
for(i in 1:length(names))
assign(data[i],as.matrix(read.fwf(names[i],widths=rep(1,32))))dis<-function(datatest,datatrain,len){
distance<-rep(0,len)
for(i in 1:len)
distance[i]<-sqrt(sum((get(datatest)-get(datatrain[i]))^2))
return((distance))
}judge<-function(test,data,names){
index<-rep(0:9,c(189,198,195,199,186,187,195,201,180,204))
di<-rep(0,1934)
di[1:1934]<-dis(test,data,length(names))
return(names(which.max(table(index[order(di)[1:5]]))))
}setwd("D:/R/data/digits/testDigits")
name<-list.files("D:/R/data/digits/testDigits")
test<-paste("test",1:946,sep="")
for(i in 1:length(name))
assign(test[i],as.matrix(read.fwf(name[i],widths=rep(1,32))))
index1<-rep(0:9,c(87,97,92,85,114,108,87,96,91,89))error<-0
for(i in 1:946){
if(judge(test[i],data,names)!=index1[i])
error<-error+1
}
运行结果:
>error
[1]19
>19/946
[1]0.02008457
也就是说,使用5-近邻算法,误差率为2%,属于一个可以接受的范围。
这里由于本人没有找到较好的批量导入数据的办法,所以代码有些复杂,也出现了hardcode和magicnumber的毛病,但是泛化也不是那么的复杂,所以也没再做更进一步的改进。希望读者告诉我如何解决R里导入批量数据的方法。
其中有两个函数是我在之前的博客中没有使用过的,现在简单介绍如下:
赋值函数assign:
assign("x", c(10.4, 5.6, 3.1, 6.4, 21.7)) 与x <- c(10.4,5.6, 3.1, 6.4, 21.7)等价
读取赋值函数的函数get:
a<- 1:4
assign("a[1]",2)
a[1]== 2 #FALSE
get("a[1]") == 2 #TRUE
在R中,我没有找到求众数的函数,简单编写了一个names(which.max(table(index[order(di)[1:5]]))),这个函数有两个众数时会输出两个,所以K近邻为了保证多数投票法有用,麻烦仔细选择合理的k值。
这里我在做训练集时并没有选择k值得过程(因为这个算法实在是太慢了,没有那个耐心)
实际使用这个算法,执行效率相当的低下,每个距离的计算包含了1024个维度的浮点运算,总计900多次,还要为测试向量准备2M的存储空间。所以k决策树是你需要进一步了解的。
K决策树的种类也有不少,比如kd树,但是他们的问题就是k的选取总是一个麻烦的过程,kd树找最近邻是十分高效的,但是找k近邻,删除结点重新建树还是比较麻烦的。
Further reading:
JULY大神的《从K近邻算法、距离度量谈到KD树、SIFT+BBF算法》
预告
本文之后,待写的几篇文章罗列如下:
- 算法二:决策树算法
- 算法三:朴素贝叶斯算法
- 算法四:支持向量机
- 算法五:神经网络
- 算法六:logistic回归
(to be continue)
R语言与机器学习学习笔记(分类算法)(1)K-近邻算法相关推荐
- R语言与机器学习学习笔记(分类算法)
转载自:http://www.itongji.cn/article/0P534092014.html 人工神经网络(ANN),简称神经网络,是一种模仿生物神经网络的结构和功能的数学模型或计算模型.神经 ...
- 语言 提取列名_学习健明老师发布的R语言练习题的学习笔记(二)
学习者:骆栢维 题目来源:生信基石之R语言 中级10 个题目:http://www.bio-info-trainee.com/3750.html 备注:本文为笔者学习健明老师GitHub答案代码的学习 ...
- k近邻算法_机器学习分类算法之k近邻算法
本编文章将介绍机器学习入门算法-k近邻算法,将会用demo演示机器学习分类算法. 在先介绍算法时,先回顾分类和回归的区别.像文章分类识别也是这样处理的,如1代表体育,2代表科技,3代表娱乐属于分类问题 ...
- 《统计学习方法》学习笔记(4)--k近邻法及常用的距离(or 相似度)度量
一.k近邻法基础知识 1. 特征空间中两个实例点的距离反应了两个实例点的相似程度. 2. k近邻模型三要素 = 距离度量(有不同的距离度量所确定的最邻近点不同)+k值的选择(应用中,k值一般取一个比较 ...
- 【2017年cs231n学习笔记1】Lecture2 K近邻 距离度量 超参数 交叉验证 线性分类器
这是2017年,斯坦福大学,李飞飞教授及其博士生讲授的CS231n课程的第二节,主要内容是KNN算法.距离度量算法.超参数的选择方法.线性分类器的简单介绍. 所有图像来自课程ppt:http://cs ...
- chapter2 机器学习之KNN(k-nearest neighbor algorithm)--K近邻算法从原理到实现
一.引入 K近邻算法作为数据挖掘十大经典算法之一,其算法思想可谓是intuitive,就是从训练集里找离预测点最近的K个样本来预测分类 因为算法思想简单,你可以用很多方法实现它,这时效率就是我们需要慎 ...
- 机器学习算法基础——k近邻算法
23.k-近邻算法以及案例预测入住位置 24.K-近邻算法案例 分类算法-k近邻算法(KNN) 定义:如果一个样本在特征空间中的k个最相似(即特征空间中最邻近)的样本中的大多数属于某一个类别,则该样本 ...
- 【转载】R语言与数据挖掘学习笔记
(1):数据挖掘相关包的介绍 今天发现一个很不错的博客(http://www.RDataMining.com),博主致力于研究R语言在数据挖掘方面的应用,正好近期很想系统的学习一下R语言和数据挖掘的整 ...
- R语言与点估计学习笔记(矩估计与MLE)
众所周知,R语言是个不错的统计软件.今天分享一下利用R语言做点估计的内容.主要有:矩估计.极大似然估计.EM算法.最小二乘估计.刀切法(Jackknife).自助法(Bootstrap)的相关内容. ...
- R plot图片背景设置为透明_学习健明老师发布的R语言练习题的学习笔记(一)...
学习者:骆栢维 题目来源:生信基石之R语言 初级10 个题目:http://www.bio-info-trainee.com/3793.html 备注:本文为笔者学习健明老师GitHub答案代码的学习 ...
最新文章
- javascript 窗口加载事件相关问题
- python算法与数据结构-希尔排序算法(35)
- QT Core | 信号槽03 - 自定义信号与槽
- 循环神经网络LSTM RNN回归:sin曲线预测
- 左手手机右手智慧屏 华为9月要搞大事情
- javaScript的Math和Date对象
- Calendar与Date用法示例
- [BZOJ3124]直径
- java多窗口,主编处理java代码怎么实现多个窗口
- php中的oop思想,OOP思想指的是什么?
- COM组件和一般DLL 的区别
- 在原有产品的基础上建立软件产品线的方式
- win10无限重启_让迷你掌上电脑更具生产力,GPD安装 Win10+Ubuntu双系统
- 【nginx读取配置文件http模块】
- 说说自己工作中的测试流程
- AutoCAD2016简体中文破解版32位64位下载
- ant-design-vue 1.7.8版本使用报错
- 仪征市职称计算机,《关于重申专业技术人员职称评定、职务聘任必须坚持外语、计算机条件的通知》……...
- 基于51单片机的信号发生器设计
- l003 Driller Augmenting Fuzzing Through Selective Symbolic Execution_2016_NDSS学习笔记
热门文章
- 怎樣制作线段动画_教程:如何制作一个绘制线条动画
- Html5用Canvas制作绘图板
- 为什么会发生通货膨胀
- docker+scrapy+scrapy_splash爬取大麦网
- 树莓派系统烧录 + 连接树莓派
- el-descriptions文本水平垂直居中
- [Python图像处理] 四十三.Python图像形态学处理万字详解(腐蚀膨胀、开闭运算、梯度顶帽黑帽运算)
- 三星 android recovery,三星所有机型如何进入recovery模式的方法
- Java版九宫格算法
- 基于边缘计算的视觉感知研究