跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客我的书AI学习GitHub 精选镜像AI工具UI配色美学关于
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
PythonAI算法

KNN 算法原理、实现与 K 值调参指南

K 近邻(KNN)算法的核心思想、距离度量方法及流程。通过 Scikit-learn 和手动实现展示了代码应用,重点分析了 K 值对分类结果的影响,并利用交叉验证选择最优 K 值。文章还总结了 KNN 的优缺点、优化方法及应用场景,为机器学习入门提供了实用参考。

Pythonist发布于 2026/3/29更新于 2026/10/25106 浏览
KNN 算法原理、实现与 K 值调参指南

一、背景介绍

K 近邻算法(K-Nearest Neighbors, KNN)是机器学习中最简单、最直观的算法之一,其核心思想源于人类对相似事物的判断逻辑 ——'近朱者赤,近墨者黑'。该算法无需复杂的训练过程,直接通过计算样本间的距离来进行分类或回归,广泛应用于图像识别、文本分类、推荐系统等领域。

二、KNN 算法原理

2.1 核心思想

KNN 的核心思想是:对于一个待预测样本,找到训练数据中与其最相似的 K 个样本(近邻),根据这 K 个样本的类别(分类问题)或数值(回归问题)进行投票或平均,从而确定待预测样本的类别或数值。

关键点:

相似性度量:通过距离函数衡量样本间的相似性。

K 值选择:近邻数量 K 对结果影响显著。

投票机制:分类问题通常采用多数投票,回归问题采用均值或加权平均。

2.2 距离度量方法

常见的距离度量方法包括:

欧氏距离:适用于连续变量,计算两点间的直线距离。

曼哈顿距离:适用于城市网格路径等场景,计算两点间的折线距离。

余弦相似度:适用于文本、图像等高维数据,衡量向量间的方向相似性。

2.3 算法流程

KNN 算法的典型流程如下:

1·数据预处理:对数据进行清洗、归一化,避免特征量纲影响距离计算。

2·计算距离:计算待预测样本与所有训练样本的距离。

3·选择近邻:按距离升序排列,选取前 K 个最近邻样本。

4·分类 / 回归决策:

分类:统计 K 个近邻的类别,选择出现次数最多的类别。

回归:计算 K 个近邻数值的平均值或加权平均值。

2.4 算法结构

三、KNN 算法代码实现

3.1 基于 Scikit-learn 的简单实现

以鸢尾花数据集(Iris Dataset)为例,演示 KNN 分类的完整流程。

import numpy as np
import matplotlib.pyplot as plt
from sklearn import datasets
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.neighbors import KNeighborsClassifier
from sklearn.metrics import accuracy_score

# 加载鸢尾花数据集
iris = datasets.load_iris()
X = iris.data[:, :] 
y = iris.target
feature_names = iris.feature_names[:]


X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=, random_state=)


scaler = StandardScaler()
X_train = scaler.fit_transform(X_train)
X_test = scaler.transform(X_test)


knn = KNeighborsClassifier(n_neighbors=)
knn.fit(X_train, y_train)


y_pred = knn.predict(X_test)
accuracy = accuracy_score(y_test, y_pred)
()

2
# 仅取前两个特征,便于可视化
2
# 划分训练集和测试集
0.3
42
# 数据标准化
# 创建 KNN 分类器(K=5)
5
# 预测测试集
print
f"Accuracy with K=5: {accuracy:.2f}"
# 输出:Accuracy with K=5: 0.98
3.2 手动实现 KNN(自定义代码)

为深入理解算法原理,我们手动实现 KNN 分类器:

class CustomKNN:
    def __init__(self, n_neighbors=3):
        self.n_neighbors = n_neighbors

    def fit(self, X_train, y_train):
        self.X_train = X_train
        self.y_train = y_train

    def predict(self, X_test):
        predictions = []
        for x in X_test:
            # 计算距离
            distances = [np.sqrt(np.sum((x - x_train)**2)) for x_train in self.X_train]
            # 获取最近的 K 个样本索引
            k_indices = np.argsort(distances)[:self.n_neighbors]
            # 获取对应的类别
            k_nearest_labels = self.y_train[k_indices]
            # 多数投票
            most_common = np.bincount(k_nearest_labels).argmax()
            predictions.append(most_common)
        return np.array(predictions)

