Topic:
- KNN 算法原理
- 常用距离算法
- 决策规则
- Kd 树
一、KNN 算法原理
什么是最近邻算法(NN) ?
最近邻算法(Nearest Neighbor,简称:NN):其针对未知类别数据 ,找到与其距离最近的数据 ,将 划入 的分类中
如上图所示,通过计算数据 (未知样本)和已知类别 (已知样本)之间的距离,判断 与不同训练集的相似度,最终判断 的类别。显然,这里将绿色未知样本类别判定与红色已知样本类别相同较为合适。
什么是K-近邻算法(K-NN) ?
K-近邻(K-Nearest Neighbors,简称:KNN)算法是最近邻(NN)算法的一个推广。
NN 算法中只依赖 1 个样本进行决策,在分类时过于绝对,会造成分类效果差的情况,为解决 NN 算法的缺陷,KNN 算法采用 K 个相邻样本的方式共同决策未知样本的类别,这样在决策中容错率相对于 NN 算法就要高很多,分类效果也会更好。
对于未知测试样本(图中 ?所示)采用 KNN 算法进行分类,首先计算未知样本和训练样本之间的相似度,找出最近 K 个相邻样本(在图中 K 值为 3,圈定距离 ?最近的 3 个样本),再根据最近的 K 个样本最终判断未知样本的类别
二、常用距离算法
距离度量
两个样本的相似度 通过 样本之间特征值的距离进行表示。
若两个样本距离越大 ↑ ,两个相似度 ↓
最常用的距离公式:曼哈顿距离 和 欧式距离
(1)曼哈顿距离
曼哈顿距离又称马氏距离,出租车距离,是计算距离最简单的方式之一。
"""曼哈顿距离计算
"""
import numpy as np
def d_man(x, y):
d = np.sum(np.abs(x - y))
return d
x = np.array([3.1, 3.2])
print("x:", x)
y = np.array([2.5, 2.8])
print("y:", y)
d_man = d_man(x, y)
print(d_man)
(2)欧式距离
欧式距离源自 维欧氏空间中两点之间的距离公式。表达式如下:
其中:
- , :两个数据点
- :每个数据中有 个特征值
- :数据 的第 个特征值
公式表示为将两个数据 和 中的每一个对应特征值之间差值的平方,再求和,最后开平方,便是欧式距离。
"""欧氏距离的计算
"""
import numpy as np
def d_euc(x, y):
d = np.sqrt(np.sum(np.square(x - y)))
return d
x = np.random.random(10) # 随机生成10个数的数组作为x特征的值
print("x:", x)
y = np.random.random(10)
print("y:", y)
distance_euc = d_euc(x, y)
print(distance_euc)
三、决策规则
上面我们通过 K-NN
得到了 K 个相邻的样本,那如何通过这 K 个邻居来判断 未知样本的最终类别?
可以根据数据特征对决策规则进行选取。
- 多数表决法:多数表决法类似于投票的过程,也就是在 K 个邻居中选择类别最多的种类作为测试样本的类别。
- 加权表决法:根据距离的远近,对近邻的投票进行加权,距离越近则权重越大,通过权重计算结果最大值的类为测试样本的类别。
"""多数表决法
"""
import operator
def majority_voting(class_count):
sorted_class_count = sorted(
class_count.items(), key=operator.itemgetter(1), reverse=True)
return sorted_class_count
arr = {'A': 3, 'B': 2, "C": 6, "D": 5}
majority_voting(arr)
四、Kd树
为了提高 KNN 搜索效率,减少计算距离的次数,可以通过构建 Kd 树的方法提高计算效率
什么是Kd树 ?
Kd 树(英文:K-dimension tree)是一种对 K 维空间中的实例点进行存储以便对其进行快速检索的树形数据结构。
Kd 树是一种二叉树
对 K 维空间的一个划分,构造 Kd 树相当于不断地用垂直于坐标轴的超平面将 K 维空间切分,构成一系列的 K 维超矩形区域。
Kd 树的每个结点对应于一个 K 维超矩形区域。
利用Kd 树可以省去对大部分数据点的搜索,从而减少搜索的计算量。
以下便是 Kd 树的最邻近搜索步骤:
- 从根节点开始,递归的往下移。往左还是往右的决定方法与插入元素的方法一样(如果输入点在分区面的左边则进入左子节点,在右边则进入右子节点)。
- 一旦移动到叶节点,将该节点当作”目前最佳点”。
- 解开递归,并对每个经过的节点运行下列步骤:
- 如果目前所在点比目前最佳点更靠近输入点,则将其变为目前最佳点。
- 检查另一边子树有没有更近的点,如果有则从该节点往下找
- 当根节点搜索完毕后完成最邻近搜索
那如何 构建 Kd树?
按 训练集中的数据进行切分?