k近邻可用于分类和回归,在模式识别的生成模型中,对类条件概率模型的非参数估计也有k近邻算法。下面我们主要说k近邻分类,和k近邻对类条件概率模型的非参数估计
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),...,(x_N,y_N)\}
T={(x1,y1),(x2,y2),...,(xN,yN)}
优化目标:
y
=
arg max
c
j
=
∑
x
i
∈
N
k
(
x
)
I
(
y
i
=
c
j
)
,
i
=
1
,
2...
N
;
j
=
1
,
2...
K
y=\argmax_{c_j}=\sum_{x_i\in N_k(x)}I(y_i=c_j),i=1,2...N;j=1,2...K
y=cjargmax=xi∈Nk(x)∑I(yi=cj),i=1,2...N;j=1,2...K
x
i
∈
X
⊆
R
n
x_i\in \mathcal{X} \subseteq \mathcal{R}^n
xi∈X⊆Rn
y
i
∈
Y
=
{
c
1
,
c
2
,
.
.
.
,
c
K
}
y_i\in \mathcal{Y}=\{c_1,c_2,...,c_K\}
yi∈Y={c1,c2,...,cK}为实例类别
N
k
(
x
N_k(x
Nk(x)是某一个样本呢的最近k个样本邻域
2. k近邻模型
k近邻模型的三要素:距离度量、k值的选择、分类决策的规定。
2.1 距离度量
设特征空间
X
\mathcal{X}
X是
n
n
n维实数向量空间
R
n
\mathcal{R}^n
Rn,
x
i
,
x
j
∈
X
,
x
i
,
x
j
x_i,x_j \in \mathcal{X},x_i,x_j
xi,xj∈X,xi,xj的
L
p
L_p
Lp距离定义为:
L
p
(
x
i
,
x
j
)
=
(
∑
l
=
1
n
∣
x
i
(
l
)
−
x
j
(
l
)
∣
p
)
(
1
p
)
,
p
≥
1
L_p(x_i,x_j)=(\sum_{l=1}^n|x_i^{(l)}-x_j^{(l)}|^{p})^{(\frac{1}{p})},p\geq 1
Lp(xi,xj)=(l=1∑n∣xi(l)−xj(l)∣p)(p1),p≥1
-
p
=
2
p=2
p=2时,称为欧式距离
L 2 ( x i , x j ) = ( ∑ l = 1 n ∣ x i ( l ) − x j ( l ) ∣ 2 ) ( 1 2 ) L_2(x_i,x_j)=(\sum_{l=1}^n|x_i^{(l)}-x_j^{(l)}|^{2})^{(\frac{1}{2})} L2(xi,xj)=(l=1∑n∣xi(l)−xj(l)∣2)(21) -
p
=
1
p=1
p=1时,称为曼哈顿距离
L 1 ( x i , x j ) = ∑ l = 1 n ∣ x i ( l ) − x j ( l ) ∣ L_1(x_i,x_j)=\sum_{l=1}^n|x_i^{(l)}-x_j^{(l)}| L1(xi,xj)=l=1∑n∣xi(l)−xj(l)∣ -
p
=
∞
p=\infty
p=∞
L ∞ ( x i , x j ) = max l ∣ x i ( l ) − x j ( l ) ∣ L_\infty(x_i,x_j)=\max_l|x_i^{(l)}-x_j^{(l)}| L∞(xi,xj)=lmax∣xi(l)−xj(l)∣
2.2 k值的选择
- k值选小了:
k小了就相当于用较小的邻域中的训练实例进行预测“学习”近似误差会减小,只有与输入实例较接近的(相似的)训练实例才会对预测结果起作用。但是缺点是“学习”的估计误差会增大。预测结果会对近邻的实例非常敏感。如果紧邻的实例点恰巧是噪声,预测结果就会错。换句话说,k值的减少就意味着整体模型较为复杂,容易发生过拟合 - k值选大了:
如果先择较大的k值,就相当于用较大邻域的训练实例进行预测。其优点是可以减少学习的估计误差,但是缺点是学习的近似误差会增大。这时与输入实例较远的训练实例也会对预测起作用,使预测发生错误。k值的增大就意味着整体的模型变简单。
在应用中,k值一般取一个比较小的数值。通常采用交叉验证方法来选取最优的k值。
2.3 分类决策规则
k近邻法中的分类决策规则往往是多数表决,即由输入实例的k个近邻的训练实例中的多数决定输入实例的类。
如果分类损失函数为0-1函数,分类函数为:
f
:
R
n
−
>
{
c
1
,
c
2
,
.
.
.
,
c
k
}
f:\mathcal{R}^n->\{c_1,c_2,...,c_k\}
f:Rn−>{c1,c2,...,ck}
误分的概率如下:
P
(
Y
≠
f
(
X
)
)
=
1
−
P
(
Y
=
f
(
X
)
)
P(Y\neq 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个训练实例构成集合
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
−
∑
x
i
∈
N
k
(
x
)
I
(
y
i
=
c
j
)
\frac{1}{k}\sum_{x_i\in N_k(x)}I(y_i\neq c_j) =1-\sum_{x_i\in N_k(x)}I(y_i=c_j)
k1xi∈Nk(x)∑I(yi=cj)=1−xi∈Nk(x)∑I(yi=cj)
3 .k近邻法的实现:kd树
k近邻最简单的方法使线性扫描。这时要计算输入实例与每一个训练实例的距离。当训练集很大时,计算非常耗时间,这种方法不可行。kd树则会提升效率:
3.1构造kd树
输入:
k
k
k维空间数据集
T
=
{
x
1
,
x
2
,
.
.
.
,
x
N
}
T=\{x_1,x_2,...,x_N\}
T={x1,x2,...,xN},其中
x
i
=
(
x
i
(
1
)
,
x
i
(
2
)
,
.
.
.
,
x
i
(
k
)
)
x_i=(x_i^{(1)},x_i^{(2)},...,x_i^{(k)})
xi=(xi(1),xi(2),...,xi(k))
输出:kd树
步骤:
- 开始:构造根节点:
选择 x ( 1 ) x^{(1)} x(1)为坐标轴,以 T T T中所有实例的 x ( 1 ) x^{(1)} x(1)坐标的中位数为切分点,将根节点对应的超巨星区域切分为两个子区域。切分由通过切分点并于坐标轴 x ( 1 ) x^{(1)} x(1)垂直的超平面实现。由根节点生成深度为1的左右子节点:左子节点对应坐标 x ( 1 ) x^{(1)} x(1)小于切分点的子区域,右子节点对应于大于坐标 x ( 1 ) x^{(1)} x(1)的子区域。 - 重复:
对深度为 j j j的结点,选择 x ( l ) x^{(l)} x(l)为切分点的坐标轴, l = j ( m o d k ) + 1 l=j(mod \ k)+1 l=j(mod k)+1,接下来的步骤和上面一样。
直白的讲:对于二叉树的每个深度按照维度顺序,每次选择一个坐标轴,根节点对第一个维度的坐标。比如,对于根节点,选择所有实例的第一维坐标轴的中位数,利用这中位数将所有实例切分为两个区域,对于深度为1:深度为1有两个节点,这两个节点的值就是根节点分的两个区域利用第二维坐标切分的子区域,每个节点切分两个区域,两个节点就切分四个区域。以此类推,直到两个子区域没有实例为止。
3.1 kd树的搜索
输入:已构造的kd树,目标点
x
x
x
输出:
x
x
x的最近邻
- 在kd树中找出包含目标点 x x x的叶节点:从根节点出发,递归向下访问kd树。若目标点 x x x当前维的坐标小于切分点的坐标,则移动到左子节点,否则移动到右子节点。直到子节点为当前最近点为止。(这里的操作是为了先将目标点放到一个最可能的区域里,确定一个大致范围)
- 以此叶节点为“当前最近点”
- 递归地向上回退,在每个节点进行以下操作
- 如果该节点保存地实例点比当前最近点距离目标点更近,则以该节点为“当前最近点”
- 当前最近点一定存在于该节点一个子节点对应地区域。检查该子节点的父结点的另一子节点对应的区域是否有更近的点。具体地,检查另一个子节点对应地区域是否与目标点为球心,以目标点与“当前最近点”间地距离为半径地超球体相交。
如果相交,可能在另一个子节点对应的区域内存在距离目标点更近的点,移动到另一个子节点。接着,递归进行最近邻搜索。(我的理解是:就是先判目标点到断父节点(回退到每一层的当前点)的距离,再比较到父节点(回退到每一层的当前点)的另一个子节点对应的区域上的点(是否有交集),找到最小距离点,赋值为“当前最近点”,依次回退,退到每一层都这么搞)
如果不相交,则向上退回。
- 当回退到根节点时,搜索结束。最后的“当前最近点”即为 x x x的最近邻点。