西瓜书学习笔记——k近邻学习(公式推导+举例应用)

文章目录

算法介绍

K最近邻(K-Nearest Neighbors,KNN)是一种常用的监督学习算法,用于分类和回归任务。该算法基于一个简单的思想:如果一个样本在特征空间中的 k k k个最近邻居中的大多数属于某个类别,那么该样本很可能属于这个类别。KNN算法不涉及模型的训练阶段,而是在预测时进行计算。

以下是KNN算法的基本步骤:

  • 选择K值: 首先,确定用于决策的邻居数量K。K的选择会影响算法的性能,通常通过交叉验证等方法来确定最优的K值。

  • 计算距离: 对于给定的测试样本,计算其与训练集中所有样本的距离。常用的距离度量包括欧几里得距离、曼哈顿距离、闵可夫斯基距离等。

  • 找到最近的K个邻居: 根据计算得到的距离,找到距离最近的K个训练样本。

  • 投票或取平均: 对于分类任务,采用多数表决的方式,即选择K个邻居中最常见的类别作为测试样本的预测类别。对于回归任务,可以取K个邻居的平均值作为预测结果。

KNN算法的优点包括简单易理解,对于小规模数据集表现良好,而且适用于多类别问题。然而,它的缺点包括计算开销较大(特别是对于大规模数据集)、对数据分布敏感,以及对特征范围差异较为敏感。

下面我们来验证 k k k近邻算法的正确性:

给定测试样本 x x x,若其最近邻样本为 z z z,则最近邻分类器出错的概率为:
P ( e r r ) = 1 − ∑ c ∈ Y P ( c ∣ x ) P ( c ∣ z ) (1) P(err)=1-\sum_{c\in \mathcal{Y}}P(c\mid x)P(c\mid z) \tag{1} P(err)=1−c∈Y∑P(c∣x)P(c∣z)(1)

我们假设样本是独立同分布的,且均匀的,对于任意的测试样本在附近总能找到式(1)中的训练样本 z z z。令 c ⋆ = arg max c ∈ Y P ( c ∣ x ) c^\star=\text{arg max}{c\in \mathcal{Y}}P(c\mid x) c⋆=arg maxc∈YP(c∣x)表示贝叶斯最优分类器的结果,有:
P ( e r r ) = 1 − ∑ c ∈ Y P ( c ∣ x ) P ( c ∣ z ) ≃ 1 − ∑ c ∈ Y P 2 ( c ∣ x ) = 1 − P 2 ( c 1 ∣ x ) − P 2 ( c 2 ∣ x ) − . . . − P 2 ( c ⋆ ∣ x ) − . . . − P 2 ( c k ∣ x ) = 1 − ∑ c ∈ Y , c ≠ c ⋆ P 2 ( c ∣ x ) − P 2 ( c ⋆ ∣ x ) ≤ 1 − P 2 ( c ⋆ ∣ x ) ≤ 2 × ( 1 − P ( c ⋆ ∣ x ) ) (2) \begin{aligned} P(err)&=1-\sum
{c\in \mathcal{Y}}P(c\mid x)P(c\mid z)\\ &\simeq1-\sum_{c\in \mathcal{Y}}P^2(c\mid x)\\ &=1-P^2(c_1\mid x)-P^2(c_2\mid x)-...-P^2(c^\star\mid x)-...-P^2(c_k\mid x) \\ &=1-\sum_{c\in \mathcal{Y},c\ne c^\star}P^2(c\mid x)-P^2(c^\star\mid x)\\ &\leq 1-P^2(c^\star\mid x)\\ &\leq 2\times (1-P(c^\star\mid x)) \end{aligned} \tag{2} P(err)=1−c∈Y∑P(c∣x)P(c∣z)≃1−c∈Y∑P2(c∣x)=1−P2(c1∣x)−P2(c2∣x)−...−P2(c⋆∣x)−...−P2(ck∣x)=1−c∈Y,c=c⋆∑P2(c∣x)−P2(c⋆∣x)≤1−P2(c⋆∣x)≤2×(1−P(c⋆∣x))(2)

这里, c ⋆ c^\star c⋆ 是我们关心的类别,而 Y \mathcal{Y} Y 是所有可能的类别的集合。在这一步,我们只考虑了 c ⋆ c^\star c⋆ 这一类别的分类情况,因为我们关注的是样本被错误分类的概率。这样,我们就得到了第五行的推导。

