在 k − N N 算 法 原 理 k-NN算法原理 k−NN算法原理这篇文章中我们讲述了 k − N N k-NN k−NN算法的实现过程以及优缺点,优点简单易实现,缺点要计算输入实例与训练集中每个样本之间的距离,计算量大。为了优化 k − N N k-NN k−NN算法的计算过程,有人提出了 k − d 树 优 化 搜 索 过 程 k-d树优化搜索过程 k−d树优化搜索过程。下面我们来看一下 k − d k-d k−d树的原理以及实现过程。
k − d k-d k−d树构建原理
设
x
i
∈
X
=
R
n
,
i
=
{
1
,
2
,
3
,
.
.
.
,
N
}
,
N
x_i\in\mathcal{X}=R^n,i=\{1,2,3,...,N\},N
xi∈X=Rn,i={1,2,3,...,N},N为训练集样本数量,
n
n
n为特征向量
x
i
x_i
xi的维度。
x
i
(
l
)
x_i^{(l)}
xi(l)是
x
i
x_i
xi向量第
l
l
l个值。其中
l
∈
{
1
,
2
,
3
,
.
.
.
,
n
}
l\in\{1,2,3,...,n\}
l∈{1,2,3,...,n}。
(1)将训练集中所有点按
x
(
1
)
x^{(1)}
x(1)的大小进行排序,取得
x
(
1
)
x^{(1)}
x(1)大小处于中间的那个样本实例。作为第一个节点。根结点
(2)接下来,在
x
(
1
)
x^{(1)}
x(1)小于中间值和
x
(
1
)
x^{(1)}
x(1)大于中间值的两个区域,分别按
x
(
2
)
x^{(2)}
x(2)大小进行排序,然后分别求出两边的
x
(
2
)
x^{(2)}
x(2)中间值的样本实例。将这两个样本点作为第一步中得到的根结点的两个叶子节点
(3)假设
n
=
2
n=2
n=2,则训练集中样本实例都是二维的特征向量。经过以上过程之后如果还有点。则继续以
x
(
1
)
x^{(1)}
x(1)划分第2步中得到的区域并作为第2步得到的点的叶子节点。
(4)以此类推,最终得到一棵平衡二叉树。
k − d k-d k−d树构建过程图示
设样本空间
X
=
{
(
2
,
3
)
,
(
4
,
7
)
,
(
5
,
4
)
,
(
7
,
2
)
,
(
8
,
1
)
,
(
9
,
6
)
,
(
10
,
8
)
}
\mathcal{X}=\{(2,3),(4,7),(5,4),(7,2),(8,1),(9,6),(10,8)\}
X={(2,3),(4,7),(5,4),(7,2),(8,1),(9,6),(10,8)},按照
k
−
d
k-d
k−d树原理我们可得以下树形结构
k − d k-d k−d树的搜索过程
假设输入
x
∈
R
n
x\in R^n
x∈Rn,
k
−
d
k-d
k−d树形状如上图。
(1)从根结点出发,在根结点时,比较输入实例
x
(
1
)
x^{(1)}
x(1)与根结点
x
1
(
1
)
x_1^{(1)}
x1(1)大小比较,如小于根结点特征向量的第一个值,走到根结点左边的子节点。如大于根结点特征向量的第一个值,则走到根结点右边的子节点。确定了第二个节点位置,假设第二个位置为
x
2
x_2
x2,在第二个位置后比较输入实例
x
(
2
)
x^{(2)}
x(2)与
x
2
(
2
)
x_2^{(2)}
x2(2)的大小并确定第三个位置。以此循环类推,知道最后直到叶子节点为止。
(2)以第一步搜索到的叶子节点为输入实例的“当前最近点”,回退到父节点。计算与父节点的距离,并与“当前最近点”进行对比,如果更短则将父节点作为“当前最近点”。
(3)计算“当前最近点”与父节点的另外一边区域是否有交集。如果有交集则去另外一个另外一个区域进行递归搜索,看是否有更近的邻居。如果没有交集则继续向上回退并重复执行第2步。
(4)直到回退到根结点,算法结束,得到最近邻。
k − d k-d k−d树的搜索图示
设样本空间
X
=
{
(
2
,
3
)
,
(
4
,
7
)
,
(
5
,
4
)
,
(
7
,
2
)
,
(
8
,
1
)
,
(
9
,
6
)
,
(
10
,
8
)
}
\mathcal{X}=\{(2,3),(4,7),(5,4),(7,2),(8,1),(9,6),(10,8)\}
X={(2,3),(4,7),(5,4),(7,2),(8,1),(9,6),(10,8)},搜索点为
(
2
,
4.5
)
(2,4.5)
(2,4.5)。问题:找出这个点的最临近点。
(1)在坐标系中划出区域,蓝色数字部分表示的他们在第几步被划分出区域,对应的也就是在二叉树中的第几层。红色的字母是每个点的代号。绿色点X是需要搜索的点。
(2)从
A
A
A点出发,根据
k
−
d
k-d
k−d树搜索原理,我们找到的叶子节点为
D
(
4
,
7
)
D(4,7)
D(4,7)。计算搜索点
(
2
,
4.5
)
(2,4.5)
(2,4.5)与点
D
D
D的欧式距离为3.202。现在,D为最邻近点。
(3)回退到
D
D
D的父节点
B
B
B,计算与
B
B
B的距离为3.041。对比发现
B
B
B的距离更近,此时将
B
B
B更新为最邻近点。
(4)以
X
X
X为圆心,以
X
X
X到最邻近点的直线距离为半径做圆。看是否与
B
B
B的另外一侧有交集,这里是有的。如下图:
(5)去
B
B
B的另外一侧开始搜索。这里我有个小疑问,另外一侧是搜索所有点吗?还是一样依照这种规则先找到叶子节点进行回退呢?还是会依照什么不一样的规则呢?如果有直到的可以评论告诉博主。谢谢
(6)第5步搜索到
E
(
2
,
3
)
E(2,3)
E(2,3),与输入样本点距离为1.5。更新最邻近点为
E
E
E。此时继续回退到点
A
A
A,计算距离大于1.5,
E
E
E保持为最邻近点。此时点
E
E
E与搜索点
x
x
x组成的圆不与点
A
A
A所在的割平面相交。
A
A
A为根结点。
(7)算法结束,
E
E
E为最邻近点。
在这里我提醒一句,我们在看算算法时尽量遵循奥卡姆剃刀法则,能在低维得到结论的绝对不要去高维空间中理解。所以我的示例都在二维坐标系中进行。