转自小狼狗的KNN面试问题的总结
1.简述一下KNN算法的原理
KNN既可以用于分类,也可以用于回归。本身没有显示的模型训练,多数情况用于分类算法。KNN算法我们主要要考虑三个重要的要素,对于固定的训练集,只要这三点确定了,算法的预测方式也就决定了。这三个最终的要素是k值的选取,距离度量的方式和分类决策规则。
1,K值的选择一般选择一个较小的值,这取决于数据量的大小和数据维度。通常K为3~10.一种常见的做法就是设置K等于训练集中样本数量的平方根。但是呢这个不一定有交叉验 证出来的好,所以呀,数据量不大,在电脑可以跑得动的前提下还是乖乖用交叉验证吧。
选择较小的k值,就相当于用较小的领域中的训练实例进行预测,训练误差会减小,只有与输入实例较近或相似的训练实例才会对预测结果起作用,与此同时带来的问题是泛化误差会增大,换句话说,K值的减小就意味着整体模型变得复杂,容易发生过拟合;
选择较大的k值,就相当于用较大领域中的训练实例进行预测,其优点是可以减少泛化误差,但缺点是训练误差会增大。这时候,与输入实例较远(不相似的)训练实例也会对预测器作用,使预测发生错误,且K值的增大就意味着整体的模型变得简单。
一个极端是k等于样本数m,则完全没有分类,此时无论输入实例是什么,都只是简单的预测它属于在训练实例中最多的类,模型过于简单。
2,距离度量的方式有很多,欧式距离是闵可夫斯基距离距离在p=2时的特例,而曼哈顿距离是p=1时的特例。不做详细接招
3,决策规则,在分类中一般用投票,回归中一般用均值。
KNN的暴力破解法:在预测样本的时候,将计算预测样本和所有训练集中的样本的距离,然后计算出最小的k个距离即可,接着多数表决,很容易做出预测。这个方法的确简单直接,在样本量少,样本特征少的时候有效。但是在实际运用中很多时候用不上,为什么呢?因为我们经常碰到样本的特征数有上千以上,样本量有几十万以上,如果我们这要去预测少量的测试集样本,算法的时间效率很成问题。因此,这个方法我们一般称之为蛮力实现。比较适合于少量样本的简单模型的时候用。
2.KNN算法有哪些优点和缺点?
优:1,该算法比较适用于样本容量比较大的类域的自动分类,而那些样本容量较小的类域采用这种算法比较容易产生误分
2,由于KNN方法主要靠周围有限的邻近的样本,而不是靠判别类域的方法来确定所属类别的,因此对于类域的交叉或重叠较多的待分样本集来说,KNN方法较其他方法更为适合
3,可用于非线性分类
4, 训练时间复杂度比支持向量机之类的算法低,仅为O(n)
5,和朴素贝叶斯之类的算法比,对数据没有假设,准确度高,对异常点不敏感
缺:1,计算量大,尤其是特征数非常多的时候
2,样本不平衡的时候,对稀有类别的预测准确率低
3,KD树,球树之类的模型建立需要大量的内存
4,使用懒散学习方法,基本上不学习,导致预测时速度比起逻辑回归之类的算法慢
5,相比决策树模型,KNN模型可解释性不强
3.k-d树实现原理
参考K近邻法(KNN)原理小结
缺点: 如果实例点是随机分布的,那么kd树搜索的平均计算复杂度是O(logN),这里的N是训练实例树。所以说,kd树更适用于训练实例数远大于空间维数时的k近邻搜索,当空间维数接近训练实例数时,它的效率会迅速下降,一降降到“解放前”:线性扫描的速度。 也正因为上述k最近邻搜索算法的第4个步骤中的所述:“回退到根结点时,搜索结束”,每个最近邻点的查询比较完成过程最终都要回退到根结点而结束,而导致了许多不必要回溯访问和比较到的结点,这些多余的损耗在高维度数据查找的时候,搜索效率将变得相当之低下
4.基于k-d树缺点改进的BBF算法
BBF算法是在k-d树建立好的基础上,在我们搜索的过程中加入一个队列。
为了便于说明,这里例一个简单的例子
以上面的查询(2,4.5)为例,搜索的算法流程为:
1,将(7,2)压人优先队列中;
2,提取优先队列中的(7,2),由于(2,4.5)位于(7,2)分割超平面的左侧,所以检索其左子结点(5,4)。同时,根据BBF机制”搜索左/右子树,就把对应这一层的兄弟结点即右/左结点存进队列”,将其(5,4)对应的兄弟结点即右子结点(9,6)压人优先队列中,此时优先队列为{(9,6)},最佳点为(7,2);然后一直检索到叶子结点(4,7),此时优先队列为{(2,3),(9,6)},“最佳点”则为(5,4);
3,提取优先级最高的结点(2,3),重复步骤2,直到优先队列为空。
5.不平衡的样本可以给KNN的预测结果造成哪些问题,有没有什么好的解决方式?
样本不平衡的时候,对稀有类别的预测准确率低。有时候我们会遇到这样的问题,即样本中某系类别的样本非常的少,甚至少于K,这导致稀有类别样本在找K个最近邻的时候,会把距离其实较远的其他
样本考虑进来,而导致预测不准确。为了解决这个问题,我们限定最近邻的一个最大距离,也就是说,我们只在一个距离范围内搜索所有的最近邻,这避免了上述问题。这个距离我们一般称为限定半径。
6.为了解决KNN算法计算量过大的问题,可以使用分组的方式进行计算,简述一下该方式的原理。
先将样本按距离分解成组,获得质心,然后计算未知样本到各质心的距离,选出距离最近的一组或几组,再在这些组内引用KNN。
本质上就是事先对已知样本点进行剪辑,事先去除对分类作用不大的样本,该方法比较适用于样本容量比较大时的情况。
7.KD树建立过程中切分维度的顺序是否可以优化?
可以先对每一维度求方差,方差大说明数据分布越分散,则从方差大的维度来逐步切分,可以取得更好的切分效果及树的平衡性。
8.KD树每一次继续切分都要计算该子区间在需切分维度上的中值,计算量很大,有什么方法可以对其进行优化?
在构建KD树前,依据每一维度先排序,在之后的切分中直接使用
9.为了防止某一维度的数据较大(50,100),而另外一维度的数据较小(0.1,0.2)而产生的距离计算的问题,需要进行归一化。
10.KNN总结
11.简述KNN最近邻分类算法的过程?