21.k最近邻算法

21.k最近邻算法

(本篇R代码对应本系列博客《17 R语言手册(第十站 k均值)》。)

1.距离函数

  数据分析师定义距离度量来计算相似性。距离度量或距离函数由实值函数d定义,例如对任一坐标x、y和z,有如下性质:
(1) d ( x , y ) ⩾ 0 , 当 且 仅 当 x = y 时 , d ( x , y ) = 0 。 d(x, y) \geqslant 0,当且仅当x=y时,d(x,y)=0。 d(x,y)0x=yd(x,y)=0
(2) d ( x , y ) = d ( y , x ) d(x, y)=d(y, x) d(x,y)=d(y,x)
(3) d ( x , z ) ⩽ d ( x , y ) + d ( y , z ) d(x, z) \leqslant d(x, y)+d(y, z) d(x,z)d(x,y)+d(y,z)
  解读一下,性质1表明距离必须是非负的,距离等于0的唯一可能就是坐标相同。性质2表明距离函数要满足交换律。性质3表明引入第3个点的时候,其值总是大于两外两个点的距离。
  (这一部分详细参考本系列博客《21.1 什么是切比雪夫、曼哈顿、欧几里德、闵可夫斯基、马哈拉诺比斯距离》,实际上,我们也可以使用不同的距离来进行最近邻的计算。)

2.欧式距离

  那么按照这样的定义说起来,最常见的就是欧氏距离了,这个函数是人类在计算现实世界距离时最常用的方法。
