0004 - 机器学习-K近邻算法

K 近邻算法 (KNN)

导语:机器学习两套合理分类体系

机器学习有两套主流划分维度,不要混在一起讲

  1. 按学习方式(有无标签)划分:有监督学习、无监督学习、半监督学习、强化学习
  2. 按任务输出划分:分类任务、回归任务、聚类任务

很多初学者容易混淆两套分类,KNN 属于有监督学习 ,它既可以完成分类任务 ,也可以完成回归任务

一、按学习方式划分(训练数据是否带标签)

1. 有监督学习

训练集同时具备:输入特征 X + 标签 Y(已知正确答案)。模型学习特征到标签的映射关系。

  • 子任务:
    • 分类:输出离散类别标签
      • 📌例子:根据花瓣长宽,判断这朵花是玫瑰、百合还是郁金香;根据邮件内容,判断是否为垃圾邮件。
    • 回归:输出连续数值
      • 📌例子:根据房屋面积、楼层、地段,预测房子的成交价格;根据历史天气数据,预测明天的温度。
  • 代表算法:KNN、逻辑回归、决策树、线性回归、随机森林
2. 无监督学习

训练集只有特征 X,没有标签 Y,算法自主挖掘数据内部结构,没有人给标准答案。

  • 子任务:聚类、降维、异常检测、关联规则
  • 📌例子:电商平台对用户购物行为做分组,自动划分出 "学生党""高消费人群""性价比用户",事先并不知道有哪几类人;对一堆图片自动把相似图片归为一组。
  • 代表算法:K‑Means、PCA 主成分分析
3. 半监督学习

少量样本带有标签,大量样本无标签。利用少量标注 + 海量无标注样本共同训练。

  • 📌例子:做图片识别,只有 100 张图片人工标注了 "猫 / 狗",硬盘里还有 10000 张没有打标签的猫狗图片,算法同时使用这两部分数据训练模型。
  • 适用场景:打标签成本极高,工业标注数据集经常遇到。
4. 强化学习

没有固定数据集。智能体 Agent 和环境交互,执行动作,接收奖励 / 惩罚信号,迭代优化行动策略。

  • 📌例子:训练游戏 AI 玩游戏,AI 不断操作上下左右,打赢游戏就给奖励,输了就惩罚,AI 自己慢慢学会通关;机器人不断尝试走路,摔倒得到负反馈,慢慢学会平稳行走。

二、按任务输出划分(拿到模型之后干什么)

  1. 分类任务 :预测离散类别。输出是类别。
    • 📌例子:判断体检人员是否患病;判断水果是苹果还是橘子。
  2. 回归任务 :预测连续数值。输出是数字。
    • 📌例子:预测未来一个月的销售额;预测人的身高。
  3. 聚类任务 :无监督,自动给数据分组。
    • 📌例子:根据客户消费记录,把客户自动分成若干群体。

✔KNN 定位总结:

学习方式:有监督学习

可完成任务:分类任务、回归任务

一、KNN 算法简介

K‑近邻算法,英文全称为 K‑Nearest Neighbor,简称 KNN ,既可以做分类任务 ,也可以做回归任务

✨核心思想

如果一个样本在特征空间中的 k 个最相似 (距离最近) 的样本中的大多数属于某一个类别,则该样本也属于这个类别。

通俗理解:根据你的邻居,推断你的类别

二、KNN 执行流程

🔹KNN 分类流程

  1. 计算未知样本到每一个训练样本的距离
  2. 将训练样本按照距离从小到大升序排序
  3. 取出距离最近的 K 个训练样本
  4. 多数表决:统计 K 个样本中各个类别样本的数量
  5. 将未知样本判定为出现次数最多的类别

🔹KNN 回归流程

回归任务不再输出类别,输出预测数值:

  1. 计算未知样本到每一个训练样本的距离
  2. 将训练样本按照距离从小到大升序排序
  3. 取出距离最近的 K 个训练样本
  4. 计算这 K 个样本目标值的平均值
  5. 将平均值作为未知样本的预测结果

💡如何找到最近 k 个邻居?距离度量,sklearn 底层自动计算,默认使用欧式距离。

三、sklearn 中 KNN 的 API 使用

3.1 sklearn 库介绍

scikit‑learn(简称 sklearn)是 Python 中最主流、开源的机器学习工具库。

  1. 封装大量算法:分类、回归、聚类、降维、特征预处理、模型评估全部封装好,不需要手动手写算法底层。
  2. 统一 API 接口规范 :几乎所有模型都遵循 fit()训练、predict()预测的统一调用范式,学习一个算法,其他算法上手很快。
  3. 内置数据集:自带鸢尾花、波士顿房价等测试数据集,方便做算法练习。
  4. 适用场景:传统机器学习项目,不包含深度学习神经网络;深度学习一般使用 TensorFlow/PyTorch。

