【ML】K近邻算法(1)

算法流程

k k k近邻算法的思路为:在训练数据中找到与该实例最邻近的 k k k个实例,这 k k k个实例的多数属于某个类,就将该输入分为这个类中. 可以发现 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),\dots, (x_N, y_N)\} T={(x1,y1),(x2y2),,(xN,yN)}
其中 x i ⊂ X ⊂ R n x_i\subset \mathcal{X}\subset \mathbb{R}^n xiXRn表示实例的特征向量, y i ⊂ Y = { c 1 , c 2 , … , c k } y_i\subset \mathcal{Y}=\{c_1, c_2, \dots, c_k\} yiY={c1,c2,,ck}表示实例的类别.

  1. 设置距离函数,根据距离函数找到训练集中与实例 x x x最相近的 k k k个点,涵盖这 k k k个点的邻域为 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 ) y=\argmax\limits_{c_j}\sum\limits_{x_i\in N_k(x)}\mathcal{I}(y_i=c_j) y=cjargmaxxiNk(x)I(yi=cj)

模型

k k k近邻算法实际上对应于特征空间的划分,模型的三个基本要素:距离度量, k k k值选择和分类规则的确定.
在特征空间中,对于每个训练实例点 x i x_i xi,距离该点比其他点更近的所有点组成一个区域为单元(cell),每个单元的标记是确定的.

距离

设特征空间 X \mathcal{X} X n n n维实数向量空间 R n \mathbb{R}^n Rn x i , x j ∈ X x_i, x_j \in \mathcal{X} xi,xjX x i = ( x i ( 1 ) , x i ( 2 ) , … , x i ( n ) ) T x_i=(x_i^{(1)}, x_i^{(2)}, \dots, x_i^{(n)})^T xi=(xi(1),xi(2),,xi(n))T,距离 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_{l=1}^n|x_i^{(l)}-x_j^{(l)}|^p)^{\frac{1}{p}} Lp(xi,xj)=(l=1nxi(l)xj(l)p)p1
p = 1 p=1 p=1时,称为曼哈顿距离
p = 2 p=2 p=2时,称为欧氏距离
p = ∞ p=\infty p=时,是各个坐标距离的最大值 max ⁡ l ∣ x i ( l ) − x j ( l ) ∣ \max\limits_l|x_i^{(l)}-x_j^{(l)}| lmaxxi(l)xj(l)

k值选择

  • 选择较小的 k k k值,近似误差减小,但是估计误差增大,容易发生过拟合.
  • 选择较大的 k k k值,近似误差增大,估计误差减小,模型较为简单,忽略了很多有用的信息

一般取较小 k k k值,再用交叉验证方法找出最优 k k k值.

分类决策规则

k k k近邻算法中分类决策规则一般是多数表决(majority voting rule),在0-1分类损失函数下,分类函数为
f : R n → { c 1 , c 2 , … , c K } f:\mathbb{R}^n\to \{c_1, c_2, \dots, 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))=1P(Y=f(X))
对于给定实例 x ∈ X x\in \mathcal{X} xX,其最近邻的 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 ) \frac{1}{k}\sum\limits_{x_i\in N_k(x)}\mathcal{I}(y_i\neq c_j)=1-\frac{1}{k}\sum\limits_{x_i\in N_k(x)}\mathcal{I}(y_i=c_j) k1xiNk(x)I(yi=cj)=1k1xiNk(x)I(yi=cj)
可以发现,其作用等价于ERM.

K-Dimensional树

k d kd kd树是一种对 k k k维空间中的实例点进行存储以便对其进行快速检索的树形数据结构,其构造过程是不断用垂直于坐标轴的超平面将 k k k维空间切分,构成一系列 k k k维超矩形区域.

算法

输入 k k k维空间数据集 T = { x 1 , x 2 , … , x N } T=\{x_1, x_2, \dots, x_N\} T={x1,x2,,xN},其中 x i = ( x i ( 1 ) , x i ( 2 ) , … , x i ( k ) ) T x_i=(x_i^{(1)}, x_i^{(2)}, \dots, x_i^{(k)})^T xi=(xi(1),xi(2),,xi(k))T

  1. 构造根节点,对应于包含 T T T k k k维空间的超矩形区域. 选择 x ( 1 ) x^{(1)} x(1)作为坐标轴,以 T T T中所有实例的 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(\bmod{k})+1 l=j(modk)+1
  3. 直到两个子区域没有实例存在时停止.

案例

给定二维空间数据集
T = { ( 2 , 3 ) , ( 5 , 4 ) , ( 9 , 6 ) , ( 4 , 7 ) , ( 8 , 1 ) , ( 7 , 2 ) } T=\{(2,3), (5, 4), (9, 6), (4, 7), (8, 1), (7, 2)\} T={(2,3),(5,4),(9,6),(4,7),(8,1),(7,2)}
构造平衡 k d kd kd树.

解析

和线段树的方法类似,采用轮转划分法,直到所有集合都不能继续划分,得到 k d kd kd树结构如下
kd

代码

#include<cstdio>
#include<cstring>
#include<iostream>

using namespace std;
const int N=50005;
const int K=5;
int id, n, k, c;

struct PO{
	int x[K];
	bool operator<(const po &a) const{return x[id]<a.id;}
}b[N];

struct TR{
	po e;
	int o; // 当前划分的维度
}tr[N<<2];

void build(int l, int r, int d, int o){
	if(l>=r) return;
	int mid=l+r>>1;
	int lc=d<<1;
	int rc=d<<1|1;
	id=o;
	nth_element(b+l, b+mid, b+r); // 使第k大的元素处于第k的位置
	tr[d].e=b[mid];
	tr[d].o=o;
	build(l, mid, lc, (o+1)%k); // 递归左侧划分
	build(mid+1, r, rc, (o+1)%k); // 递归右侧划分
}

搜索

在构造的 k d kd kd树中找到目标点 x x x的近邻.

  1. 从根节点出发,递归向下访问 k d kd kd树,如果目标点 x x x当前维的坐标小于切分点的坐标,转左子节点;如果目标点 x x x当期维的坐标大于切分点坐标,转右子节点. 递归到叶子节点
  2. 回溯,更新最近点(超球体判定方法)

kd_search

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Quant0xff

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值