Scikit-learn Python机器学习 - 分类算法 - K-近邻(KNN)算法

发布于:2025-09-12 ⋅ 阅读:(22) ⋅ 点赞:(0)

锋哥原创的Scikit-learn Python机器学习视频教程:

https://www.bilibili.com/video/BV11reUzEEPH

课程介绍

本课程主要讲解基于Scikit-learn的Python机器学习知识,包括机器学习概述,特征工程(数据集,特征抽取,特征预处理,特征降维等),分类算法(K-临近算法,朴素贝叶斯算法,决策树等),回归与聚类算法(线性回归,欠拟合,逻辑回归与二分类,K-means算法)等。

Scikit-learn Python机器学习 - 分类算法 - K-近邻(KNN)算法

K近邻(K-Nearest Neighbors, KNN)是一种非常直观和简单的监督学习算法,既可用于分类,也可用于回归。它的核心思想可以用一句老话概括:“物以类聚,人以群分”

1. 核心思想

一个样本的类别或值,由其在特征空间中最相邻的K个样本(邻居)的多数投票(分类)或平均值(回归)来决定。

2. 工作原理 (以分类为例)
  1. 存储数据:KNN是一种“惰性学习”(lazy learning)算法。它不会从训练数据中学习一个判别函数,而是简单地把所有的训练样本存储起来

  2. 计算距离:当需要预测一个新数据点(查询点)时,KNN计算该点与训练集中每一个点的距离

  3. 寻找邻居:选取距离最近的K个训练样本(这就是K的由来)。

  4. 投票决策:对于分类任务,统计这K个邻居中哪个类别最多,就将新数据点预测为那个类别。

3. 关键参数与概念
  • K值:邻居的数量。

    • K值过小(如K=1):模型变得复杂,容易受到噪声数据的干扰,即过拟合

    • K值过大:模型变得简单,学习的近似误差增大,容易忽略训练数据中的细节,即欠拟合

    • 如何选择K:通常通过交叉验证来选择,一般取一个较小的奇数(为了避免平票),具体值需要根据数据实验决定。

  • 距离度量:如何计算两个点之间的“远近”。

    • 欧氏距离:最常用,

    • 曼哈顿距离d = |x₂ - x₁| + |y₂ - y₁|

    • 闵可夫斯基距离:欧氏和曼哈顿距离的泛化形式。

  • 决策规则

    • 分类:多数投票法。可以引入距离加权投票(距离越近的邻居权重越大),以提高准确性。

    • 回归:取K个邻居目标值的平均值。同样可以引入距离加权。

4. 算法特点
  • 优点

    • 原理简单,易于理解和实现。

    • 无需训练过程(惰性学习),只需存储数据。

    • 对数据的分布没有假设,适用于各种复杂数据。

  • 缺点

    • 计算成本高:预测时需要计算与所有训练样本的距离,当数据集很大时,预测速度非常慢。

    • 对不平衡数据敏感:如果某个类的样本数量过多,会对投票结果产生过大影响。

    • 维度灾难:在高维特征空间中,点与点之间的距离会变得很不明显,导致性能下降。

    • 对特征尺度敏感:如果特征量纲不一,距离计算会被大尺度的特征主导。因此,使用KNN前通常需要做数据标准化/归一化

KNeighborsClassifier 是实现 K 最近邻 (K-NN) 算法的核心类,其预测规则非常简单:通过测量新样本与训练集中所有样本的距离,找出最相似的 K 个样本(邻居),然后通过这 K 个邻居的类别投票来决定新样本的类别。

它的构造函数包含多个关键参数,用于灵活地定制算法的行为。下面是所有参数的详细介绍:

sklearn.neighbors.KNeighborsClassifier(
    n_neighbors=5,
    *,
    weights='uniform',
    algorithm='auto',
    leaf_size=30,
    p=2,
    metric='minkowski',
    metric_params=None,
    n_jobs=None
)

KNeighborsClassifier 的主要参数如下表所示:

