算法描述
首先描述下KNN算法的使用场景,假设我们有数据集:
T={(x1,y1),(x2,y2),...,(xn,yn)}
其中,x∈Rn 为实例的特征向量,y∈{c1,c2,...,cK} 为实例的分类。如果此时给定一个特征向量x,我们需要输出x所属的分类。
KNN假设我们的实例数据集已经确定了,即每个实例的特征向量都有对应的分类,因此KNN算法没有训练过程。我们要做的是,给定一个邻近数值k,然后计算选择出和需要分类的向量x最相近的k个实例,记为Nk(x),然后根据一定的决策规则,从Nk(x)中决定x所属的类别
算法模型说明
距离度量
这是指输入的向量x与所有实例的距离,有多种形式,这里我们给出最长用的Lp距离:
Lp(xi,xj)=(l=1∑n∣xi(l)−xj(l)∣p)p1
这里,p≥1。如果p=1,则是曼哈顿距离;p=2,则是欧几里得距离。
k值选择
k值如果过小,那么只有和输入数据距离很近的实例才会发生作用,此时模型会对输入数据的邻近点非常敏感。如果邻近点是噪声数据点,则数据波动会很大。从另一个角度将,k值小意味着模型会相对复杂,容易出现过拟合的现象。
k值如果过大,这种情况比较容易理解,假设k和实例数一样,那么会直接匹配到最近点,此时说明模型太简单了,实际意义不大。
实际中,我们一般选择一个相对较小的k值,然后交叉验证即可
分类决策规则
假设我们选择出了最近的k个实例,此时需要确认输入向量到底属于哪个分类。一般来说,我们通过多数表决的方式决定。
算法实现
数据量比较大的情况下,直接遍历数据集是不显示的,因为此时的复杂度是O(N)级别的。这里引入kd−Tree的方式,对已有的数据集建立kd-tree索引,把复杂度搜索的复杂度降到logN。
kd−Tree的wiki