d  Fucliden  ( x , y ) = ∑ i ( x i − y i ) 2 d_{\text { Fucliden }}(x, y)=\sqrt{\sum_{i}\left(x_{i}-y_{i}\right)^{2}} d Fucliden (x,y)=i(xiyi)2
  即使从图像上来看,这个距离的计算也非常的直观。
  当然,在度量距离的时候,可能由于某些变量数值上更大,会掩盖那些数值较小的变量,因此,我们需要对此进行标准化处理。这是在本系列博客《07 主成分分析(基础版)》中就详细阐述了的。
  通常,我们采用两种方法:

  • MMN 最大-最小规范化
    X ∗ = X − min ⁡ ( X ) range ⁡ ( X ) = X − min ⁡ ( X ) max ⁡ ( X ) − min ⁡ ( X ) X^{*}=\frac{X-\min (X)}{\operatorname{range}(X)}=\frac{X-\min (X)}{\max (X)-\min (X)} X=range(X)Xmin(X)=max(X)min(X)Xmin(X)
      (稍微注意这个函数就可以发现,它的取值始终实在0和1之间。注意之后如果有取值在0-1之间的分类变量的话,分类变量对它的取值影响就很大。)
  • Z-score标准化
    X ∗ = X − mean ⁡ ( X ) SD ⁡ ( X ) X^{*}=\frac{X-\operatorname{mean}(X)}{\operatorname{SD}(X)} X=SD(X)Xmean(X)
      (经验上来讲,这个函数的取值在-3和3之间,范围更宽。)
      此外对于分分类变量来说,欧氏距离并不合适。为此,我们需要一个“差异”函数,用于比较一对记录中的第 i 个属性值的大小。
    ( x i , y i ) = { 0 若 x i = y i 1 否则 \left( x_i,y_i \right) =\left\{ \begin{array}{l} \text{0 若}x_i=y_i\\ \text{1 否则}\\ \end{array} \right. (xi,yi)={xi=yi否则
      其中 x i x_i xi y i y_i yi是分类值。我们可以用 D i f f e r e n t ( x i , y i ) 函 数 Different(x_i,y_i)函数 Different(xi,yi) 替换上述分类变量的第 i i i 项。当然,在不同情况的时候,可以适当的对这个函数进行加权。

3.加权投票

  在一个新的k-近邻算法里,对于一个新的纪录,大家可能会认为与新记录更接近或更相似的近邻应该比那些与新记录更远的近邻得到更大的权重。与新记录距离较远的浅灰色记录获得和与新记录距离较近的深灰色记录同样的投票权,这种方式公平吗?这样做也许是不公平的。为此,分析人员可能会采用加权投票方式,距离近的近邻在分类决策中将比距离远的近邻获得更大的投票权。基于加权的投票将会大大减少平局发生的可能性。
  采用加权投票,特定记录对分类新记录的影响与其和新记录的距离成反比。
  给个例子:
在这里插入图片描述
原有3条数据,两个分类,对他们进行 最大最小规范化 ,然后我们计算他们之间的距离:
d (    new, A ) = ( 0.05 − 0.0467 ) 2 + ( 0.25 − 0.2471 ) 2 = 0.004393 d ( new,B ) = ( 0.05 − 0.0533 ) 2 + ( 0.25 − 0.1912 ) 2 = 0.58893 d ( new, C ) = ( 0.05 − 0.0917 ) 2 + ( 0.25 − 0.2794 ) 2 = 0.051022 \begin{aligned} d\left( \,\,\text{new, A} \right) &=\sqrt{\left( 0.05-0.0467 \right) ^2+\left( 0.25-0.2471 \right) ^2}=0.004393\\ d\left( \text{new,B} \right) &=\sqrt{\left( 0.05-0.0533 \right) ^2+\left( 0.25-0.1912 \right) ^2}=0.58893\\ d\left( \text{new,}C \right) &=\sqrt{\left( 0.05-0.0917 \right) ^2+\left( 0.25-0.2794 \right) ^2}=0.051022\\ \end{aligned} d(new, A)d(new,B)d(new,C)=(0.050.0467)2+(0.250.2471)2 =0.004393=(0.050.0533)2+(0.250.1912)2 =0.58893=(0.050.0917)2+(0.250.2794)2 =0.051022
  这些记录的投票权重将按照距离的平方倒数获得。
  记录(A)为新记录投票给深灰色记录(选择药物B和C),因此该分类的权重投票如下:
V o t e ( d a r k g r a y ) = 1 d (  new  , A ) 2 = 1 0.00439 3 2 ≅ 51818 Vote(dark gray)=\frac{1}{d(\text { new }, \mathrm{A})^{2}}=\frac{1}{0.004393^{2}} \cong 51818 Vote(darkgray)=d( new ,A)21=0.0043932151818
    记录(B和C)为新记录投票给中灰色记录(选择药物A和X),因此该分类的权重投票如下:
Votes (medium gray)  = 1 d ( n e w , B ) 2 + 1 d ( n e w , C ) 2 = 1 0.05889 3 2 + 1 0.05102 2 2 ≅ 672 \begin{aligned} & \text {Votes (medium gray) } \\=& \frac{1}{d(n e w, B)^{2}}+\frac{1}{d(n e w, C)^{2}} \\=& \frac{1}{0.058893^{2}}+\frac{1}{0.051022^{2}} \\ \cong & 672 \end{aligned} ==Votes (medium gray) d(new,B)21+d(new,C)210.05889321+0.05102221672
  此时,我们比较结果,则选择深灰色的类级。

4.轴伸缩

  除了根据距离来选择加权而来归类之外,我们还可以使用 轴伸缩 的方法。为何呢?以决策树为例,在决策树分类中,只考虑使用那些与分类有关的属性。在k-最近邻算法中,默认情况下要计算所有属性的距离。可能存在一些相关记录,其所有的重要的变量都与新记录相似,而在不重要的方面却与新记录距离甚远,导致其总体上与新记录有相当大的距离,由此在分类决策中未被考虑。因此分析师可以对算法作出一些限制,让算法去考虑对分类新记录重要的字段,或者至少让算法不考虑那些不相关的字段。
  例如,假设通过交叉验证或者领域专家推荐,在药物分类时,钠/钾比的重要性是年龄的3倍。那么可以得到KaTeX parse error: Expected '}', got 'EOF' at end of input: z_{Na/K)=3及$Z_{age}=1。针对前述的示例,记录A、B、C与新记录的距离如下:
d (    new, A ) = ( 0.05 − 0.0467 ) 2 + [ 3 ( 0.25 − 0.2471 ) ] 2 = 0.009305 d (    new ,B ) = ( 0.05 − 0.0533 ) 2 + [ 3 ( 0.25 − 0.1912 ) ] 2 = 0.17643 d (    new , C ) = ( 0.05 − 0.0917 ) 2 + [ 3 ( 0.25 − 0.2794 ) ] 2 = 0.09756 \begin{aligned} d\left( \,\,\text{new, A} \right) &=\sqrt{\left( 0.05-0.0467 \right) ^2+\left[ 3\left( 0.25-0.2471 \right) \right] ^2}=0.009305\\ d\left( \,\,\text{new ,B} \right) &=\sqrt{\left( 0.05-0.0533 \right) ^2+\left[ 3\left( 0.25-0.1912 \right) \right] ^2}=0.17643\\ d\left( \,\,\text{new ,}C \right) &=\sqrt{\left( 0.05-0.0917 \right) ^2+\left[ 3\left( 0.25-0.2794 \right) \right] ^2}=0.09756\\ \end{aligned} d(new, A)d(new ,B)d(new ,C)=(0.050.0467)2+[3(0.250.2471)]2 =0.009305=(0.050.0533)2+[3(0.250.1912)]2 =0.17643=(0.050.0917)2+[3(0.250.2794)]2 =0.09756
  简单地说起来,这其实就是在你觉得关键的变量上乘以一个系数,使它的影响力变的更大一点点。这里的例子中呢,钠/钾比伸缩并未改变分类的结果,仍然选择采用深灰色点。然而,在实际工作中,轴伸缩可以得到更精确的分类,因为采用该方法可量化每个变量在分类决策中的相关性。

5.k-最近邻算法用于评估和预测

  最普遍的,我们用KNN来进行分类。然而,其实它还可以用于连续性目标变量的评估和预测。
  以使用过的例子来讲解:
在这里插入图片描述
  这个例子中,我们希望估计年龄为17岁,Na/K为1.5的病人的收缩压(目标变量)。令k=3,我们得到表中3个最近邻,我们对Na/K的加权值为3。
  局部加权平均将采用血压加权平均来估计3个最近邻的血压,与我们前例采用同样的方法,以距离的平方倒数为权重。目标变量值 y ^ \hat{y} y^计算如下:
y ^ n c w = ∑ i w i y i ∑ i w i \hat{y}_{\mathrm{ncw}}=\frac{\sum_{i} w_{i} y_{i}}{\sum_{i} w_{i}} y^ncw=iwiiwiyi
  在这个公式里,其中有已存在的记录 x 1 , x 2 , … , x k x_{1}, x_{2}, \dots, x_{k} x1,x2,,xk,其 w i = 1 / d ( w_{i}=1 / d( wi=1/d( new , x i ) 2 , x_{i})^{2} ,xi)2
  这个例子里,我们的计算如下:
y ^ ncw = ∑ i w i y i ∑ i w i = ( 120/ 0.00930 5 2 ) + ( 122/ 0.1764 3 2 ) + ( 130/ 0.0975 6 2 ) ( 1/ 0.00930 5 2 ) + ( 1/ 0.1764 3 2 ) + ( 1/ 0.0975 6 2 ) = 120.0954 \hat{y}_{\text{ncw}}=\frac{\sum_i{w}_iy_i}{\sum_i{w}_i}=\frac{\left( \text{120/}0.009305^2 \right) +\left( \text{122/}0.17643^2 \right) +\left( \text{130/}0.09756^2 \right)}{\left( \text{1/}0.009305^2 \right) +\left( \text{1/}0.17643^2 \right) +\left( \text{1/}0.09756^2 \right)}=120.0954 y^ncw=iwiiwiyi=(1/0.0093052)+(1/0.176432)+(1/0.097562)(120/0.0093052)+(122/0.176432)+(130/0.097562)=120.0954
  结果与预期吻合,估计的血压值与数据集中和新记录最近(在伸缩属性空间中)的记录的血压值非常接近。换句话说,因为记录A与新记录更靠近,所以其血压值120在估计新记录的血压值时获得的权重更大一些。

6.k值的选择

  这个可以按照经验,也可以采用类似前面使用 轴伸缩 时用的交叉验证过程。通过选择不同的k值来训练随机选择的训练集,获得能够最小化分类或评估误差的k值。

K最近邻(K-Nearest Neighbors,KNN)算法是一种常用的多分类算法。它基于样本之间的距离来进行分类,具体操作如下: 1. 计算距离:对于测试样本,计算它与训练集中每个样本的距离。常见的距离度量方法有欧氏距离、曼哈顿距离等。 2. 选择K个最近邻:根据距离,选择与测试样本最近的K个训练样本。 3. 进行投票或求平均:根据K个最近邻样本的标签,进行投票决策或求平均值,得到测试样本的分类结果。 以下是一个使用K最近邻算法进行多分类的Python代码示例: ```python from sklearn.neighbors import KNeighborsClassifier import pandas as pd from sklearn.model_selection import train_test_split # 读取数据集 data = pd.read_csv('final_data1.csv') Y = data.y X = data.drop('y', axis=1) # 数据集划分为训练集和测试集 X_train, X_test, y_train, y_test = train_test_split(X, Y, test_size=0.2, random_state=42) # 创建并训练KNN分类器 knn = KNeighborsClassifier(n_neighbors=3) # 设置K值为3 knn.fit(X_train, y_train) # 在测试集上进行预测 y_pred = knn.predict(X_test) ``` 上述代码使用了`sklearn`库中的`neighbors`模块,通过导入`KNeighborsClassifier`创建了一个K最近邻分类器对象`knn`。在创建分类器对象时,通过参数`n_neighbors`设置了K的值为3。然后使用训练集数据`X_train`和对应的标签`y_train`调用`knn.fit()`方法进行训练。最后,使用训练好的模型在测试集数据`X_test`上进行预测,预测结果存储在`y_pred`中。 需要注意的是,KNN算法的性能很大程度上依赖于选择合适的K值和距离度量方法。在实际应用中,可以使用交叉验证等方法来选择最佳的K值,并根据数据集的特点选择合适的距离度量方法。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值