kNN分类详解(标准kNN、距离加权kNN)

云渲染与流化平台视频服务智能体验与创作

Classification

KNN 是具有简单工作机制的最古老的规则之一,自1951年提出以来已经发现了许多应用(Fix and Hodges,1951)。为了推广 kNN 数学机制,通常考虑二进制分类的情况,其中目标变量 的值被编码为0和1。此外,为了从数学上刻画 kNN 机制,引入了一些附加符号。假设使用一个距离度量(例如,Euclidean)来量化训练集 中所有特征向量(观测值)到给定特征向量 (测试观测值)的距离,对于这个特征向量,我们得到 表示 的估计值。把与 最接近的观测值表示为 ,其相关标号为 。 注意和 都是 的函数,因为距离是相对于 来测量的

Standard kNN Classifier(标准kNN分类器)

在二进制分类问题中,给出了一个表示为 的标准 kNN 分类器

其中 表示相对于给定特征向量 的最近邻的数目, 表示事件 ,当 发生时是1,否则是0。在这里我们写 来提醒我们函数 (即分类器)本质上是类标记 的估计量

详细说明, 计算 的 个最近邻中标号为1的训练观测值的数目, 它是 的 个最近邻中标号为0的训练观测值的个数,如果 ,那么 (即 kNN 将标签1分配给 )否则, ,因子 对分类器的决策过程没有任何影响,可以从不等式的两端安全地消除,然而在这里使用它更好地反映了标准 kNN 分类器和后面看到的 kNN 的其他形式之间的关系,对于 类的多分类问题 ,(例如,在鸢尾花分类问题中有 c = 3) ,再次确定 的 个最近邻,计算这些 训练样本中的标签数,并在这些 个观测值中将 分类为多数类,也就是说

在二进制分类应用程序中,通常避免偶数 k 以防止 中的关联。例如,在这些应用程序中,通常看到 k 为3或5的 kNN (即使用3NN 和5NN 规则) ; 然而,一般来说,k 应该被视为一个超参数,并通过模型选择过程进行调整。一般来说,k 越大,决策边界越光滑。这些是决策区域之间的边界(例如,由分类器获得的特征空间的 分区),下面将由代码呈现


          
import numpy as np
          
arrays = np.load('data/iris_train_scaled.npz') # 经过标准化处理后的鸢尾花数据集
          
X_train = arrays['X']
          
y_train = arrays['y']
          
arrays = np.load('data/iris_test_scaled.npz')
          
X_test = arrays['X']
          
y_test = arrays['y']
          
print('X shape = {}'.format(X_train.shape) + '\ny shape = {}'.format(y_train.shape))
      

picture.image


          
X_train = X_train[:,[0,1]]
          
X_test = X_test[:,[0,1]]
      

为了说明起见,只考虑数据中的前两个特性; 即 X _ train 和 X _ test 中的第一和第二个特性(列)


          
# 导入必要的库
          
%matplotlib inline
          
import matplotlib.pyplot as plt
          
from matplotlib.colors import ListedColormap
          
from sklearn.neighbors import KNeighborsClassifier as KNN
          
import numpy as np
          

          
# 设置类别颜色和创建颜色映射
          
color = ('aquamarine', 'bisque', 'lightgrey')
          
cmap = ListedColormap(color)
          

          
# 计算用于绘图的最小和最大值
          
mins = X_train.min(axis=0) - 0.1
          
maxs = X_train.max(axis=0) + 0.1
          
x = np.arange(mins[0], maxs[0], 0.01)
          
y = np.arange(mins[1], maxs[1], 0.01)
          
X, Y = np.meshgrid(x, y)
          
coordinates = np.array([X.ravel(), Y.ravel()]).T
          

          
# 创建子图
          
fig, axs = plt.subplots(2, 2, figsize=(6, 4), dpi=200)
          
fig.tight_layout()
          

          
# K 值的列表,用于迭代
          
K_val = [1, 3, 9, 36]
          

          
# 遍历子图和 K 值
          