KNN 相关类都放在模块 sklearn.neighbors 下面:

  • KNeighborsClassifier:KNN 分类模型
  • KNeighborsRegressor:KNN 回归模型

通用模型使用四步套路:

  1. 导包:导入对应算法类
  2. 准备数据集:特征 X,标签 y
  3. 模型实例化 + fit(X_train,y_train) 训练
  4. predict(X_test) 做预测

3.2 KNN 分类代码示例(垃圾邮件模拟案例)

业务场景:模拟简单二分类,0 代表正常邮件,1 代表垃圾邮件,预测样本[4]是正常邮件还是垃圾邮件。

复制代码
# 1.导包 此处导入knn分类模型
from sklearn.neighbors import KNeighborsClassifier

# 2.准备数据(此处我们模拟数据)
# x_train:训练集特征,方括号嵌套,即使只有1个特征,也要写成二维列表格式
x_train = [[0], [1], [2], [3]]
# x_test:待预测的测试样本
x_test = [[4]]
# y_train:训练集标签,0=正常邮件,1=垃圾邮件
y_train = [0, 0, 0, 1]

# 3.模型使用
# 3.1 创建分类模型
# n_neighbors=2:设置K值,取距离最近2个邻居
# 注意:KNN投票出现票数相同时,底层优先选择标签索引更小的类别
knn_model = KNeighborsClassifier(n_neighbors=2)

# 3.2 模型训练 fit(特征,标签)
# KNN是惰性学习,fit不会真正训练计算权重,只是保存全部训练数据集
knn_model.fit(x_train, y_train)

# 3.3 模型预测,传入待预测样本
y_pred = knn_model.predict(x_test)

# 3.4 打印预测结果
print(f"分类预测结果为:{y_pred}")

代码逐行解释

  1. from sklearn.neighbors import KNeighborsClassifier:从 sklearn 的 neighbors 模块导入 KNN 分类器。
  2. x_train = [[0], [1], [2], [3]]:训练特征,sklearn 要求输入特征必须是二维数组,所以每个样本外面套一层[]
  3. y_train = [0, 0, 0, 1]:训练集标签,一维列表,和训练特征一一对应。
  4. KNeighborsClassifier(n_neighbors=2):实例化模型,n_neighbors就是超参数 K,代表取几个邻居。
  5. .fit(x_train, y_train):传入训练特征与标签。KNN 惰性算法,这里仅保存数据,没有复杂运算。
  6. .predict(x_test):对测试样本做预测,此时才会计算距离,查找 K 个邻居,投票输出类别。

3.3 KNN 回归代码示例(房价预测模拟案例)

业务场景:根据特征值预测房价,输出连续数字,不是类别。

复制代码
# 1.导包 此处导入knn回归模型
from sklearn.neighbors import KNeighborsRegressor

# 2.准备数据(此处我们模拟数据)
# x_train训练特征,二维格式
x_train = [[0], [1], [2], [3]]
# x_test待预测样本
x_test = [[4]]
# y_train标签,代表房价,单位万:0->70w,1->80w,2->100w,3->110w
y_train = [70, 80, 100, 110]

# 3.模型使用
# 3.1 创建回归模型,n_neighbors=3,取最近3个邻居
knn_model = KNeighborsRegressor(n_neighbors=3)

# 3.2 模型训练,保存训练数据
knn_model.fit(x_train, y_train)

# 3.3 模型预测,输出邻居目标值的平均值
y_pred = knn_model.predict(x_test)

# 3.4 打印预测结果
print(f"回归预测结果为:{y_pred}")

代码逐行解释

  1. from sklearn.neighbors import KNeighborsRegressor:导入 KNN 回归模型。
  2. 回归任务的标签y_train不再是类别编号,是真实连续数值,本例代表房价。
  3. KNeighborsRegressor(n_neighbors=3):实例回归模型,设置 K=3。
  4. .fit(x_train,y_train):同样惰性学习,保存训练数据。
  5. .predict(x_test):找到最近 K 个样本,计算这 K 个样本 y 值的平均值作为预测输出,不再做投票。

💡补充常用方法

  • .predict_proba():仅分类模型可用,输出每个样本属于各个类别的概率;回归模型没有这个方法。

四、距离度量

