本文主要是介绍统计学习-KNN,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
KNN是一种基本的分类(由与该样本最近的k个样本进行投票表决)与回归方法(回归问题:可以将一个样本的k个近邻的平均属性或者加权平均属性赋予该样本)。k值的选择,距离度量以及分类决策规则是KNN的三个基本要素。KNN1968年由Cover和Hart提出。
1.距离的度量
1.1闵可夫斯基距离
闵可夫斯基距离不是距离,是一组距离的定义。
Lp(xi,yi)=(∑nl=1∣∣xli−xlj∣∣p)1p
1.2当 p=2 时,称为欧式距离,即有:
Lp(xi,yi)=(∑nl=1∣∣xli−xlj∣∣2)12
1.3当 p=1 时,称为曼哈顿距离,即有:
Lp(xi,yi)=∑nl=1∣∣xli−xlj∣∣
1.4当 p=∞ 时,称为切比雪夫距离,即有:
Lp(xi,yi)=maxl=1∣∣xli−xlj∣∣
1.5夹角余弦
cos(θ)=xi∗xj|xi|∗|xj|
1.6汉明距离
两个特征向量之间的汉明距离定义为将其中一个变为另外一个所需要作的最小替换次数。例如特征向量“1111”与“1001”之间的汉明距离为2。应用:信息编码(为了增强容错性,应使得编码间的最小汉明距离尽可能大)
2.K值得选择
k值较小的时候,只有与测试样本较近的训练实例才会对预测结果起作用,但是缺点是泛化能力较差,因为如果离测试样本最近的训练实例刚好是噪声,预测就会出错。换句话说,k值得减小意味着整体模型变得复杂,容易发生过拟合。
k值较大的时候,比如k=N(训练样本总数),这种模型就过于简单,无论来了什么样本都将其预测为训练样本中最多的类别。这种模型忽略了训练实例中大量有用的信息。
在实际应用中,k的取值一般较小,然后是通过交叉验证的方法来确定最优k值。
3.分类决策规则
一般用投票的机理决定样本的类别,而多数表决等价于经验风险最小化。
4.kNN的实现:kd树
kNN最简单的实现就是线性扫面,假若存在N个样本,那么时间复杂度就是 O(N) ,利用kd树可以使得时间复杂度为 O(logN)
算法:构建k-d树(createKDTree)
输入:数据点集Data-set和其所在的空间Range(感觉这个Range应该就是split域的值)
输出:Kd,类型为k-d tree
1.If Data-set为空,则返回空的k-d tree
2.调用节点生成程序: (1)确定split域:对于所有描述子数据(特征矢量),统计它们在每个维上的数据方差。假设每条数据记录为64维,可计算64个方差。挑选出最大值,对应的维就是split域的值。数据方差大表明沿该坐标轴方向上的数据分散得比较开,在这个方向上进行数据分割有较好的分辨率; (2)确定Node-data域:数据点集Data-set按其第split域的值排序。位于正中间的那个数据点被选为Node-data。此时新的Data-set' = Data-set \ Node-data(除去其中Node-data这一点)。
3.dataleft = {d属于Data-set' && d[split] ≤ Node-data[split]} Left_Range = {Range && dataleft} dataright = {d属于Data-set' && d[split] > Node-data[split]} Right_Range = {Range && dataright}
4.left = 由(dataleft,Left_Range)建立的k-d tree,即递归调用createKDTree(dataleft,Left_Range)。并设置left的parent域为Kd; right = 由(dataright,Right_Range)建立的k-d tree,即调用createKDTree(dataleft,Left_Range)。并设置right的parent域为Kd。
如果想详细了解KNN以及相关拓展可以参考该文。
这篇关于统计学习-KNN的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!