for ax, K in zip(axs.ravel(), K_val):
          
    # 使用当前 K 值创建 KNN 分类器
          
    knn = KNN(n_neighbors=K)
          
    
          
    # 将分类器拟合到训练数据
          
    knn.fit(X_train, y_train)
          
    
          
    # 预测网格中每个点的类标签
          
    Z = knn.predict(coordinates)
          
    Z = Z.reshape(X.shape)
          
    
          
    # 绘制决策区域
          
    ax.tick_params(axis='both', labelsize=6)
          
    ax.set_title(str(K) + 'NN Decision Regions', fontsize=8)
          
    ax.pcolormesh(X, Y, Z, cmap=cmap, shading='nearest')
          
    
          
    # 绘制决策边界
          
    ax.contour(X, Y, Z, colors='black', linewidths=0.5)
          
    
          
    # 绘制每个类别的训练数据点
          
    ax.plot(X_train[y_train == 0, 0], X_train[y_train == 0, 1], 'g.', markersize=4)
          
    ax.plot(X_train[y_train == 1, 0], X_train[y_train == 1, 1], 'r.', markersize=4)
          
    ax.plot(X_train[y_train == 2, 0], X_train[y_train == 2, 1], 'k.', markersize=4)
          
    
          
    # 设置轴标签和标题
          
    ax.set_xlabel('sepal length (normalized)', fontsize=7)
          
    ax.set_ylabel('sepal width (normalized)', fontsize=7)
          
    
          
    # 打印在训练数据和测试数据上的准确度
          
    print('K={} 时,训练数据的准确度为 {:.3f}'.format(K, knn.score(X_train, y_train)))
          
    print('K={} 时,测试数据的准确度为 {:.3f}'.format(K, knn.score(X_test, y_test)))
          

          
# 隐藏外部子图的标签
          
for ax in axs.ravel():
          
    ax.label_outer()
      

picture.image

picture.image

正如在图中所看到的,超参数 k 值越大,通常决策边界越平滑。也就是说明,更平滑的决策区域并不一定意味着更好的分类器性能

Distance-Weighted kNN Classifier(距离加权kNN分类器)

分类是标准 kNN 分类器的机制。还有另一种形式的 kNN 称为距离加权 kNN (DW-kNN),在这种形式下,测试观测值 的 个最近邻根据它们与 的距离加权。这个想法是,接近 的观测值应该对决策施加更大的影响。一种简单的加权方案是根据观测值与 的距离的倒数对观测值进行加权,这种加权方案使 DW-kNN 分类器成为:

其中 表示 到 的距离,如果把每个权重 看作训练观察 的‘得分’,然后 DW-kNN 将测试观测值 分类为具有最大“累积分数”的类,其观测值位于 的 个最近邻之中,在这个阶段,很容易看出前面给出的标准 kNN 是 DW-kNN 的一种特殊形式,其中 最近邻对表决的贡献相等,也就是说,当 对于所有 最近邻,也就是

在某些情况下,DW-kNN 可能最终的行为类似于一个简单的最近邻规则(1NN) ,因为训练观测非常接近测试观测将采取非常大的权重。但在实践中,使用 DW-kNN 或标准 kNN 的选择,甚至 k 的选择都可以在模型选择阶段决定。在 scikit-learn (从版本1.2.2开始)中,DW-kNN 可以通过将 KNeighborsClassifier 的权重参数设置为' distance '(权重的默认值是' uniform ',对应于标准 kNN)来实现

The Choice of Distance(距离选择)

为了识别观测值的最近邻,有各种距离度量的选择,可以在标准 kNN 或 DW-kNN 中使用,设 和 ,表示两个 维向量,其中 表示 的 维元素,可以定义这些向量之间的各种距离,三种常见的距离选择是Euclidean,Manhattan和Minhowski分别表示为 , 和

接下来,为了在 kNN 分类器中指定距离的选择,距离的名称以分类器为前缀,列如Manhattan-kNN分类器和Manhattan-weighted kNN是指选择 Manhattan 距离的标准 kNN 和 DW-kNN 分类器,当没有明确指出此选项时,应使用欧几里得距离Euclidean,这个Minhowski有一个命令 ,这是一个任意的整数,当 和 时,Minhowski减小到Manhattan和Euclidean,在KNeighborsClassifier中,距离的选择由度量参数决定。虽然 KNeighborsClassifier中的默认指标是 Minkowski,但是还有另一个参数 ,它决定了Minhowski的顺序,默认值为2。这意味着KNeighborsClassifier的默认指标是Euclidean

如果你对类似于这样的文章感兴趣。

欢迎关注、点赞、转发~

0
0
0
0
关于作者

文章

0

获赞

0

收藏

0

相关资源
KubeZoo: 轻量级 Kubernetes 多租户方案探索与实践
伴随云原生技术的发展,多个租户共享 Kubernetes 集群资源的业务需求应运而生,社区现有方案各有侧重,但是在海量小租户的场景下仍然存在改进空间。本次分享对现有多租户方案进行了总结和对比,然后提出一种基于协议转换的轻量级 Kubernetes 网关服务:KubeZoo,该方案能够显著降低多租户控制面带来的资源和运维成本,同时提供安全可靠的租户隔离性。
相关产品
评论
未登录
看完啦,登录分享一下感受吧~
暂无评论