# 使用自定义 KNN
custom_knn = CustomKNN(n_neighbors=3)
custom_knn.fit(X_train, y_train)
y_pred_custom = custom_knn.predict(X_test)
print(f"Custom KNN Accuracy: {accuracy_score(y_test, y_pred_custom):.2f}")
# 输出:0.96 

四、K 值选择与可视化分析

4.1 K 值对分类结果的影响

K 值是 KNN 算法的核心超参数,其大小直接影响分类结果:

  • K 值过小:模型复杂度高,易受噪声影响,导致过拟合。
  • K 值过大:模型趋于平滑,可能忽略局部特征,导致欠拟合。

示例:在鸢尾花数据集上,不同 K 值的分类边界差异如下:

def plot_decision_boundary(clf, X, y, title, k=None):
    plt.figure(figsize=(8, 6))
    x_min, x_max = X[:, 0].min() - 1, X[:, 0].max() + 1
    y_min, y_max = X[:, 1].min() - 1, X[:, 1].max() + 1
    xx, yy = np.meshgrid(np.arange(x_min, x_max, 0.02), np.arange(y_min, y_max, 0.02))
    Z = clf.predict(np.c_[xx.ravel(), yy.ravel()])
    Z = Z.reshape(xx.shape)
    plt.contourf(xx, yy, Z, alpha=0.8)
    # 绘制散点图
    for i, color in zip([0, 1, 2], ['r', 'g', 'b']):
        idx = np.where(y == i)
        plt.scatter(X[idx, 0], X[idx, 1], c=color, label=iris.target_names[i], edgecolor='k')
    plt.xlabel(feature_names[0])
    plt.ylabel(feature_names[1])
    plt.title(f"KNN Decision Boundary (K={k})")
    plt.legend()
    plt.show()

# K=1(过拟合)
knn1 = KNeighborsClassifier(n_neighbors=1)
knn1.fit(X_train, y_train)
plot_decision_boundary(knn1, X_test, y_test, "K=1", k=1)

# K=15(欠拟合)
knn15 = KNeighborsClassifier(n_neighbors=15)
knn15.fit(X_train, y_train)
plot_decision_boundary(knn15, X_test, y_test, "K=15", k=15)
4.2 交叉验证选择最优 K 值

通过交叉验证可以有效选择最优 K 值:

from sklearn.model_selection import cross_val_score

# 候选 K 值
k_values = range(1, 31)
cv_scores = []
for k in k_values:
    knn = KNeighborsClassifier(n_neighbors=k)
    scores = cross_val_score(knn, X_train, y_train, cv=5, scoring='accuracy')
    cv_scores.append(scores.mean())

# 绘制 K 值与准确率曲线
plt.plot(k_values, cv_scores, marker='o', linestyle='--', color='b')
plt.xlabel('K Value')
plt.ylabel('Cross-Validation Accuracy')
plt.title('K Value Selection via Cross-Validation')
plt.show()

五、KNN 算法的优缺点与优化

5.1 优点

简单易懂:原理直观,无需复杂数学推导。

无需训练:直接使用训练数据进行预测。

泛化能力强:对非线性数据分布有较好的适应性。

5.2 缺点

计算复杂度高:预测时需计算与所有训练样本的距离。

存储成本高:需存储全部训练数据。

对噪声敏感:K 值过小时,异常值可能显著影响结果。

5.3 优化方法

数据预处理:归一化、特征选择。

近似最近邻搜索:KD 树、球树等加速算法。

加权投票:根据距离赋予不同权重。

六、KNN 算法的应用场景

  • **图像识别与分类:**常用于手写数字识别、人脸识别等任务。
  • **推荐系统:**基于用户或物品的相似度进行推荐。
  • **医疗诊断:**根据患者的临床指标预测疾病类别。
  • **异常检测:**通过判断样本与近邻的距离识别异常点。

七、KNN 与其他算法的对比

算法核心思想优点缺点适用场景
KNN基于相似性投票 / 平均简单直观、无需训练计算慢、存储成本高、高维性能差小规模数据、实时预测
逻辑回归基于概率的线性分类训练快、可解释性强仅适用于线性可分数据、需调参二分类、概率预测
决策树基于特征划分的树结构分类可解释性强、能处理非线性数据易过拟合、对噪声敏感分类规则提取、快速预测

