机器学习基础——K近邻
K近邻基础k近邻法分类的直观理解:给定一个训练数据集,对于新的输入实例,在训练集中找到与该实例最邻近的k个实例。这k个实例的多数属于某个类别,则该输入实例就划分这个类别。KNN三要素k近邻法的三要素:k值选择、距离度量和分类决策规则。k值选择当k=1时k近邻算法称为最近邻算法。此时将训练集中与x⃗\vec xx最近点的类别作为x⃗\vec xx的分类。k值的选择会对k近邻法的结果产生重...
K近邻基础
k近邻法分类的直观理解:给定一个训练数据集,对于新的输入实例,在训练集中找到与该实例最邻近的k个实例。这k个实例的多数属于某个类别,则该输入实例就划分这个类别。
KNN三要素
k近邻法的三要素:k值选择、距离度量和分类决策规则。
k值选择
当k=1时k近邻算法称为最近邻算法。此时将训练集中与x⃗\vec xx最近点的类别作为x⃗\vec xx的分类。
k值的选择会对k近邻法的结果产生重大影响。
k较小
相当于在较小的邻域中的训练实例进行预测,学习的近似误差减少。
-
优点:只有与输入实例较近的训练实例才会对预测起作用。
-
缺点: 学习的估计误差会增大,预测结果对近邻的实例非常敏感,若近邻的训练实例点刚好是噪声,那么预测就会出错。
k较大
相当于在较大的邻域中的训练实例进行预测
- 优点:减少学习的估计误差
- 缺点:学习的近似误差会增大,使得模型整体变得简单,忽略了训练实例中大量有用的信息。
距离度量
KNN算法要求数据的所有特征都可以做可比较的量化。若在数据特征中存在非数值类型,必须采取手段将其量化为数值。样本有多个参数,每一个参数都有自己的定义域和取值范围。为了公平,样本参数必须做一些归一化处理,最简单的方式就是所有特征的数据都采取归一化处置。
K近邻模型的特征空间一般是n维实数向量空间Rn\mathbb{R}^nRn。一般为欧式距离,也可以是一般的LpL_pLp距离:
Lp(xi⃗,xj⃗)=(∑i=1n∣xi(l)−xj(l)∣p)1pxj⃗,xj⃗∈X=Rnxi⃗=(xi(1),xi(2),⋯ ,xi(n))Tp≥1 L_p(\vec{x_i},\vec{x_j}) = (\sum_{i=1}^n|x^{(l)}_i-x^{(l)}_j|^p)^{\frac{1}{p}} \\\vec{x_j},\vec{x_j}\in \mathcal{X}=\mathbb{R}^n \\\vec{x_i} = (x^{(1)}_i,x^{(2)}_i,\cdots,x^{(n)}_i)^T \\p\ge 1 Lp(xi,xj)=(i=1∑n∣xi(l)−xj(l)∣p)p1xj,xj∈X=Rnxi=(xi(1),xi(2),⋯,xi(n))Tp≥1
当p=2p=2p=2时,为欧式距离
当p=1p=1p=1时,为曼哈顿距离
当p=∞p=\inftyp=∞时,为每个维度距离中的最大值L∞(xi⃗,xj⃗)=maxl∣xi(l)−xj(l)∣L_{\infty}(\vec{x_i},\vec{x_j})=\max_{l}|x^{(l)}_i-x^{(l)}_j|L∞(xi,xj)=maxl∣xi(l)−xj(l)∣
不同的距离度量所确定的最近邻点是不同的,一般情况下,选欧式距离囝距离度量,但只适用于连续度量。
分类决策规则
分类决策通常采用多数表决。也可以基于距离的远近进行加权投票,距离越近的样本权重越大。
多数表决规则等价于经验风险最小化。设分类的损失函数为0-1损失函数,分类函数为f:Rn→{c1c2,⋯ ,ck}f:\mathbb{R}^n \rightarrow \{c_1c_2,\cdots,c_k\}f:Rn→{c1c2,⋯,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\vec x\in \mathcal{X}x∈X,其最近邻的k个训练点构成集合Nk(x⃗)N_{k}(\vec x)Nk(x)。则误分类率为:
1k∑x⃗i∈Nk(x⃗)I(yi≠cj)=1−1k∑x⃗i∈Nk(x⃗)I(yi=cj) \frac{1}{k}\sum_{\vec x_i \in N_k(\vec x)} I(y_i\ne c_j)=1-\frac{1}{k}\sum_{\vec x_i \in N_k(\vec x)}I(y_i=c_j) k1xi∈Nk(x)∑I(yi̸=cj)=1−k1xi∈Nk(x)∑I(yi=cj)
即多数表决:
cj=argmaxcj∑x⃗∈Nk(x⃗)I(yi=cj) c_j = \arg \underset{c_j}{\max} \sum_{\vec x\in N_k(\vec x)} I(y_i=c_j) cj=argcjmaxx∈Nk(x)∑I(yi=cj)
K近邻算法
- 输入:训练数据集T={(x⃗1,y1),(x⃗2,y2),⋯ ,(x⃗N,yN)},x⃗i∈X⊆RnT=\{(\vec x_1,y_1),(\vec x_2,y_2),\cdots,(\vec x_N,y_N)\},\vec x_i\in \mathcal{X}\sube \mathbb{R}^nT={(x1,y1),(x2,y2),⋯,(xN,yN)},xi∈X⊆Rn为实例的特征向量,yi∈Y={c1,c2,⋯ ,cK}y_i\in \mathcal{Y}=\{c_1,c_2,\cdots,c_K\}yi∈Y={c1,c2,⋯,cK}为实例的类别。
- 输出:实例x⃗\vec xx所属的类别yyy
- 步骤
- 根据给定的距离度量,在T中寻找与x⃗\vec xx最近邻的k个点。定义涵盖这k个点的x⃗\vec xx的邻域记作Nk(x⃗)N_k(\vec x)Nk(x)
- 从Nk(x⃗)N_k(\vec x)Nk(x)中,根据分类决策规则决定x⃗\vec xx的类别
kd树
k近邻法中如何对训练数据进行快速k近邻搜索个问题,最简单粗暴的方法是:线性扫描。通过计算输入样本与每个训练样本的距离,来找出最近邻的k个训练样本。当训练集很大时,计算非常耗时,常用的解决方法是使用kd树,可以大幅度提高k近邻搜索的效率。
- 输入:k维空间数据集为T
- 输出:kd树
- 算法步骤
- 开始:构造根节点。选择x1x^{1}x1为轴,以T中所有样本的x1x^1x1坐标的中位数x1∗x^{1*}x1∗作为切分点,将根节点的超矩形切分为两个子区域。切分超平面x1=x1∗x^{1} = x^{1*}x1=x1∗。本次切分产生深度为1的左右子节点。左子节点对应于坐标x1<x1∗x^{1}<x^{1*}x1<x1∗的子区域;右子节点对应于坐标x1>x1∗x^{1}>x^{1*}x1>x1∗的子区域。落在切分超平面上的点x1=x1∗x^{1} = x^{1*}x1=x1∗,保存在根节点。
- 重复:对深度为jjj的子节点,选择xlx^{l}xl为切分的坐标轴,l=jmod  k+1l=j\mod{k}+1l=jmodk+1 。本次切分之后,树的深度为j+1j+1j+1。这里取模,而不是l=j+1l=j+1l=j+1,是因为树的深度可以超过维度kkk,此时切分轴又重复回到x1x^1x1,轮转坐标轴进行切分
- 结束:直到所有节点的两个子域中没有样本存在时,切分停止。此时得到kd树。
使用kd树的算法相对复杂,用kd树的最近邻搜索算法如下:
-
输入: kd树和样本x⃗\vec{x}x
-
输出:样本x⃗\vec xx的最近邻点
-
步骤
-
在kd树中找到包含测试点x⃗\vec xx的叶节点。方法是:从根结点出发,递归向下访问kd树。
- 若测试点x⃗\vec xx当前维度的坐标小于切分点的坐标,则查找当前节点的左子节点。
- 若测试点x⃗\vec xx当前维度的坐标大于切分点的坐标,则查找当前节点的右子节点。
在访问过程中记录下访问的各节点的顺序。
-
以此叶节点为当前最近x⃗nst\vec x_{nst}xnst。真实最近点一点在x⃗\vec xx与当前最近点构成的超球体内。x⃗\vec xx为球心。
-
设当前考察的节点为x⃗\vec xx,递归向上回退,设回退弹出的节点为x⃗inew\vec x_{inew}xinew(每次回退都是退到kd树的父节点)。考察节点x⃗inew\vec x_{inew}xinew所在的超平面与以x⃗\vec xx为球心、以x⃗\vec xx到当前最近点x⃗nst\vec x_{nst}xnst的距离半径的超球体是否相交
-
若相交
若x⃗i\vec x_ixi是x⃗inew\vec x_{inew}xinew的左子节点,则进入x⃗inew\vec x_{inew}xinew的右子节点,然后先进行向下搜搜,然后向上回退。
若x⃗i\vec x_ixi是x⃗inew\vec x_{inew}xinew的右子节点,则进入x⃗inew\vec x_{inew}xinew的左子节点,然后先进行向下搜搜,然后向上回退。
-
若不相交,则直接回退
-
-
当回到根结点时,搜索结束,最后的当前最近点即为x⃗\vec xx的最近邻点。
-
kd搜索的平均计算复杂度为O(logN)O(\log N)O(logN),N为训练集大小。
魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。
更多推荐


所有评论(0)