西瓜书学习笔记——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()
相关推荐
准橙考典22 分钟前
怎么能更好的通过驾考呢?
人工智能·笔记·自动驾驶·汽车·学习方法
hong16168831 分钟前
跨模态对齐与跨领域学习
学习
AI街潜水的八角1 小时前
基于C++的决策树C4.5机器学习算法(不调包)
c++·算法·决策树·机器学习
喵~来学编程啦1 小时前
【论文精读】LPT: Long-tailed prompt tuning for image classification
人工智能·深度学习·机器学习·计算机视觉·论文笔记
阿伟来咯~1 小时前
记录学习react的一些内容
javascript·学习·react.js
Suckerbin2 小时前
Hms?: 1渗透测试
学习·安全·网络安全
水豚AI课代表2 小时前
分析报告、调研报告、工作方案等的提示词
大数据·人工智能·学习·chatgpt·aigc
聪明的墨菲特i2 小时前
Python爬虫学习
爬虫·python·学习
Diamond技术流2 小时前
从0开始学习Linux——网络配置
linux·运维·网络·学习·安全·centos
密码小丑2 小时前
11月4日(内网横向移动(一))
笔记