K近邻算法(KNN)推导分析

Knn和kd树介绍

author:DivinerShi

KNN算法

优点:
直观,简单,可以用来做分类也可以用来做回归
可用于非线性分类,训练时间复杂度为O(n)
准确度高,对数据没有假设,对outier不敏感。
缺点:
计算量大,样本不平衡问题难处理,需要大量的内存
算法解释:
给定一个数据集,对新的输入样本,在数据集中找到与新的输入样本距离最近的k个样本,将这k个样本中最多数属于某个类的那个类别当作新的输入样本的类别。
即在距离最近的k个邻域内,去确定新的输入样本x的类别y:
这里写图片描述
N为类别c的个数,K为选择的邻域内样本个数,I为指示函数,即当时I为1,否则为0。

当k为1,是该算法就是最近邻算法,k的选择会一定程度影响算法性能,当k很小的时候,算法很容易受到噪声的影响,使得算法的Bias较大,而且如果数据集很大,意味着模型很复杂,很容易过拟合

如果k=N,那么就是整个数据集了,那么无论输入的是啥样本,选择的都是整个数据集中数量最多的那个类别。所以当k选择较大的时候,此时模型过于简单,Variance过大,容易欠拟合

距离度量:

最常见的是欧式距离,也可以曼哈顿距离,或者其他Lp距离,看具体问题具体选择。

实现:

K近邻最简单的实现就是直接遍历整个数据集,叫线性扫描(linear scan),但是这样的话,需要将输入的样本和数据集中每个样本进行度量距离,如果数据集很大的话,计算是非常耗时的。所以比较常见的是KD树

KD树

Kd树是一个二叉树,利用树来对k维空间进行划分。

构造KD树:

1.先计算每个特征的方差(数据方差大说明沿着这个座标轴方向上数据点分散的比较开,在这个方向上进行数据分割可以获得最大的区分度),降序排列构建二叉树。
2.计算每个特征的中位值(最中间的作为分割节点),将中位值所在的节点作为分割节点,比它大的放右节点,小的放左节点。
3.以此递归,直到最后要划分的子空间中只有一个数据点。

搜索:

1.搜索最近邻点,沿着路径搜索即可,找到叶子节点,计算搜索节点和叶子以搜索节点和叶子节点的距离保存为最近距离。
2.回溯,比较上一节点和搜索节点距离与之前的最近距离的大小,比当前最近距离小的话,替换当前节点所计算的距离为最小距离。去该节点的另一子节点进行搜索,判断是否还有更小的距离存在。以此回溯。
3.到根节点时结束。

不足

该算法在分类时有个重要的不足是,当样本不平衡时,即:一个类的样本容量很大,而其他类样本数量很小时,很有可能导致当输入一个未知样本时,该样本的K个邻居中大数量类的样本占多数。

当维数过大时,直接利用kd树快速检索的性能急剧下降。假设数据集的维数k,那么数据集的规模N最好远大于2的k次方,才能达到高效搜索。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章