参数名 默认值 可选值/类型 描述 调优建议
n_neighbors 5 int 确定用于查询的邻居数量 (k值) 较小的k值:模型更复杂,可能对噪声敏感较大的k值:模型更简单,决策边界更平滑 需要调优 通常通过交叉验证选择,一般从3-10开始尝试
weights 'uniform' 'uniform', 'distance', 或 callable 'uniform':所有近邻权重相等'distance':权重为距离的倒数,近邻影响更大callable:用户自定义的函数(接收距离数组,返回权重数组) 需要调优 尝试 'distance' 往往能提升模型性能
algorithm 'auto' {'auto', 'ball_tree', 'kd_tree', 'brute'} 计算最近邻的算法'auto':自动选择'ball_tree'/'kd_tree':树结构算法,适用于数据量较大或维数适中(如维数小于20时[kd_tree效率高])'brute':暴力搜索,适用于小数据集或高维稀疏数据 通常使用 'auto' 即可
leaf_size 30 int 传递给 BallTree 或 KDTree 的叶子大小。影响树的构建和查询速度以及内存存储。 对性能影响小,通常保持默认
p 2 int 距离度量公式的超参数**p=1:曼哈顿距离p=2:欧氏距离 (默认) p=其他值:相应的闵可夫斯基距离 对于大多数情况,使用默认的 p=2 (欧氏距离) 即可
metric 'minkowski' str or callable 用于距离计算的度量。默认为 'minkowski'(当 p=2 时即欧氏距离)。其他可选如 'euclidean'、'manhattan'、'chebyshev'、'cosine' 或自定义可调用对象 对于数值型数据,默认的欧氏距离通常足够
metric_params None dict 传递给距离度量函数的额外关键字参数 多数情况下无需设置
n_jobs None int 并行运行的任务数。None:1-1:使用所有处理器 大数据集且核多时可设置为 -1 以加速搜索
5. 具体示例
from sklearn.datasets import load_iris
from sklearn.metrics import accuracy_score, classification_report
from sklearn.model_selection import train_test_split
from sklearn.neighbors import KNeighborsClassifier
from sklearn.preprocessing import StandardScaler
​
# 1,加载数据
iris = load_iris()
X = iris.data  # 特征矩阵 (150个样本,4个特征:萼长、萼宽、瓣长、瓣宽)
y = iris.target  # 特征值 目标向量 (3类鸢尾花:0, 1, 2)
​
# 2,数据预处理
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2)  # 划分训练集和测试集
​
scaler = StandardScaler()  # 数据标准化:消除不同特征量纲的影响
X_train_scaled = scaler.fit_transform(X_train)  # fit计算生成模型,transform通过模型转换数据
X_test_scaled = scaler.transform(X_test)  # # 使用训练集的参数转换测试集
​
# 3,创建和训练KNN模型
knn = KNeighborsClassifier(n_neighbors=3)  # 创建KNN分类器实例,选择K=3
knn.fit(X_train_scaled, y_train)  # “训练”模型(惰性学习,这里实际上只是存储数据)
​
# 4,进行预测并评估模型
y_pred = knn.predict(X_test_scaled)  # 在测试集上进行预测
print('knn预测值:', y_pred)
print('正确值   :', y_test)
​
accuracy = accuracy_score(y_test, y_pred)  # 计算准确率
print(f'测试集准确率:{accuracy:.2f}')
print('分类报告:\n', classification_report(y_test, y_pred, target_names=iris.target_names))

运行结果:

knn预测值: [2 1 2 0 2 2 2 0 0 1 0 1 1 1 1 2 0 2 1 1 0 2 0 0 1 2 0 1 0 0]
正确值   : [2 1 1 0 2 2 2 0 0 1 0 1 1 1 1 2 0 2 1 1 0 1 0 0 1 2 0 1 0 0]
测试集准确率:0.93
分类报告:
               precision    recall  f1-score   support
​
      setosa       1.00      1.00      1.00        11
  versicolor       1.00      0.83      0.91        12
   virginica       0.78      1.00      0.88         7
​
    accuracy                           0.93        30
   macro avg       0.93      0.94      0.93        30
weighted avg       0.95      0.93      0.93        30

数学知识:拟合 

形象的说,拟合就是把平面上一系列的点,用一条光滑的曲线连接起来。因为这条曲线有无数种可能,从而有各种拟合方法。拟合的曲线一般可以用函数表示,根据这个函数的不同有不同的拟合名字。


网站公告

今日签到

点亮在社区的每一天
去签到