R语言与机器学习(1)K-近邻算法
R中k-近邻实现

一、R语言包函数kknn简介R语言里的kknn包可以实现最近邻算法——使用其中的kknn函数,具体函数格式如下kknn(formula=formula(train),train,test,na.action=na.omit(),k=7,distance= 2)参数解释:formula:一个回归模型,具体为分类变量~特征变量train:训练集test:测试集na.action:缺失值处理,默认为去掉缺失值k:k值的选择,默认为7distance:这个是明科夫斯基距离。
值为2时为欧氏距离。
当然还有其他的距离,可以参考《统计建模与R》P398的那些距离。
还有其他的一些参数,这里略去。
二、一个简单的例子帮助理解使用该函数我们使用kknn包自带的iris数据集进行实验,完整的代码如下:> library(kknn) #加载该包。
> data(iris) #加载数据#下面我们提取自己的训练数据和测试数据> ir<-iris> ir<-edit(iris) #让你看看数据的机构,好熟悉数据> set.seed(123) #设定随机种子,即实验的可重复> count.train<-round(runif(100,1,150)) #生成100个1-150区间的均匀分布的随机整数,注意可能有重复数值> set.seed(124)> count.test<-round(runif(50,1,150))> train<-ir[count.train,] #生成训练数据> test<-ir[count.test,] #生成测试数据> result.knn<-kknn(Species~.,train,test) #对测试集进行分类。
> summary(result.knn) #查看分类的结果,如下对结果解释,fit:即test中每一个样本对应的类别。
r语言 knn模型

r语言创建knn模型示例
k-最近邻(k-Nearest Neighbors,k-NN)是一种基本的机器学习算法,可以用于分类和回归问题。
在R语言中,你可以使用class或mclust包来创建k-NN 模型。
以下是一个使用class包的基本示例:
在这个例子中,我们创建了一个包含两个类别的数据集,每个类别有10个样本。
然后,我们随机地将数据集分成训练集和测试集。
接着,我们使用训练集训练一个k-NN模型,其中k=3。
最后,我们打印出模型的分类结果。
需要注意的是,knn()函数默认选择类别数目为训练集中样本最多的类别作为预测的类别。
如果你希望改变这个行为,可以使用method参数。
例如,如果你希望使用投票的方式进行分类,可以将method参数设置为"votes"。
机器学习经典分类算法——k-近邻算法(附python实现代码及数据集)

机器学习经典分类算法——k-近邻算法(附python实现代码及数据集)⽬录⼯作原理存在⼀个样本数据集合,也称作训练样本集,并且样本集中每个数据都存在标签,即我们知道样本集中每⼀数据与所属分类的对应关系。
输⼊没有标签的新数据后,将新数据的每个特征与样本集中数据对应的特征进⾏⽐较,然后算法提取样本集中特征最相似数据(最近邻)的分类特征。
⼀般来说,我们只选择样本数据集中前k个最相似的数据,这就是k-近邻算法中k的出处,通常k是不⼤于20的整数。
最后选择k个最相似数据中出现次数最多的分类,作为新数据的分类。
举个例⼦,现在我们⽤k-近邻算法来分类⼀部电影,判断它属于爱情⽚还是动作⽚。
现在已知六部电影的打⽃镜头、接吻镜头以及电影评估类型,如下图所⽰。
现在我们有⼀部电影,它有18个打⽃镜头、90个接吻镜头,想知道这部电影属于什么类型。
根据k-近邻算法,我们可以这么算。
⾸先计算未知电影与样本集中其他电影的距离(先不管这个距离如何算,后⾯会提到)。
现在我们得到了样本集中所有电影与未知电影的距离。
按照距离递增排序,可以找到k个距离最近的电影。
现在假定k=3,则三个最靠近的电影依次是He's Not Really into Dudes、Beautiful Woman、California Man。
python实现⾸先编写⼀个⽤于创建数据集和标签的函数,要注意的是该函数在实际⽤途上没有多⼤意义,仅⽤于测试代码。
def createDataSet():group = array([[1.0,1.1],[1.0,1.0],[0,0],[0,0.1]])labels = ['A','A','B','B']return group, labels然后是函数classify0(),该函数的功能是使⽤k-近邻算法将每组数据划分到某个类中,其伪代码如下:对未知类别属性的数据集中的每个点依次执⾏以下操作:(1)计算已知类别数据集中的点与当前点之间的距离;(2)按照距离递增次序排序;(3)选取与当前点距离最⼩的k个点;(4)确定前k个点所在类别的出现频率;(5)返回前k个点出现频率最⾼的类别作为当前点的预测分类。
机器学习之K-近邻算法

