何谓K近邻算法,即K-Nearest Neighbor algorithm,简称KNN算法,单从名字来猜测,能够简单粗暴的认为是:K个最近的邻居,当K=1时,算法便成了最近邻算法,即寻找最近的那个邻居。html
用官方的话来讲,所谓K近邻算法,便是给定一个训练数据集,对新的输入实例,在训练数据集中找到与该实例最邻近的K个实例(也就是上面所说的K个邻居),这K个实例的多数属于某个类,就把该输入实例分类到这个类中。git
如上图所示,有两类不一样的样本数据,分别用蓝色的小正方形和红色的小三角形表示,而图正中间的那个绿色的圆所标示的数据则是待分类的数据。也就是说,如今,咱们不知道中间那个绿色的数据是从属于哪一类(蓝色小正方形or红色小三角形),KNN就是解决这个问题的。github
若是K=3,绿色圆点的最近的3个邻居是2个红色小三角形和1个蓝色小正方形,少数从属于多数,基于统计的方法,断定绿色的这个待分类点属于红色的三角形一类。面试
若是K=5,绿色圆点的最近的5个邻居是2个红色三角形和3个蓝色的正方形,仍是少数从属于多数,基于统计的方法,断定绿色的这个待分类点属于蓝色的正方形一类。算法
于此咱们看到,当没法断定当前待分类点是从属于已知分类中的哪一类时,咱们能够依据统计学的理论看它所处的位置特征,衡量它周围邻居的权重,而把它归为(或分配)到权重更大的那一类。这就是K近邻算法的核心思想。数据结构
咱们看到,K近邻算法的核心在于找到实例点的邻居,这个时候,问题就接踵而至了,如何找到邻居,邻居的断定标准是什么,用什么来度量。这一系列问题即是下面要讲的距离度量表示法。机器学习
有哪些距离度量的表示法(普及知识点,能够跳过):函数
欧氏距离,最多见的两点之间或多点之间的距离表示法,又称之为欧几里得度量,它定义于欧几里得空间中,如点 x = (x1,...,xn) 和 y = (y1,...,yn) 之间的距离为:学习
$$d(x,y)=\sqrt{(x_1-y_1)^2+(x_2-y_2)^2+...+(x_n-y_n)^2}=\sqrt{\sum_{i=1}^{n}(x_i-y_i)^2}$$测试
二维平面上两点a(x1,y1)与b(x2,y2)间的欧氏距离:
$$d_{12}=\sqrt{(x_1-x_2)^2+(y_1-y_2)^2}$$
三维空间两点a(x1,y1,z1)与b(x2,y2,z2)间的欧氏距离:
$$d_{12}=\sqrt{(x_1-x_2)^2+(y_1-y_2)^2+(z_1-z_2)^2}$$
两个n维向量a(x11,x12,…,x1n)与 b(x21,x22,…,x2n)间的欧氏距离:
$$d_{12}=\sqrt{\sum_{k=1}^{n}(x_{1k}-x_{2k})^2}$$
也能够用表示成向量运算的形式:
$$d_{12}=\sqrt{(a-b)(a-b)^T}$$
曼哈顿距离,咱们能够定义曼哈顿距离的正式意义为L1-距离或城市区块距离,也就是在欧几里得空间的固定直角坐标系上两点所造成的线段对轴产生的投影的距离总和。例如在平面上,坐标(x1, y1)的点P1与坐标(x2, y2)的点P2的曼哈顿距离为:$|x_1-x_2|+|y_1-y_2|$,要注意的是,曼哈顿距离依赖座标系统的转度,而非系统在座标轴上的平移或映射。
通俗来说,想象你在曼哈顿要从一个十字路口开车到另一个十字路口,驾驶距离是两点间的直线距离吗?显然不是,除非你能穿越大楼。而实际驾驶距离就是这个“曼哈顿距离”,此即曼哈顿距离名称的来源, 同时,曼哈顿距离也称为城市街区距离(City Block distance)。
二维平面两点a(x1,y1)与b(x2,y2)间的曼哈顿距离
$$d_{12}=|x_1-x_2|+|y_1-y_2|$$
两个n维向量a(x11,x12,…,x1n)与 b(x21,x22,…,x2n)间的曼哈顿距离
$$d_{12}=\sum_{k=1}^{n}|x_{1k}-x_{2k}|$$
切比雪夫距离,若二个向量或二个点p 、and q,其座标分别为Pi及qi,则二者之间的切比雪夫距离定义以下:
$$D_{Chebyshev}(p,q)=max_i(|p_i-q_i|)$$
这也等于如下Lp度量的极值:$\lim_{x \to \infty}(\sum_{i=1}^{n}|p_i-q_i|^k)^{1/k}$,所以切比雪夫距离也称为L∞度量。
以数学的观点来看,切比雪夫距离是由一致范数(uniform norm)(或称为上确界范数)所衍生的度量,也是超凸度量(injective metric space)的一种。
在平面几何中,若二点p及q的直角坐标系坐标为(x1,y1)及(x2,y2),则切比雪夫距离为:
$$D_{Chess}=max(|x_2-x_1|,|y_2-y_1|)$$
玩过国际象棋的朋友或许知道,国王走一步可以移动到相邻的8个方格中的任意一个。那么国王从格子(x1,y1)走到格子(x2,y2)最少须要多少步?。你会发现最少步数老是max( | x2-x1 | , | y2-y1 | ) 步 。有一种相似的一种距离度量方法叫切比雪夫距离。
二维平面两点a(x1,y1)与b(x2,y2)间的切比雪夫距离 :
$$d_{12}=max(|x_2-x_1|,|y_2-y_1|)$$
两个n维向量a(x11,x12,…,x1n)与 b(x21,x22,…,x2n)间的切比雪夫距离:
$$d_{12}=max_i(|x_{1i}-x_{2i}|)$$
这个公式的另外一种等价形式是
$$d_{12}=lim_{k\to\infin}(\sum_{i=1}^{n}|x_{1i}-x_{2i}|^k)^{1/k}$$
闵可夫斯基距离(Minkowski Distance),闵氏距离不是一种距离,而是一组距离的定义。
两个n维变量a(x11,x12,…,x1n)与 b(x21,x22,…,x2n)间的闵可夫斯基距离定义为:
$$d_{12}=\sqrt[p]{\sum_{k=1}^{n}|x_{1k}-x_{2k}|^p}$$
其中p是一个变参数。 当p=1时,就是曼哈顿距离 当p=2时,就是欧氏距离 当p→∞时,就是切比雪夫距离
根据变参数的不一样,闵氏距离能够表示一类的距离。
标准化欧氏距离,标准化欧氏距离是针对简单欧氏距离的缺点而做的一种改进方案。标准欧氏距离的思路:既然数据各维份量的分布不同,那先将各个份量都“标准化”到均值、方差相等。至于均值和方差标准化到多少,先复习点统计学知识。
假设样本集X的数学指望或均值(mean)为m,标准差(standard deviation,方差开根)为s,那么X的“标准化变量”X*表示为:(X-m)/s,并且标准化变量的数学指望为0,方差为1。 即,样本集的标准化过程(standardization)用公式描述就是:
$$X^*=\frac{X-m}{s}$$
标准化后的值 = ( 标准化前的值 - 份量的均值 ) /份量的标准差 通过简单的推导就能够获得两个n维向量a(x11,x12,…,x1n)与 b(x21,x22,…,x2n)间的标准化欧氏距离的公式:
$$d_{12}=\sqrt{\sum_{k=1}^{n}(\frac{x_{1k}-x_{2k}}{s_k})^2}$$
马氏距离
有M个样本向量X1~Xm,协方差矩阵记为S,均值记为向量μ,则其中样本向量X到u的马氏距离表示为:
$$D(X)=\sqrt{(X-u)^TS^{-1}(X_i-X_j)}$$
若协方差矩阵是单位矩阵(各个样本向量之间独立同分布),则公式就成了,也就是欧氏距离了:
$$D(X_i,X_j)=\sqrt{(X_i-X_j)^T(X_i-X_j)}$$
若协方差矩阵是对角矩阵,公式变成了标准化欧氏距离。
马氏距离的优缺点:量纲无关,排除变量之间的相关性的干扰。
巴氏距离
在统计中,巴氏距离距离测量两个离散或连续几率分布的类似性。它与衡量两个统计样品或种群之间的重叠量的巴氏距离系数密切相关。巴氏距离距离和巴氏距离系数以20世纪30年代曾在印度统计研究所工做的一个统计学家A. Bhattacharya命名。同时,Bhattacharyya系数能够被用来肯定两个样本被认为相对接近的,它是用来测量中的类分类的可分离性。
对于离散几率分布 p和q在同一域 X,它被定义为:
$$D_B(p,q)=-ln(BC(p,q))$$
其中:
$$BC(p,q)=\sum_{x\in_{}X}\sqrt{p(x)q(x)}$$
是Bhattacharyya系数。
汉明距离
两个等长字符串s1与s2之间的汉明距离定义为将其中一个变为另一个所须要做的最小替换次数。例如字符串“1111”与“1001”之间的汉明距离为2。应用:信息编码(为了加强容错性,应使得编码间的最小汉明距离尽量大)。
夹角余弦
几何中夹角余弦可用来衡量两个向量方向的差别,机器学习中借用这一律念来衡量样本向量之间的差别。
在二维空间中向量A(x1,y1)与向量B(x2,y2)的夹角余弦公式:
$$cos\theta=\frac{x_1x_2+y_1y_2}{\sqrt{x_1^2+y_1^2}\sqrt{x_2^2+y_2^2}}$$
两个n维样本点a(x11,x12,…,x1n)和b(x21,x22,…,x2n)的夹角余弦:
$$cos\theta=\frac{a*b}{|a||b|}$$
夹角余弦取值范围为[-1,1]。夹角余弦越大表示两个向量的夹角越小,夹角余弦越小表示两向量的夹角越大。当两个向量的方向重合时夹角余弦取最大值1,当两个向量的方向彻底相反夹角余弦取最小值-1。
杰卡德类似系数
两个集合A和B的交集元素在A,B的并集中所占的比例,称为两个集合的杰卡德类似系数,用符号J(A,B)表示。杰卡德类似系数是衡量两个集合的类似度一种指标。
$$J(A,B)=\frac{|A\cap_{}B|}{|A\cup_{}B|}$$
与杰卡德类似系数相反的概念是杰卡德距离:
$$J_{\delta}(A,B)=1-J(A,B)=\frac{|A\cup_{}B|-|A\cap_{}B|}{|A\cup_{}B|}$$
皮尔逊系数
在统计学中,皮尔逊积矩相关系数用于度量两个变量X和Y之间的相关(线性相关),其值介于-1与1之间。一般状况下经过如下取值范围判断变量的相关强度:
0.8-1.0 极强相关 0.6-0.8 强相关 0.4-0.6 中等程度相关 0.2-0.4 弱相关 0.0-0.2 极弱相关或无相关
简单说来,各类“距离”的应用场景简单归纳为,
在实际应用中,K值通常取一个比较小的数值,例如采用交叉验证法(简单来讲,就是一部分样本作训练集,一部分作测试集)来选择最优的K值。
Kd-树是K-dimension tree的缩写,是对数据点在k维空间(如二维(x,y),三维(x,y,z),k维(x1,y,z..))中划分的一种数据结构,主要应用于多维空间关键数据的搜索(如:范围搜索和最近邻搜索)。本质上说,Kd-树就是一种平衡二叉树。
首先必须搞清楚的是,k-d树是一种空间划分树,说白了,就是把整个空间划分为特定的几个部分,而后在特定空间的部份内进行相关搜索操做。想像一个三维(多维有点为难你的想象力了)空间,kd树按照必定的划分规则把这个三维空间划分了多个空间,以下图所示:
kd树构建的伪代码以下图所示:
再举一个简单直观的实例来介绍k-d树构建算法。假设有6个二维数据点{(2,3),(5,4),(9,6),(4,7),(8,1),(7,2)},数据点位于二维空间内,以下图所示。为了能有效的找到最近邻,k-d树采用分而治之的思想,即将整个空间划分为几个小部分,首先,粗黑线将空间一分为二,而后在两个子空间中,细黑直线又将整个空间划分为四部分,最后虚黑直线将这四部分进一步划分。
6个二维数据点{(2,3),(5,4),(9,6),(4,7),(8,1),(7,2)}构建kd树的具体步骤为:
与此同时,通过对上面所示的空间划分以后,咱们能够看出,点(7,2)能够为根结点,从根结点出发的两条红粗斜线指向的(5,4)和(9,6)则为根结点的左右子结点,而(2,3),(4,7)则为(5,4)的左右孩子(经过两条细红斜线相连),最后,(8,1)为(9,6)的左孩子(经过细红斜线相连)。如此,便造成了下面这样一棵k-d树:
对于n个实例的k维数据来讲,创建kd-tree的时间复杂度为O(knlogn)。
k-d树算法能够分为两大部分,除了上部分有关k-d树自己这种数据结构创建的算法,另外一部分是在创建的k-d树上各类诸如插入,删除,查找(最邻近查找)等操做涉及的算法。下面,我们依次来看kd树的插入、删除、查找操做。
元素插入到一个K-D树的方法和二叉检索树相似。本质上,在偶数层比较x坐标值,而在奇数层比较y坐标值。当咱们到达了树的底部,(也就是当一个空指针出现),咱们也就找到告终点将要插入的位置。生成的K-D树的形状依赖于结点插入时的顺序。给定N个点,其中一个结点插入和检索的平均代价是O(log2N)。
插入的过程以下:
应该清楚,这里描述的插入过程当中,每一个结点将其所在的平面分割成两部分。因比,Chicago 将平面上全部结点分红两部分,一部分全部的结点x坐标值小于35,另外一部分结点的x坐标值大于或等于35。一样Mobile将全部x坐标值大于35的结点以分红两部分,一部分结点的Y坐标值是小于10,另外一部分结点的Y坐标值大于或等于10。后面的Toronto、Buffalo也按照一分为二的规则继续划分。
KD树的删除能够用递归程序来实现。咱们假设但愿从K-D树中删除结点(a,b)。若是(a,b)的两个子树都为空,则用空树来代替(a,b)。不然,在(a,b)的子树中寻找一个合适的结点来代替它,譬如(c,d),则递归地从K-D树中删除(c,d)。一旦(c,d)已经被删除,则用(c,d)代替(a,b)。假设(a,b)是一个X识别器,那么,它得替代节点要么是(a,b)左子树中的X坐标最大值的结点,要么是(a,b)右子树中x坐标最小值的结点。
下面来举一个实际的例子(来源:中国地质大学电子课件,原课件错误已经在下文中订正),以下图所示,原始图像及对应的kd树,如今要删除图中的A结点,请看一系列删除步骤:
要删除上图中结点A,选择结点A的右子树中X坐标值最小的结点,这里是C,C成为根,以下图:
从C的右子树中找出一个结点代替先前C的位置,
这里是D,并将D的左子树转为它的右子树,D代替先前C的位置,以下图:
在D的新右子树中,找X坐标最小的结点,这里为H,H代替D的位置,
在D的右子树中找到一个Y坐标最小的值,这里是I,将I代替原先H的位置,从而A结点从图中顺利删除,以下图所示:
从K-D树中删除一个结点是代价很高的,很清楚删除子树的根受到子树中结点个数的限制。用TPL(T)表示树T总的路径长度。可看出树中子树大小的总和为TPL(T)+N。 以随机方式插入N个点造成树的TPL是O(N*log2N),这就意味着从一个随机造成的K-D树中删除一个随机选取的结点平均代价的上界是O(log2N) 。
k-d树查询算法的伪代码以下所示:
我写了一个递归版本的二维kd tree的搜索函数你对比的看看:
举例
星号表示要查询的点查询点(2,4.5)。经过二叉搜索,顺着搜索路径很快就能找到最邻近的近似点。而找到的叶子节点并不必定就是最邻近的,最邻近确定距离查询点更近,应该位于以查询点为圆心且经过叶子节点的圆域内。为了找到真正的最近邻,还须要进行相关的‘回溯'操做。也就是说,算法首先沿搜索路径反向查找是否有距离查询点更近的数据点。
实例点是随机分布的,那么kd树搜索的平均计算复杂度是O(logN),这里的N是训练实例树。因此说,kd树更适用于训练实例数远大于空间维数时的k近邻搜索,当空间维数接近训练实例数时,它的效率会迅速降低,一降降到“解放前”:线性扫描的速度。
也正由于上述k最近邻搜索算法的第4个步骤中的所述:“回退到根结点时,搜索结束”,每一个最近邻点的查询比较完成过程最终都要回退到根结点而结束,而致使了许多没必要要回溯访问和比较到的结点,这些多余的损耗在高维度数据查找的时候,搜索效率将变得至关之地下,那有什么办法能够改进这个原始的kd树最近邻搜索算法呢?
从上述标准的kd树查询过程能够看出其搜索过程当中的“回溯”是由“查询路径”决定的,并无考虑查询路径上一些数据点自己的一些性质。一个简单的改进思路就是将“查询路径”上的结点进行排序,如按各自分割超平面(也称bin)与查询点的距离排序,也就是说,回溯检查老是从优先级最高(Best Bin)的树结点开始。
仍是以上面的查询(2,4.5)为例,搜索的算法流程为:
SIFT+KD_BBF搜索算法,详细参考文末的参考文献。
在k-means或kNN,咱们是用欧氏距离来计算最近的邻居之间的距离。为何不用曼哈顿距离?
**答:**咱们不用曼哈顿距离,由于它只计算水平或垂直距离,有维度的限制。另外一方面,欧式距离可用于任何空间的距离计算问题。由于,数据点能够存在于任何空间,欧氏距离是更可行的选择。例如:想象一下国际象棋棋盘,象或车所作的移动是由曼哈顿距离计算的,由于它们是在各自的水平和垂直方向的运动。
KD-Tree相比KNN来进行快速图像特征比对的好处在哪里?
答:极大的节约了时间成本.点线距离若是 > 最小点,无需回溯上一层,若是<,则再上一层寻找。
做者:@mantchs
GitHub:https://github.com/NLP-LOVE/ML-NLP
欢迎你们加入讨论!共同完善此项目!群号:【541954936】<a target="_blank" href="//shang.qq.com/wpa/qunwpa?idkey=863f915b9178560bd32ca07cd090a7d9e6f5f90fcff5667489697b1621cecdb3"><img border="0" src="http://pub.idqqimg.com/wpa/images/group.png" alt="NLP面试学习群" title="NLP面试学习群"></a>
原文出处:https://www.cnblogs.com/mantch/p/11287075.html