第三章k近邻法
3.1 k k k近邻算法
k
k
k近邻法(k-nearest neighbor,k-NN):基本的分类和回归方法。这里只讨论分类问题。对新的实例,根据其
k
k
k个最近邻的训练实例的类别,通过多数表决等方式进行预测。故不具备显示的学习过程。利用训练数据集对特征空间进行划分,并作为分类的“模型”。
k
k
k近邻法三要素:
k
k
k值的选择、距离度量、分类规则。
算法3.1(
k
k
k近邻法):
【输入】:训练数据集
T
=
{
(
x
1
,
y
1
)
,
(
x
2
,
y
2
)
,
⋯
,
(
x
N
,
y
N
)
}
T=\{(x_1,y_1),(x_2,y_2),\dotsb,(x_N,y_N)\}
T={(x1,y1),(x2,y2),⋯,(xN,yN)}
其中,
x
i
∈
X
⊆
R
n
x_i \isin{\mathcal{X}} \sube{{\bf R}^n}
xi∈X⊆Rn为实例的特征向量,
y
i
∈
Y
=
{
c
1
,
c
2
,
⋯
,
c
k
}
y_i \in{\mathcal{Y}}=\{c_1,c_2,\dotsb,c_k\}
yi∈Y={c1,c2,⋯,ck}为实例的类别,
i
=
1
,
2
,
⋯
,
N
i=1,2,\dotsb,N
i=1,2,⋯,N;实例特征向量
x
x
x;
【输出】:实例
x
x
x所属的类
y
y
y。
(1)根据给定的距离度量,在训练集
T
T
T 中找出与
x
x
x 最邻近的
k
k
k 个点,涵盖这
k
k
k 个点的
x
x
x 的领域记作
N
k
(
x
)
N_k(x)
Nk(x);
(2)在
N
k
(
x
)
N_k(x)
Nk(x) 中根据分类决策规则(如多数表决)决定
x
x
x 的类别
y
y
y:
y
=
arg
max
c
j
∑
x
i
∈
N
k
(
x
)
I
(
y
i
=
c
j
)
,
i
=
1
,
2
,
⋯
,
N
;
j
=
1
,
2
,
⋯
,
K
(3.1)
y=\arg\underset{c_j}{\max}\sum_{x_i\in{N_k(x)}}{I(y_i=c_j)},i=1,2,\dotsb,N;j=1,2,\dotsb,K \tag{3.1}
y=argcjmaxxi∈Nk(x)∑I(yi=cj),i=1,2,⋯,N;j=1,2,⋯,K(3.1)
式(3.1)中,
I
I
I为指示函数,即当
y
i
=
c
i
y_i=c_i
yi=ci时
I
I
I为1,否则为0.
ps:
k
=
1
k=1
k=1时为特殊情况,称为 最近邻算法 ,对于输入的实例点
x
x
x,训练数据集中与它最邻近点的类别作为
x
x
x的类。
3.2 k k k近邻模型
k k k近邻法模型对应于对特征空间的划分。当其三要素确定,就是对特征空间进行了划分,确定子空间里的每个点所属的类。
3.2.1 模型
3.2.2 距离度量
L
p
(
x
i
,
y
j
)
=
(
∑
l
=
1
n
∣
x
i
(
l
)
−
y
j
(
l
)
∣
p
)
1
p
,
p
≥
1
L_p(x_i,y_j)={\Biggl(\sum_{l=1}^{n}|x_{i}^{(l)}-y_{j}^{(l)}|^p\Biggr)}^{1\over p} ,p\ge1
Lp(xi,yj)=(l=1∑n∣xi(l)−yj(l)∣p)p1,p≥1
p
=
1
p=1
p=1时,为曼哈顿距离(Manhattan distance)
p
=
2
p=2
p=2时,为欧氏距离(Euclidean distance)
p
=
∞
p= \infty
p=∞时,为切比雪夫距离,各个坐标距离的最大值
3.2.3 k k k值的选择
k
k
k越小,近似误差减小,估计误差增大,整体模型的复杂度提升,容易过拟合。
k
k
k越大,近似误差增大,估计误差减小,整体模型的复制度降低,模型简单,但预测错误增大。
k
=
N
k=N
k=N时,任何输入,都将简单地预测其分类,模型过于简单,忽略了训练实例钟的大量有用信息,不可取。
一般
k
k
k较小,常采用交叉验证法来选取最优
k
k
k值。
3.2.4 分类决策规则
常采用多数表决规则。
若分类的损失函数为0-1损失函数,分类函数为:
f
:
R
n
→
{
c
1
,
c
2
,
⋯
,
c
k
}
f:{\bf R}^n\to \{c_1,c_2,\dotsb,c_k\}
f:Rn→{c1,c2,⋯,ck}那么误分类的概率是:
P
(
Y
≠
f
(
X
)
)
=
1
−
P
(
Y
=
f
(
X
)
)
P(Y\ne f(X))=1-P(Y=f(X))
P(Y=f(X))=1−P(Y=f(X))对给定的实例
x
∈
X
x\in \mathcal X
x∈X,其最近邻的
k
k
k个训练实例点构成集合
N
k
(
x
)
N_k(x)
Nk(x)。如果涵盖
N
k
(
x
)
N_k(x)
Nk(x)的区域的类别是
c
j
c_j
cj,那么误分类率是:
1
k
∑
x
i
∈
N
k
(
x
)
I
(
y
i
≠
c
j
)
=
1
−
1
k
∑
x
i
∈
N
k
(
x
)
I
(
y
i
=
c
j
)
{1\over k}\sum_{x_i\in N_k(x)}I(y_i\ne c_j)=1-{1\over k}\sum_{xi\in N_{k}(x)}I(y_i=c_j)
k1xi∈Nk(x)∑I(yi=cj)=1−k1xi∈Nk(x)∑I(yi=cj)
要使误分类率最小,即经验风险最小,就要使
∑
x
i
∈
N
k
(
x
)
I
(
y
i
=
c
j
)
\sum_{x_i\in N_{k}(x)}I(y_i=c_j)
∑xi∈Nk(x)I(yi=cj)最大,所以多数表决规则等价于经验风险最小化。
3.3 k k k近邻法的实现: k d kd kd树
实现
k
k
k近邻法时,要考虑如何对训练数据进行快速
k
k
k近邻搜索,这点再特征空间的维数大及训练数据容量大时尤其必要。
k
k
k近邻法最简单的实现方法时线性扫描(linear scan)。这时要计算输入实例与每一个训练实例的距离。当训练集很大时,计算非常耗时,这种方法是不可行的。
为了提高
k
k
k近邻搜索的效率,可以考虑使用特殊的结构存储训练数据,以减少计算距离的次数。具体方法很多,这里主要介绍
k
d
kd
kd树(kd tree) 方法。
3.3.1 构造 k d kd kd树
根节点对应于
k
k
k维空间中包含所有实例点的超矩形区域,再通过递归,在超矩形区域(结点)上选择一个坐标轴和在此坐标轴上的一个切分点,确定一个超平面,这个超平面通过选定的切分点且垂直于选定的坐标轴;这时实例被分到两个子区域,分别为树的新结点。重复这个过程直到子区域内没有实例时终止(终止时的结点为叶子结点)。
当切分点时实例点的中位数时,得到的
k
d
kd
kd树是平衡的,平衡的
k
d
kd
kd树搜索时效率未必最优。
算法3.2(构造平衡
k
d
kd
kd树)
【输入】:
k
k
k维空间数据集
T
=
{
x
1
,
x
2
,
⋯
,
x
N
}
T=\{x_1,x_2,\dotsb,x_N\}
T={x1,x2,⋯,xN},其中
x
i
=
(
x
i
1
,
x
i
2
,
⋯
,
x
i
k
)
T
,
i
=
1
,
2
,
⋯
,
N
x_i=(x_{i}^{1},x_{i}^{2},\dotsb,x_{i}^{k})^T,i=1,2,\dotsb,N
xi=(xi1,xi2,⋯,xik)T,i=1,2,⋯,N;
【输出】:
k
d
kd
kd树。
(1)开始:构造根结点,根结点对应于包含
T
T
T的
k
k
k维空间的超矩形区域。
选择
x
1
x^{1}
x1为坐标轴,以
T
T
T中所有实例的
x
1
x^{1}
x1坐标的中位数为切分点,将根结点对应的超矩形区域切分为两个子区域。切分由通过切分点并与坐标轴
x
(
1
)
x^(1)
x(1)垂直的超平面实现。
由根结点生成深度为1的左、右子结点:左子结点对应坐标
x
(
1
)
x^(1)
x(1)小于切分点的子区域,右子结点对应于坐标
x
(
1
)
x^(1)
x(1)大于切分点的子区域。
将落在切分超平面上的实例点保存在根结点。
(2)重复:对深度为
j
j
j的结点,选择
x
(
l
)
x^{(l)}
x(l)为切分的坐标轴,
l
=
j
(
m
o
d
k
)
+
1
l=j(\mod k)+1
l=j(modk)+1,以该结点的区域中所有实例的
x
(
l
)
x^{(l)}
x(l)坐标的中位数为切分点,将该结点对应的超矩形区域切分为两个子区域。切分由通过切分点并与坐标轴
x
(
l
)
x^{(l)}
x(l)垂直的超平面实现。
由该结点生成深度为
j
+
1
j+1
j+1的左、右子结点:左子结点对应坐标
x
(
l
)
x^{(l)}
x(l)小于切分点的子区域,右子结点对应坐标
x
(
l
)
x^{(l)}
x(l)大于切分点的子区域。
将落在切分超平面上的实例点保存在该结点。
(3)直到两个子区域没有实例存在时停止。从而形成
k
d
kd
kd树的区域划分。
3.3.2 搜索 k d kd kd树
如何利用
k
d
kd
kd树进行
k
k
k近邻搜索。在局部区域搜索,以提高效率。
算法3.3(用
k
d
kd
kd树的最近邻搜索)
【输入】:已构造的
k
d
kd
kd树;目标点
x
x
x;
【输出】:
x
x
x的最近邻。
(1)在
k
d
kd
kd树中找出包含目标点
x
x
x的叶结点:从根结点出发,递归地向下访问
k
d
kd
kd树。若目标点
x
x
x当前维的坐标小于切分点的坐标,则移动到左子节点,否则移动到右子节点。直到子结点为叶子结点为止。
(2)以此叶结点为“当前最近点”。
(3)递归地向上回退,在每个结点进行以下操作:
(a)如果该结点保存的实例点比当前最近点距离目标点更近,则以该实例点为“当前最近点”。
(b)当前最近点一定存在于该结点一个子结点对应的区域。检查该子结点的父结点的另一子结点对应的区域是否有更近的点。具体地,检查另一子结点对应的区域是否与以目标结点为球心、以目标点与“当前最近点”间的距离为半径的超球体相交。
如果相交,可能在另一个子结点对应的区域内存在距目标点更近的点,移动到另一个子结点,接着,递归地进行最近邻搜索;
如果不相交,向上回退。
(4)当回退到根结点时,搜索结束。最后的“当前最近点”即为
x
x
x的最近邻点。
若实例点时随机分布的,
k
d
kd
kd树搜索的平均计算复杂度时
O
(
log
N
)
O(\log N)
O(logN),其中
N
N
N是训练实例数。
k
d
kd
kd树适合训练实例数远大于空间维度数时的
k
k
k近邻搜索。当空间维数接近训练实例数时,它的效率会迅速下降,几乎接近线性扫描。
习题
3.2
解: x x x的最近邻点是 ( 2 , 3 ) T (2,3)^T (2,3)T
3.3
解:算法3.3是最近邻算法, k k k近邻算法,需要再加一个容量为 k k k的队列,存储目标点 x x x的 k k k个邻近的点,并每次跟新队列。