机器学习之K-近邻算法声明:本篇博⽂是学习《机器学习实战》⼀书的⽅式路程,系原创,若转载请标明来源。
1. K-近邻算法的⼀般流程:(1)收集数据:可以使⽤任何⽅法(如爬⾍)。
(2)准备数据:距离计算所需要的数值,最好是结构化的数据格式。
(3)分析数据:可以使⽤任何⽅法。
(4)测试算法:计算误差率。
(5)使⽤算法:⾸先需要输⼊样本数据和结构化的输出结果,然后运⾏K-近邻算法判定输⼊数据分别属于哪个分类,最后应⽤对计算出的分类执⾏后续的处理。
2. K-近邻算法的伪代码和Python代码对未知类别属性的数据集中的每个点依次执⾏以下操作:(1)计算已知类别数据集中的点与当前点之间的距离。
(2)按照距离递增次序排序。
(3)选取与当前点距离最⼩的k个点。
(4)确定前k个点所在类别的出现频率。
(5)返回前k个点出现频率最⾼的类别作为当前点的预测分类。
程序代码:def classify0(inX, dataSet, labels, k):dataSetSize = dataSet.shape[0]diffMat = tile(inX, (dataSetSize,1)) - dataSetsqDiffMat = diffMat**2sqDistances = sqDiffMat.sum(axis=1)distances = sqDistances**0.5sortedDistIndicies = distances.argsort()classCount={}for i in range(k):voteIlabel = labels[sortedDistIndicies[i]]classCount[voteIlabel] = classCount.get(voteIlabel,0) + 1sortedClassCount = sorted(classCount.iteritems(), key=operator.itemgetter(1), reverse=True)return sortedClassCount[0][0]代码解释:(1)classify0()函数的四个输⼊参数:inX ⽤于分类的输⼊向量,dataSet是输⼊的训练样本集,labels是标签向量,最后k是⽤于选择最近邻的数⽬,其中标签向量的元素数⽬和矩阵dataSet的⾏数相同。
机器学习:K-近邻算法(KNN)

机器学习:K-近邻算法(KNN)机器学习:K-近邻算法(KNN)⼀、KNN算法概述KNN作为⼀种有监督分类算法,是最简单的机器学习算法之⼀,顾名思义,其算法主体思想就是根据距离相近的邻居类别,来判定⾃⼰的所属类别。
算法的前提是需要有⼀个已被标记类别的训练数据集,具体的计算步骤分为⼀下三步:1、计算测试对象与训练集中所有对象的距离,可以是欧式距离、余弦距离等,⽐较常⽤的是较为简单的欧式距离;2、找出上步计算的距离中最近的K个对象,作为测试对象的邻居;3、找出K个对象中出现频率最⾼的对象,其所属的类别就是该测试对象所属的类别。
⼆、算法优缺点1、优点思想简单,易于理解,易于实现,⽆需估计参数,⽆需训练;适合对稀有事物进⾏分类;特别适合于多分类问题。
2、缺点懒惰算法,进⾏分类时计算量⼤,要扫描全部训练样本计算距离,内存开销⼤,评分慢;当样本不平衡时,如其中⼀个类别的样本较⼤,可能会导致对新样本计算近邻时,⼤容量样本占⼤多数,影响分类效果;可解释性较差,⽆法给出决策树那样的规则。
三、注意问题1、K值的设定K值设置过⼩会降低分类精度;若设置过⼤,且测试样本属于训练集中包含数据较少的类,则会增加噪声,降低分类效果。
通常,K值的设定采⽤交叉检验的⽅式(以K=1为基准)经验规则:K⼀般低于训练样本数的平⽅根。
2、优化问题压缩训练样本;确定最终的类别时,不是简单的采⽤投票法,⽽是进⾏加权投票,距离越近权重越⾼。
四、python中scikit-learn对KNN算法的应⽤#KNN调⽤import numpy as npfrom sklearn import datasetsiris = datasets.load_iris()iris_X = iris.datairis_y = iris.targetnp.unique(iris_y)# Split iris data in train and test data# A random permutation, to split the data randomlynp.random.seed(0)# permutation随机⽣成⼀个范围内的序列indices = np.random.permutation(len(iris_X))# 通过随机序列将数据随机进⾏测试集和训练集的划分iris_X_train = iris_X[indices[:-10]]iris_y_train = iris_y[indices[:-10]]iris_X_test = iris_X[indices[-10:]]iris_y_test = iris_y[indices[-10:]]# Create and fit a nearest-neighbor classifierfrom sklearn.neighbors import KNeighborsClassifierknn = KNeighborsClassifier()knn.fit(iris_X_train, iris_y_train)KNeighborsClassifier(algorithm='auto', leaf_size=30, metric='minkowski',metric_params=None, n_jobs=1, n_neighbors=5, p=2,weights='uniform')knn.predict(iris_X_test)print iris_y_testKNeighborsClassifier⽅法中含有8个参数(以下前两个常⽤):n_neighbors : int, optional (default = 5):K的取值,默认的邻居数量是5;weights:确定近邻的权重,“uniform”权重⼀样,“distance”指权重为距离的倒数,默认情况下是权重相等。
K近邻算法PPT课件