八、小结

KNN 算法以其简单性和直观性成为机器学习入门的经典算法,适用于小规模、低维数据的快速分类 / 回归任务。尽管存在计算效率和高维性能的局限,但其思想为许多复杂算法提供了基础。通过数据预处理、近似搜索和加权机制,KNN 的实用性可进一步提升;未来,随着硬件计算能力的提升和近似搜索算法的发展,KNN 在大规模数据中的应用可能迎来新突破。结合深度学习的特征提取能力,可构建更强大的混合模型。

目录

  1. 一、背景介绍
  2. 二、KNN 算法原理
  3. 2.1 核心思想
  4. 2.2 距离度量方法
  5. 2.3 算法流程
  6. 2.4 算法结构
  7. 三、KNN 算法代码实现
  8. 3.1 基于 Scikit-learn 的简单实现
  9. 加载鸢尾花数据集
  10. 划分训练集和测试集
  11. 数据标准化
  12. 创建 KNN 分类器(K=5)
  13. 预测测试集
  14. 输出:Accuracy with K=5: 0.98
  15. 3.2 手动实现 KNN(自定义代码)
  16. 使用自定义 KNN
  17. 输出:0.96
  18. 四、K 值选择与可视化分析
  19. 4.1 K 值对分类结果的影响
  20. K=1(过拟合)
  21. K=15(欠拟合)
  22. 4.2 交叉验证选择最优 K 值
  23. 候选 K 值
  24. 绘制 K 值与准确率曲线
  25. 五、KNN 算法的优缺点与优化
  26. 5.1 优点
  27. 5.2 缺点
  28. 5.3 优化方法
  29. 六、KNN 算法的应用场景
  30. 七、KNN 与其他算法的对比
  31. 八、小结

更多推荐文章

查看全部
  • 多模态与大语言模型经典论文解读目录
  • 国产开源时序数据库 IoTDB 选型指南与核心功能解析
  • CLI-Anything:让所有软件都能被 AI Agent 原生调用
  • 动态规划:子数组与子串问题
  • SpringBoot 旅游管理系统设计与实现
  • 设计模式:模板方法模式详解
  • Ollama 本地部署教程:Windows/Linux/Mac 安装与使用指南
  • 智能家居电平转换电路实战:从理论到PCB制作
  • Web 开发者多模态 Agent 图像识别 Skills 全栈实战
  • WebStorm 下载与安装实战
  • Ghostty + Yazi + Lazygit:构建现代化终端开发工作流
  • Claude Code 模型配置详解
  • Python Flask 企业合同管理系统技术要点与选型对比
  • WSL2 + Ubuntu 24.04 + Docker Desktop 本地开发环境搭建
  • C++11 右值引用与移动语义详解及容器性能优化
  • rrweb snapshot 深度解密:DOM 序列化与重建技术
  • 前端实现 PC 网站微信扫码授权登录
  • 自然语言处理在教育领域的实战应用
  • 多模态大模型评测框架 LMMs-Eval 详解
  • 基于 YOLOv8 的无人机枸杞树病害检测数据集与训练方案

相关免费在线工具

  • 加密/解密文本

    使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online

  • RSA密钥对生成器

    生成新的随机RSA私钥和公钥pem证书。 在线工具,RSA密钥对生成器在线工具,online

  • Mermaid 预览与可视化编辑

    基于 Mermaid.js 实时预览流程图、时序图等图表,支持源码编辑与即时渲染。 在线工具,Mermaid 预览与可视化编辑在线工具,online

  • 随机西班牙地址生成器

    随机生成西班牙地址(支持马德里、加泰罗尼亚、安达卢西亚、瓦伦西亚筛选),支持数量快捷选择、显示全部与下载。 在线工具,随机西班牙地址生成器在线工具,online

  • Gemini 图片去水印

    基于开源反向 Alpha 混合算法去除 Gemini/Nano Banana 图片水印,支持批量处理与下载。 在线工具,Gemini 图片去水印在线工具,online

  • curl 转代码

    解析常见 curl 参数并生成 fetch、axios、PHP curl 或 Python requests 示例代码。 在线工具,curl 转代码在线工具,online