K近邻法
KNN是机器学习的基本算法,也是原理最简单的算法之一,既可以做分类也可以做回归,作为惰性学习算法,KNN不产生模型,算法的原理也很简单,现有一个数据集,里面很有多个有标签的样本,这些样本的共有的特征构成了一个多维空间,当有一个需要预测的样本出现时,我们把这个样本放入到多维空间中,找到离这个样本点最近的k个样本,这些样本叫做最近邻,我们采用少数服从多数,一点一票的原理来判断,在最近邻中最多标签的类别就是这个样本点的标签类别,越相近越相似
算法解析
上图是书中给出的算法流程,很好理解,根据距离公式在训练集中找到了与我们需要给出预测的样本点x距离最近的k个点,涵盖这k个点的x的邻域记作N
在使用多数表决的方式来确定预测点的类别,式3.1表示对于每一个数据集的标签Cj,进行I(yi=Cj)求和,返回数目最多的标签类别,就是我们需要预测的样本点x的类别。
距离公式
KD树
由于传统KNN算法需要将待预测样本点x与所有样本计算距离,这在数据集较大的情况下非常难办,因为要计算的量实在是太多了,所以就提出了KD树,KD树是二叉树,表示了对k维空间的一个划分,构造KD树的流程就是不断地用垂直于坐标轴的超平面把k维空间切分,构造成了一系列k维超矩阵区域,KD树的每一个节点对应了一个超矩阵区域。
算法的流程书中介绍的很详细,唯一有出入的就是在切分数据集时坐标轴选择的方式,本文根据样本点每一个特征的数据集的方差大小来选择切分的维度,选择方差大的特征来切分,这样可以提高效率。
搜索KD树
流程如下 根据需要预测的样本点x,在构建好的KD树中从根节点开始找到与x距离最小的叶子节点,将该叶子节点作为暂时的最近点,开始回退,首先会退到该叶子节点的父节点,检查以最近点与样本点x为半径的超球体,是否与该叶子节点的兄弟节点的区域相交,如果相交,则有可能存在更近点,就找到叶子节点的兄弟节点,计算距离是否比最近点要小,如果比最近点要小,则更新最近点;如果不相交,则再回退上一级父节点,如果更新之后的超球体与上一级父节点的另一个子节点的区域相交,则在该子节点的区域内寻找是否有距离更小的点,以此类推。
代码
代码包含了传统的KNN分类器和KD树的建立方法
import numpy as np
import pandas as pd
def KNN(train,test,k):
m,n=train.shape
m1,n1=test.shape
result=[]
for i in range(m1):
dist=((train.iloc[:,:-1]-test.iloc[i,:-1]