• 包含目标点的叶结点对应包含目标点的最小超矩形区域。以此叶 结点的实例点作为当前最近点。目标点的最近邻一定在以目标点 为中心并通过当前最近点的超球体内部。然后返回当前结点的父 结点,如果父结点的另一子结点的超矩形区域与超球体相交,那 么在相交的区域内寻找与目标点更近的实例点。如果存在这样的 点,将此点作为新的当前最近点。
➢ 问题:给这个绿色的圆分类? ➢ 如果K=3,绿色圆点的最近的3个邻居是2个红色小三角形和1个蓝
色小正方形,少数从属于多数,基于统计的方法,判定绿色的这 个待分类点属于红色的三角形一类。 ➢ 如果K=5,绿色圆点的最近的5个邻居是2个红色三角形和3个蓝色 正方形,还是少数从属于多数,基于统计的方法,判定绿色的这 个待分类点属于蓝色的正方形一类。
区域内没有实例时终止。在此过程中,将实例保存在相应的结点
上。
2020/7/23
9
K近邻法的实现:kd树
2020/7/23
10
K近邻法的实现:kd树
2020/7/23
11
K近邻法的实现:kd树
➢ 搜索kd树
• 利用kd树可以省去大部分数据点的搜索,从而减少搜索的计算量 。这里以最近邻为例,同样的方法可以应用到K近邻。
2020/7/23
5
K近邻的三个基本要素
2020/7/23
6
K近邻的三个基本要素
➢ K值的选择
• 如果选择较小的k值,就相当于用较小的邻域中的训练实例进行预 测, “学习”的近似误差会减小,只有与输入实例较近的训练实 例才会对预测结果起作用。但缺点是“学习”的估计误差会增大 ,预测结果会对近邻的实例点非常敏感。换句话说,k值的减小意 味着整体模型变得复杂,容易发生过拟合。
基于R语言的k_最近邻法数字模式识别研究

基于 R 语言的 k-最近邻法数字模式识别研究钟志强(鞍山师范学院物理科学与技术学院,辽宁 鞍山 114007)[摘 要] k-最近邻法是常见的机器学习算法,R 语言中通过 kknn 包完成算法实现,但其无法实现图像文件的处理。
为此,本文先将图像文件转换成文本文件,再结合 KNN 算法对文件中数字图像进行模式识别。
实验得出其判断结果达到了预 期指标。
[关键词] k-最近邻法;模式识别;R 语言现以著名鸢尾花(iris )数据集实现算例:包含五个指标花瓣长度(Petal .Length)、萼片宽度(Sepal.Width)、花瓣宽度 (Petal.Width)、萼片长度(Sepal.Length)、三种花类型(Species : setosa ,versicolor ,virginica )150 笔记录。
其结果见表 1 和图 1。
data(iris);m<- d im(iris)[1];val<- s ample(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=1,kernel="triangular");summary (iris .kknn);fit<-fitted(iris .kknn);table(iris .valid$Species , fit)pcol<- as . character(as . numeric(iris . valid $Species)); pairs(iris .valid[1:4],pch=pcol ,col = c("green3","red")[(iris .valid$Species != fit)+1]) 1.k-最近邻法原理k-最近邻法(k-nearest neighbor ,KNN)是最简单的机器学 习算法之一,可以用于分类和回归。
k-近邻分类算法