在最后一步,我们使用了不等式 1 − a b ≤ ( 1 − a ) + ( 1 − b ) 1-ab \leq (1-a)+(1-b) 1−ab≤(1−a)+(1−b),其中 a = P ( c ⋆ ∣ x ) a = P(c^\star\mid x) a=P(c⋆∣x), b = P ( c ⋆ ∣ x ) b = P(c^\star\mid x) b=P(c⋆∣x)。这样我们就得到了最终的推导:
P ( e r r ) ≤ 2 × ( 1 − P ( c ⋆ ∣ x ) ) P(err)\leq2\times (1-P(c^\star\mid x)) P(err)≤2×(1−P(c⋆∣x))

故 k k k近邻分类器泛化错误率不超过贝叶斯最优分类器的错误率的两倍。

实验分析

数据集如下所示:

读入数据集:

py 复制代码
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

data = pd.read_csv('data/4.0a.csv')

定义欧式距离:

py 复制代码
# 定义欧氏距离计算函数
def euclidean_distance(point1, point2):
    return np.sqrt(np.sum((point1 - point2) ** 2))

定义KNN算法:

py 复制代码
# 定义KNN算法函数
def knn_predict(train_data, test_point, k):
    distances = []
    
    # 计算测试点与每个训练点的距离
    for index, row in train_data.iterrows():
        train_point = row[['Density', 'Sugar inclusion rate']].values
        label = row['label']
        distance = euclidean_distance(test_point, train_point)
        distances.append((distance, label))
    
    # 根据距离排序,选择前k个最近的点
    distances.sort()
    neighbors = distances[:k]
    
    # 统计最近点的标签
    label_counts = {0: 0, 1: 0}
    for _, label in neighbors:
        label_counts[label] += 1
    
    # 返回预测的标签
    return max(label_counts, key=label_counts.get)

执行KNN算法并绘制结果:

py 复制代码
# 设定k值
k_value = 3

# 生成密集的点用于绘制决策边界
x_values, y_values = np.meshgrid(np.linspace(0, 1, 100), np.linspace(0, 1, 100))
grid_points = np.c_[x_values.ravel(), y_values.ravel()]

# 预测每个点的标签
predictions = np.array([knn_predict(data, point, k_value) for point in grid_points])

# 将预测结果转换为与 x_values, y_values 相同的形状
predictions = predictions.reshape(x_values.shape)

# 绘制散点图
plt.scatter(data['Density'], data['Sugar inclusion rate'], c=data['label'], cmap='viridis', edgecolors='k')
plt.title('Original Data Points')

# 绘制决策边界
plt.contourf(x_values, y_values, predictions, alpha=0.3, cmap='viridis')
plt.xlabel('Density')
plt.ylabel('Sugar inclusion rate')
plt.title(f'KNN Classification (k={k_value})')

plt.show()
相关推荐
m0_678693332 分钟前
深度学习笔记29-RNN实现阿尔茨海默病诊断(Pytorch)
笔记·rnn·深度学习
每次的天空10 分钟前
Android-自定义View的实战学习总结
android·学习·kotlin·音视频
重庆小透明16 分钟前
力扣刷题记录【1】146.LRU缓存
java·后端·学习·算法·leetcode·缓存
sigmoidAndRELU1 小时前
读Vista
笔记·stable diffusion·世界模型
Sincerelyplz2 小时前
【Temproal】快速了解Temproal的核心概念以及使用
笔记·后端·开源
许白掰2 小时前
【stm32】HAL库开发——CubeMX配置RTC,单片机工作模式和看门狗
stm32·单片机·嵌入式硬件·学习·实时音视频
future14123 小时前
C#学习日记
开发语言·学习·c#
Yo_Becky3 小时前
【PyTorch】PyTorch预训练模型缓存位置迁移,也可拓展应用于其他文件的迁移
人工智能·pytorch·经验分享·笔记·python·程序人生·其他
DIY机器人工房3 小时前
0.96寸OLED显示屏 江协科技学习笔记(36个知识点)
笔记·科技·stm32·单片机·嵌入式硬件·学习·江协科技
martian6654 小时前
支持向量机(SVM)深度解析:从数学根基到工程实践
算法·机器学习·支持向量机