1. K近邻算法(KNN)
1. K近邻算法(KNN)
2. KNN和KdTree算法实现
1. 前言
K近邻法(k-nearest neighbors,KNN)是一种很基本的机器学习方法了,在我们平常的生活中也会不自主的应用,就是“物以类聚,人以群分”。比如,我们判断一个人的人品,只需要观察他来往最密切的几个人的人品好坏就可以得出了。这里就运用了KNN的思想。KNN方法既可以做分类,也可以做回归,这点和决策树算法相同。
KNN做回归和分类的主要区别在于最后做预测时候的决策方式不同。KNN做分类预测时,一般是选择多数表决法,即训练集里和预测的样本特征最近的K个样本,预测为里面有最多类别数的类别。而KNN做回归时,一般是选择平均法,即最近的K个样本的样本输出的平均值作为回归预测值。由于两者区别不大,虽然本文主要是讲解KNN的分类方法,但思想对KNN的回归方法也适用。本文后面主要介绍的是KNN的分类问题。
2. KNN算法原理
给定一个训练集,对新输入的实例,在训练集中找到与该实例最邻近的k个实例,这k个实例的多数属于某个类,我们就把该输入实例分为这个类。
2.1 算法描述
输入:训练数据集\(T=\{(x_1,y_1),(x_2,y_2),...,(x_N,y_N)\}\),其中\(x_i\in{\chi}\)为实例的特征向量,\(y_i\in{\{c_1,c_2,...,c_m\}}\)为实例的类别;实例特征向量x
输出:实例x所属的类别y
- 根据给定的距离度量方式,在训练集T中找到与x最邻近的k个点,涵盖着k个点的x的领域记住\(N_k(x)\)
- 在\(N_k(x)\)中根据分类决策规则决定x的类别y
\[
y=argmax_{c_j}\sum_{x_i\in{N_k(x)}}I(y_i=c_j)
\]
其中\(I(y_i=c_j)\)为指示函数,当\(y_i=c_j\)的时候\(I=1\),后者\(I=0\)
3. KNN的基本要素
对于一个确定的训练集,只要确定了距离度量、k值和分类决策规则,就能对任何一个新的实例,确定它的分类。
3.1 距离度量
距离度量是描述特征空间中两个实例的距离,也是这两个实例的相似程度。在n维实数向量空间中,我们主要使用的距离度量方式是欧式距离,但也可以使用更加一般化\(L_p\)距离(闵可夫斯基距离)。
在特征空间中,取出两个特征\(x_i\),\(x_j\),它们分别是n维的特征向量。
3.1.1 欧氏距离
\[
L_2(x_i,x_j)=(\sum_{l=1}^n|x_i^l-x_j^l|)^{\frac{1}{2}}
\]
3.1.2 曼哈顿距离
\[
L_1(x_i,x_j)=\sum_{l=1}^n|x_i^l-x_j^l|
\]
3.1.3 闵可夫斯基距离
\[
L_p(x_i,x_j)=(\sum_{l=1}^n|x_i^l-x_j^l|)^{\frac{1}{p}}
\]
从上式可以看出,欧氏距离和曼哈顿距离分别是闵可夫斯基距离的\((p=2,p=1)\)特殊情况
3.2 k值的选择
对于k值的选择,没有一个固定的经验,一般根据样本的分布,选择一个较小的值,然后通过交叉验证选择一个合适的k值。
- 选择较小的k值,就相当于用较小的领域中的训练实例进行预测,训练误差会减小,只有与输入实例较近或相似的训练实例才会对预测结果起作用,与此同时带来的问题是泛化误差会增大。换句话说,k值的减小就意味着整体模型变得复杂,容易发生过拟合。
- 选择较大的k值,就相当于用较大领域中的训练实例进行预测,其优点是可以减少泛化误差,但缺点是训练误差会增大。这时候,与输入实例较远(不相似的)训练实例也会对预测器作用,使预测发生错误。换句话说,k值的增大就意味着整体的模型变得简单,容易发生欠拟合。
一个极端是k等于样本数m,则完全没有分类,此时无论输入实例是什么,都只是简单的预测它属于在训练实例中最多的类,模型过于简单。
3.3 分类决策规则
对于分类决策规则,一般都是使用前面提到的多数表决法。
4. kd树
KNN算法最简单的实现方式,就是好计算输入实例和所有训练实例的距离,然后进行排序,取前k个,进行分类。但是训练集特别大的时候,这种方式非常耗时,不可行。下面介绍kd树的方式,kd树是通过减少输入实例和训练实例的计算次数来达到优化的目的。
kd树算法包括三步,第一步是建树,第二部是搜索最近邻,最后一步是预测。
4.1 构造kd树
kd树是一种对n维空间的实例点进行存储,以便对其进行快速检索的树形结构。kd树是二叉树,构造kd树相当于不断的用垂直于坐标轴的超平面将n维空间进行划分,构成一系列的n维超矩阵区域。
我们首先来看建树的方法。kd树建树采用的是从m个样本的n维特征中,分别计算n个特征的取值的方差,用方差最大的第k维特征\(n_k\)来作为根节点。对于这个特征,我们选择特征nk的取值的中位数\(n_{kv}\)对应的样本作为划分点,对于所有第k维特征的取值小于\(n_{kv}\)的样本,我们划入左子树,对于第k维特征的取值大于等于\(n_{kv}\)的样本,我们划入右子树,对于左子树和右子树,我们采用和刚才同样的办法来找方差最大的特征来做更节点,递归的生成kd树。
下面的流程图更加清晰的描述了kd树的构建过程:
构建好的kd树,大概如下:
4.2 kd树搜索最近邻
当我们生成kd树以后,就可以去预测测试集里面的样本目标点了。预测的过程如下:
- 对于一个目标点,我们首先在kd树里面找到包含目标点的叶子节点。以目标点为圆心,以目标点到叶子节点样本实例的距离为半径,得到一个超球体,最近邻的点一定在这个超球体内部。
- 然后返回叶子节点的父节点,检查另一个子节点包含的超矩形体是否和超球体相交,如果相交就到这个子节点寻找是否有更加近的近邻,有的话就更新最近邻,并且更新超球体。如果不相交那就简单了,我们直接返回父节点的父节点,在另一个子树继续搜索最近邻。
- 当回溯到根节点时,算法结束,此时保存的最近邻节点就是最终的最近邻。
从上面的描述可以看出,kd树划分后可以大大减少无效的最近邻搜索,很多样本点由于所在的超矩形体和超球体不相交,根本不需要计算距离。大大节省了计算时间。
搜索过程,大致如下:
4.3 kd树预测
有了kd树搜索最近邻的办法,kd树的预测就很简单了,在kd树搜索最近邻的基础上,我们选择到了第一个最近邻样本,就把它置为已选。在第二轮中,我们忽略置为已选的样本,重新选择最近邻,这样跑k次,就得到了目标的k个最近邻。然后根据多数表决法,如果是KNN分类,预测为k个最近邻里面有最多类别数的类别。如果是KNN回归,用k个最近邻样本输出的平均值作为回归预测值。
1. K近邻算法(KNN)的更多相关文章
- k近邻算法(KNN)
k近邻算法(KNN) 定义:如果一个样本在特征空间中的k个最相似(即特征空间中最邻近)的样本中的大多数属于某一个类别,则该样本也属于这个类别. from sklearn.model_selection ...
- 机器学习(四) 分类算法--K近邻算法 KNN (上)
一.K近邻算法基础 KNN------- K近邻算法--------K-Nearest Neighbors 思想极度简单 应用数学知识少 (近乎为零) 效果好(缺点?) 可以解释机器学习算法使用过程中 ...
- 一看就懂的K近邻算法(KNN),K-D树,并实现手写数字识别!
1. 什么是KNN 1.1 KNN的通俗解释 何谓K近邻算法,即K-Nearest Neighbor algorithm,简称KNN算法,单从名字来猜想,可以简单粗暴的认为是:K个最近的邻居,当K=1 ...
- 机器学习(四) 机器学习(四) 分类算法--K近邻算法 KNN (下)
六.网格搜索与 K 邻近算法中更多的超参数 七.数据归一化 Feature Scaling 解决方案:将所有的数据映射到同一尺度 八.scikit-learn 中的 Scaler preprocess ...
- k近邻算法(knn)的c语言实现
最近在看knn算法,顺便敲敲代码. knn属于数据挖掘的分类算法.基本思想是在距离空间里,如果一个样本的最接近的k个邻居里,绝大多数属于某个类别,则该样本也属于这个类别.俗话叫,"随大流&q ...
- 《机器学习实战》---第二章 k近邻算法 kNN
下面的代码是在python3中运行, # -*- coding: utf-8 -*- """ Created on Tue Jul 3 17:29:27 2018 @au ...
- 最基础的分类算法-k近邻算法 kNN简介及Jupyter基础实现及Python实现
k-Nearest Neighbors简介 对于该图来说,x轴对应的是肿瘤的大小,y轴对应的是时间,蓝色样本表示恶性肿瘤,红色样本表示良性肿瘤,我们先假设k=3,这个k先不考虑怎么得到,先假设这个k是 ...
- 07.k近邻算法kNN
1.将数据分为测试数据和预测数据 2.数据分为data和target,data是矩阵,target是向量 3.将每条data(向量)绘制在坐标系中,就得到了一系列的点 4.根据每条data的targe ...
- 机器学习随笔01 - k近邻算法
算法名称: k近邻算法 (kNN: k-Nearest Neighbor) 问题提出: 根据已有对象的归类数据,给新对象(事物)归类. 核心思想: 将对象分解为特征,因为对象的特征决定了事对象的分类. ...
- 机器学习(1)——K近邻算法
KNN的函数写法 import numpy as np from math import sqrt from collections import Counter def KNN_classify(k ...
随机推荐
- android 点击通知栏返回应用 ,非启动一个新Activity
再使用如下的 Intent 设置: Intent intent = new Intent(this, MainActivity.class); intent.addFlags(Intent.FLAG_ ...
- Transparent Huge Pages
在RHEL6中,透明大页功能是默认开启的. 开启该选项后,内核会尽可能地尝试分配大页,如果mmap区域是2mb,那么每个linux进程都会分配到2mb大小的页.如果大页不够用了(比如物理内存不够了), ...
- iOS Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'unable to
刚接触iOS,依照教程操作执行出现错误 Terminating app due to uncaught exception 'NSInternalInconsistencyException', re ...
- 【转】java io 流 设计模式
知识点:什么是装饰模式: http://wenku.baidu.com/view/ad4eac9f51e79b896802263b.html(原理讲的很清楚) http://wenku.baidu.c ...
- 配置eureka 老是报错connected time out 或者 refused connected
报错信息总是连接错误,我指定了端口号,却不按照我指定的端口进行访问,而是访问eureka-server 的端口号是8761 ,这是因为配置有问题. 查看 类 EurekaClientConfigBea ...
- 找不到dubbo:annotaion错误
dubbo 2.8.4 出现找不到dubbo:annotation的错误,其实这个不会影响程序正确的运行,但是看到有红叉心里肯定非常不爽: 解决办法是,将dubbo-2.8.4.jar包,后缀改成.z ...
- WPF使用System.Windows.SystemParameters类获得屏幕分辨率
转自 http://hi.baidu.com/shirley_cst/item/a55c290c8aa2ee2ca0312da3 示例代码如下所示. double x = SystemParamete ...
- Nginx(四):压缩功能详解
gzip (GNU-ZIP) 是一种压缩技术.经过 gzip 压缩后页面大小可以变为原来的 30%甚至更小. 这样,用户浏览页面的时候速度会快得多. gzip 的压缩页面需要浏览器和服务器双方都支持 ...
- 禁用 Windows 启动时错误恢复的“启动启动修复(推荐)”
bcdedit /set {default} bootstatuspolicy ignoreallfailures bcdedit /set {current} recoveryenabled No
- Lua中and、or的一些特殊使用方法
Lua中的逻辑运算符:与(and).或(or)和非(not),与其它语言的逻辑运算符功能一致,这里不做赘述.仅仅说一点,全部的逻辑运算符将false和nil视为假,其它不论什么东西视为真.0也视为真. ...