闵可夫斯基距离通用公式:

d₁₂ = 开 p 次方 (Σ |x₁ₖ − x₂ₖ|^p)

p 为可变参数,改变 p 得到不同距离:

表格

距离类型 参数 p 特点 适用场景
欧氏距离 p=2 勾股定理,直线距离 连续数值、低维空间(KNN 默认)
曼哈顿距离 p=1 各维度差值绝对值求和
切比雪夫距离 p→∞ 只看最大维度差异 极值主导场景,路径规划
闵可夫斯基距离 任意 p 通用公式 需要平衡多维度差异通用场景
  • p=2 → 欧氏距离
  • p=1 → 曼哈顿距离
  • p 趋向无穷大 → 切比雪夫距离

KNN 算法高度依赖距离计算,特征的数值大小会直接影响距离结果,所以需要做特征预处理

五、特征预处理:归一化 & 标准化

📌为什么要做预处理?

不同特征单位、数值量级差距巨大,某一个特征数值过大,会直接主导距离计算结果,算法无法学习其他特征。

例子:身高、体重、视力,体重数值远大于另外两个特征,计算距离时体重会起决定性作用。

1. 归一化 MinMaxScaler

把原始数据映射到 [min,max],默认映射到[0,1]

公式:

X' = (x − min) / (max − min)

X'' = X' * (mx − mi) + mi

  • 缺点:最大最小值极易受异常点干扰,鲁棒性差
  • 适用:小数据、数据比较干净没有异常值场景
  • sklearn API:sklearn.preprocessing.MinMaxScaler(feature_range=(0,1))

2. 标准化 StandardScaler

将数据转换为均值为 0,标准差为 1的标准正态分布。

公式:

X' = (x − mean) / σ

  • mean:该特征平均值
  • σ:该特征标准差

示例代码:

复制代码
from sklearn.preprocessing import StandardScaler

def dm03_StandardScaler():
    #准备数据
    data=[[90,2,10,40],
          [60,4,15,45],
          [75,3,13,46]]
    #实例化标准化对象
    transformer = StandardScaler()
    #转换数据
    data = transformer.fit_transform(data)
    print(data)
    print('transformer.mean_',transformer.mean_)
    print('transformer.var_',transformer.var_)
  • 特点:少量异常点对均值标准差影响很小,鲁棒性强
  • 适用:大数据、有噪声数据,工业开发优先使用标准化
  • sklearn API:sklearn.preprocessing.StandardScaler()

📊归一化 vs 标准化对比

表格

预处理 抗异常点 适用场景
归一化 MinMaxScaler 差,受最大最小值影响 小数据,数据无异常点
标准化 StandardScaler 较好,少量异常点影响小 大数据,嘈杂数据,工业常用

六、整体知识梳理总结

  1. KNN 可以做分类、回归;核心逻辑依靠距离找最近邻居做预测。
  2. K 值是超参数;距离计算默认欧氏距离,底层是闵可夫斯基距离。
  3. KNN 对特征数值敏感,必须做特征预处理。
  4. 归一化容易被异常点破坏;标准化更适合工业大数据项目。
  5. sklearn 提供现成 API,直接调用 fit 训练、predict 预测。

补充:KNN 属于惰性学习算法,训练阶段没有真正训练模型,只是保存全部训练数据集,预测时才计算距离。

相关推荐
ellenwan202644 分钟前
量化实现的难点,常在规则和流程
人工智能·python
Lethehong1 小时前
ToDesk远程终端怎么用:手机免进桌面排查 Windows,主机名/账号/ipconfig/进程一篇讲透
人工智能
天辛大师1 小时前
天心大师谈重新学会传统文化,AI时代的心经奥义
大数据·人工智能·随机森林·重构·启发式算法
新知图书1 小时前
第 12 章 案例实战:多模态客服智能体
人工智能·语音识别
吴佳浩1 小时前
企业如何把通用大模型训练成行业模型:Continued Pre-Training实战指南
人工智能·神经网络·llm
luckystar513~1 小时前
Hermes 实战 :多渠道接入——日报推送到飞书/Telegram
人工智能·agent·智能体开发·hermes实战·智能体网关
clorinda1 小时前
从零理解 PyTorch:用神经网络完成 MNIST 手写数字识别
人工智能·pytorch·神经网络
吴佳浩1 小时前
大模型是怎么来的:从数据到 Foundation Model
人工智能·llm·agent
IT_陈寒1 小时前
Redis Pipeline用错竟比不用还慢,这个坑我帮你踩过了
前端·人工智能·后端