k-近邻分类算法K近邻分类算法是一种基于实例的分类算法,它的主要思想是通过计算每个样本点与其周围的k个最近邻点的距离来确定该点的类别。
该算法主要应用于分类问题中,并且在实际应用过程中具有很好的可用性、易实现性和理解性。
算法原理算法首先通过确定k值来确定分类的邻域大小,以及根据k值的选择来确定分类的准确性和鲁棒性。
之后通过计算每个样本点与其邻域内k个最近邻点之间的距离来确定该样本点所属的分类。
具体流程如下:1.确定数据集中的k值和距离度量标准;2.对于每个待分类的样本点,计算与其邻域中k个最近邻点之间的距离;3.根据邻域中k个最近邻点的类别来确定该样本点所属的类别;4.重复步骤2和3,直到所有待分类的样本点均被分类完毕;5.给出分类结果。
距离度量标准在k-近邻分类算法中,距离度量标准是非常重要的,因为它决定了样本点之间距离的计算方式。
目前常见的距离度量标准有欧式距离、曼哈顿距离和切比雪夫距离。
欧式距离:$d=\sqrt{{\sum_{i=1}^{n}{(x_i-y_i)^2}}}$优缺点1.基于实例,不需要对数据进行任何假设和理论分析;2.算法的可预测性高,具有很好的分类性能;3.没有过拟合的现象,可以对复杂的数据集进行分类;4.整体而言,k-近邻分类算法非常容易理解和实现。
1.计算量比较大,对于大型数据集而言,算法的效率较低;2.对于高维数据集而言,容易出现维数灾难问题,即算法的效果会逐渐降低;3.容易受到异常值的影响,且在分类决策区域方面可能存在不连续的问题。
应用场景k-近邻分类算法广泛应用于模式识别、数据挖掘和生物信息学等领域,特别适合处理较小的数据集。
目前该算法已被应用于医疗诊断、电子商务、物联网等领域,既可以用于分类问题,也可以用于回归问题。
同时,对于分类问题而言,该算法并不适用于类别数比较多或类别间存在相互交叉的情况。
因此,在实际应用过程中,应根据具体情况来选择算法,以达到最佳的分类效果。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
K-近邻算法原理及举例工作原理:我们知道样本集中每一个数据与所属分类的对应关系,输入没有标签的新数据后,将新数据与训练集的数据对应特征进行比较,找出“距离”最近的k(通常k<20)数据,选择这k个数据中出现最多的分类作为新数据的分类。
算法描述:(1) 计算已知类别数据及中的点与当前点的距离;(2) 按距离递增次序排序(3) 选取与当前点距离最小的k个点(4) 确定前K个点所在类别出现的频率(5) 返回频率最高的类别作为当前类别的预测这里我们使用最常见欧氏距离作为衡量标准,以鸢尾花数据集为例来说明K-近邻算法:鸢尾花数据集包含150个数据,测量变量为花瓣,花萼的长度与宽度,分类变量为setosa, versicolor, 和 virginica。
准备数据:为了了解数据,我们先通过作图分析,相关分析来看看数据分类指标的合理性,这一点十分重要,有助于减少分类指标中的噪声。
从上图可以看出,我们通过这2个变量大致是可以把鸢尾花分类的,也就是说分类的特征变量选择是合理的,(同理可以分析另外2个,分类效果不如这两个,但大致上还是能区分的)当然我们也可以选择计算相关系数来看特征变量的合理性。
我们很容易发现,数值差最大的属性对距离的影响最大,所以在特征值等权重的假定下,我们先得归一化特征值,计算公式为:Newvalue=(oldvalue-min)/(max-min)R代码:autonorm<-function(data){for(iin 1:length(data))data[i]<-(data[i]-min(data))/(max(data)-min(data))return(data)}data<-as.matrix(apply(iris[,1:4],2,autonorm))得到了归一化后的数据集,下面计算距离。
我们在这里取三个数据作为验证集来看看分类的效果,首先将验证集归一化: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))计算距离,仅以x为例,运行代码:(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的输出结果为标签xyyz分类1233频数5415虽然对测试y出现了错误分类,但根据多数投票法x,y,z为setosa, versicolor, 和virginica,得到了正确分类结果。
值得一提的是,我们用同样的办法计算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值选择,默认为7distance 这个是明科夫斯基距离,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)这里我们的训练集选取更随机化,得到结果是:fitsetosa versicolor virginicasetosa 12 0 0versicolor 0 22 0virginica 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<-0for(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:4assign("a[1]",2)a[1]== 2 #FALSEget("a[1]") == 2 #TRUE在R中,我没有找到求众数的函数,简单编写了一个names(which.max(table(index[order(di)[1:5]]))),这个函数有两个众数时会输出两个,所以K近邻为了保证多数投票法有用,麻烦仔细选择合理的k值。
这里我在做训练集时并没有选择k值得过程(因为这个算法实在是太慢了,没有那个耐心)实际使用这个算法,执行效率相当的低下,每个距离的计算包含了1024个维度的浮点运算,总计900多次,还要为测试向量准备2M的存储空间。