主要参考书目《统计学习方法》第2版,清华大学出版社
参考书目 Machine Learning in Action, Peter Harrington
用于考研复试笔记,所以写的很简洁,自己能看懂就行。有学习需求请绕道,参考吴恩达机器学习或以上书籍,讲得比大多数博客好。
概念
输入:训练数据集
T
=
{
(
x
1
,
y
1
)
,
(
x
2
,
y
x
)
,
.
.
.
,
(
x
N
,
y
N
)
}
T=\{(x_1,y_1),(x_2,y_x),...,(x_N,y_N)\}
T={(x1,y1),(x2,yx),...,(xN,yN)}
其中,
x
i
∈
χ
⊂
R
n
x_i \in \chi \subset R_n
xi∈χ⊂Rn为实例的特征向量,
y
i
⊂
Y
=
{
c
1
,
c
2
,
.
.
.
,
c
k
}
y_i\subset Y=\{c_1,c_2,...,c_k\}
yi⊂Y={c1,c2,...,ck}为实例的类别,
i
=
1
,
2
,
.
.
.
,
N
;
i=1,2,...,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
y=\argmax\limits_{c_j}\sum\limits_{x_i \in N_k(x)}I(y_i=c_j), i = 1,2,...,N;j=1,2,...,K
y=cjargmaxxi∈Nk(x)∑I(yi=cj),i=1,2,...,N;j=1,2,...,K
I
I
I为指示函数,当
y
=
c
j
y_=c_j
y=cj时
I
I
I为1,否则
I
I
I为0.
本质是找距离最近的k个点构成集合,这个集合中最多的种类就是 x x x的种类。
k
k
k近邻法的特殊情况是
k
=
1
k=1
k=1的情形。
k
k
k近邻没有显式的学习过程。
距离度量
特征空间中两个实例点的距离是两个实例点相似程度的反映。
k
k
k近邻模型的特征空间一般是
n
n
n维实数向量空间
R
n
R^n
Rn。使用的距离是欧式距离,但也可以是其他距离,如更一般的
L
p
L_p
Lp距离或Minkowski距离。
设特征空间
χ
\chi
χ是
n
n
n维实数向量空间
R
n
R^n
Rn,
x
i
,
x
j
∈
χ
,
x
i
=
(
x
i
(
1
)
,
x
i
(
2
)
,
.
.
.
,
x
i
(
n
)
)
T
,
x
j
=
(
x
j
(
1
)
,
x
j
(
2
)
,
.
.
.
,
x
j
(
n
)
)
T
x_i,x_j \in \chi,x_i=(x_i^{(1)},x_i^{(2)},...,x_i^{(n)})^T,x_j=(x_j^{(1)},x_j^{(2)},...,x_j^{(n)})^T
xi,xj∈χ,xi=(xi(1),xi(2),...,xi(n))T,xj=(xj(1),xj(2),...,xj(n))T,
x
i
,
x
j
x_i,x_j
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
L_p(x_i,x_j)=(\sum\limits_{l=1}^n|x_i^{(l)}-x_j^{(l)}|^p)^{\frac{1}{p}}
Lp(xi,xj)=(l=1∑n∣xi(l)−xj(l)∣p)p1
特别地,当
p
=
∞
p=\infin
p=∞时,它是各个坐标距离地最大值,即
L
∞
(
x
i
,
x
j
)
=
max
l
∣
x
i
(
l
)
−
x
j
(
l
)
∣
L_{\infin}(x_i,x_j)=\max\limits_{l}|x_i^{(l)}-x_j^{(l)}|
L∞(xi,xj)=lmax∣xi(l)−xj(l)∣
原理
k值的选择
k值较小容易发生过拟合
kd树
为了提高 k k k近邻搜索的效率,可以考虑使用特殊的结构存储训练数据,以减少计算距离的次数。具体方法有很多,下面介绍其中一种的 k d kd kd树(kd tree)方法。
k-d tree是每个节点均为k维数值点的二叉树,其上的每个节点代表一个超平面,该超平面垂直于当前划分维度的坐标轴,并在该维度上将空间划分为两部分,一部分在其左子树,另一部分在其右子树。即若当前节点的划分维度为d,其左子树上所有点在d维的坐标值均小于当前值,右子树上所有点在d维的坐标值均大于等于当前值。
kd树的构造
对深度为
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,然后划分为左子树和右子树递归构造
kd树的查找
时间复杂度
O
(
l
o
g
(
N
)
)
O(log(N))
O(log(N))
疑问
上图中第一次查找时,(8,1)确实更远,但是如果改成(7,4)还需要搜索右边的点吗。
答:不可能出现这种情况。上面描述有误吗,不能拿(8,1)参考,而是应该拿(9,6)参考,因为按照划分的顺序,(9,6)是父节点。也不可能出现疑问中的情况。
代码
不想写了。。累了。
贴一个掉包,kd-tree的代码有空再补。。主要是py不熟。
import numpy as np
from sklearn.neighbors import KDTree
np.random.seed(0)
points = np.random.random([15,2])
tree = KDTree(points)
point = points[0]
print(points)
print(point)
print("========================")
dists, indices = tree.query([point], k = 3)
p