Lucas带你手撕机器学习——K近邻

news2024/11/29 6:31:32

K近邻 (K-Nearest Neighbor KNN)

K近邻算法(K-Nearest Neighbors, KNN)是一种简单直观的机器学习算法,适用于分类和回归问题。它的核心思想是:判断一个数据点的类别或预测值时,参考它在特征空间中最近的 KKK 个数据点

1. KNN 的基本原理

KNN 算法基于距离的度量来进行分类或回归。其工作方式可以用以下步骤来描述:

分类问题中的 KNN

假设我们有一些数据点,每个数据点都有一个类别,比如颜色。现在有一个新的点,我们希望知道这个点属于哪一种颜色类别。

  1. 选择 K:选择一个正整数 K,表示我们要考虑的新点周围最近的 K 个邻居点。

  2. 计算距离:计算新点与每个已有点之间的距离。常用的距离度量是欧几里得距离,公式如下:

在这里插入图片描述

其中 x 和 y 是两个数据点的特征向量。

同时有的情况也会使用曼哈顿距离公式。

在这里插入图片描述

  1. 选择最近的 K 个邻居:从已有数据中,选择与新点距离最近的 K 个点。

  2. 投票分类:统计这 K 个邻居中各个类别的数量,选择出现次数最多的类别作为新点的预测类别。

回归问题中的 KNN

在回归问题中,KNN 的原理类似,只是预测的是一个数值,而不是一个类别。

  1. 选择 K:选择一个正整数 K。
  2. 计算距离:计算新点与每个已有点之间的距离。
  3. 选择最近的 K 个邻居:选择与新点距离最近的 K 个点。
  4. 取平均值:对这 K 个邻居的数值取平均值,作为新点的预测值。

2. K 值的选择

  • 如果 K 值较小(例如 1),模型会对训练数据的噪声非常敏感,容易导致过拟合。
  • 如果 K 值较大(例如接近数据总数),模型会变得非常平滑,可能忽略细节,导致欠拟合。
  • 常见的做法是通过交叉验证选择一个合适的 K 值。

3. 使用 Scikit-Learn 实现 KNN

我们可以用 Python 的 Scikit-Learn 库实现一个简单的 KNN 示例。以下是代码示例,用于分类问题:

import numpy as np
from sklearn.model_selection import train_test_split
from sklearn.neighbors import KNeighborsClassifier
from sklearn.metrics import accuracy_score

# 生成模拟数据
np.random.seed(42)
X = np.random.rand(100, 2) * 10  # 100 个样本,2 个特征
y = (X[:, 0] + X[:, 1] > 10).astype(int)  # 简单规则:如果 x1 + x2 > 10,标记为 1,否则为 0

# 拆分数据为训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

# 创建 KNN 分类器并进行训练
k = 3  # 使用 3 个最近邻居
model = KNeighborsClassifier(n_neighbors=k)
model.fit(X_train, y_train)

# 预测并计算准确率
y_pred = model.predict(X_test)
accuracy = accuracy_score(y_test, y_pred)
print(f'模型在测试集上的准确率: {accuracy}')

# 可视化结果
import matplotlib.pyplot as plt
plt.figure(figsize=(8, 6))
plt.scatter(X_test[:, 0], X_test[:, 1], c=y_pred, cmap='coolwarm', marker='o', label='预测结果')
plt.scatter(X_test[:, 0], X_test[:, 1], c=y_test, cmap='coolwarm', marker='x', alpha=0.5, label='真实值')
plt.xlabel('特征 1')
plt.ylabel('特征 2')
plt.title(f'KNN 分类结果 (K={k})')
plt.legend(loc='upper left')
plt.show()

在这里插入图片描述

4. 代码解释

  • 生成模拟数据:生成了 100 个样本,每个样本有两个特征。标签 y 是通过 x1+x2>10 来生成的二分类问题。
  • 数据集拆分:将数据集分为训练集和测试集,80% 用于训练,20% 用于测试。
  • 创建和训练模型:使用 KNeighborsClassifier 类创建 KNN 模型,并用训练集数据进行训练。
  • 预测和评估:用测试集数据进行预测,计算模型在测试集上的准确率。
  • 可视化结果:使用散点图展示测试集中数据点的预测结果和真实标签。

5. Pytorch实现KNN

import torch
import torch.nn.functional as F
import numpy as np
import matplotlib.pyplot as plt
from sklearn.model_selection import train_test_split
from sklearn.datasets import make_classification

# 生成模拟数据
X, y = make_classification(n_samples=100, n_features=2, n_classes=2, random_state=42)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

# 将数据转换为 PyTorch 张量
X_train_tensor = torch.tensor(X_train, dtype=torch.float32)
X_test_tensor = torch.tensor(X_test, dtype=torch.float32)
y_train_tensor = torch.tensor(y_train, dtype=torch.int64)

# 定义 KNN 预测函数
def knn_predict(X_train, y_train, X_test, k=3):
    # 计算所有测试点与训练点的距离
    distances = torch.cdist(X_test, X_train)
    
    # 找到距离最近的 K 个训练点的索引
    knn_indices = distances.topk(k, largest=False).indices
    
    # 通过 K 个邻居的标签进行投票
    knn_labels = y_train[knn_indices]
    y_pred = torch.mode(knn_labels, dim=1).values
    
    return y_pred

# 使用 KNN 进行预测
k = 3
y_pred = knn_predict(X_train_tensor, y_train_tensor, X_test_tensor, k)

# 计算准确率
accuracy = (y_pred == torch.tensor(y_test)).float().mean().item()
print(f'KNN 模型在测试集上的准确率: {accuracy}')

# 可视化结果
plt.figure(figsize=(8, 6))
plt.scatter(X_test[:, 0], X_test[:, 1], c=y_pred.numpy(), cmap='coolwarm', marker='o', label='预测结果')
plt.scatter(X_test[:, 0], X_test[:, 1], c=y_test, cmap='coolwarm', marker='x', alpha=0.5, label='真实值')
plt.xlabel('特征 1')
plt.ylabel('特征 2')
plt.title(f'KNN 分类结果 (K={k})')
plt.legend(loc='upper left')
plt.show()

代码说明

  1. 数据生成:使用 make_classification 生成二维分类数据,便于可视化。然后使用 train_test_split 将数据拆分为训练集和测试集。
  2. 数据转换:将数据转换为 PyTorch 的张量,以便后续计算。
  3. 自定义 KNN 函数
    • torch.cdist 用于计算测试集和训练集之间的欧几里得距离矩阵。
    • 使用 topk 找到距离最近的 KKK 个训练样本的索引。
    • 使用 torch.mode 进行多数投票,从而确定测试样本的预测标签。
  4. 计算准确率:比较预测值和真实标签,计算分类的准确率。
  5. 可视化结果:使用 Matplotlib 绘制预测结果与真实标签的散点图。

6. KNN 的优缺点

优点

  • 简单直观:KNN 没有复杂的训练过程,适合对模型原理的初步理解。
  • 无参数学习:KNN 是一种懒惰学习算法,不需要显式地训练模型,而是直接保存训练样本。
  • 适合小规模数据集:对于样本量小且特征不多的数据集,KNN 效果较好。

缺点

  • 计算量大:KNN 需要对每个新样本计算与所有训练样本的距离,所以在样本量大时,计算开销大。
  • 对特征尺度敏感:KNN 基于距离度量,不同尺度的特征会对距离计算产生影响,因此通常需要对特征进行标准化处理。
  • 受噪声影响大:当数据中存在噪声或异常值时,KNN 的分类结果会受到很大影响。

7. 总结

KNN 是一个基于“多数投票”思想的算法:

  • 分类:通过计算新样本与训练样本的距离,选择 KKK 个最近的邻居,选择出现次数最多的类别作为新样本的类别。
  • 回归:通过选择 KKK 个最近的邻居,取这些邻居标签的平均值作为预测值。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2222175.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【2024】【字节青训营】:字节青训营入营测试题——Java版本(已提交通过)

目录 简单题目 计算x到y的最小步数 环状 DNA 序列的最小表示法 Base32 解码和编码 打点计时器 兔群繁殖之谜 完美整数 找出整数数组中占比超过 一半 的数 找出最长的神奇数列 找单独的数 字符串最短循环字串 二进制反码转换问题 中等题目 简单四则运算 数字翻译…

什么是微服务中的反应性扩展?

大家好,我是锋哥。今天分享关于【什么是微服务中的反应性扩展?】面试题?希望对大家有帮助; 什么是微服务中的反应性扩展? Reactive Extensions 也称为 Rx。这是一种设计方法,我们通过调用多个服务来收集结果…

STM32G474使用TIM2触发DAC输出输出正弦波

STM32G474使用TIM2触发DAC输出,数据从内存到外设就要使用DMA来协助。DAC1每隔1秒输出一个正弦波数据,就会模拟近似得到模拟的正弦波形。用来测试CPU内部的运算放大器,或者用作其它模拟输入信号。 测试程序如下: #include "…

立志最细,FreeRtos的中断管理(Interrupt Management)函数,详解!!!

前言:本文参考,韦东山老师开发文档,连接放在最后。 为什么需要中断管理函数? 在FreeRtos操作系统中,需要实时响应性,也就是随时随地必须保证正常多任务的运行,如果有中断发生,因为中…

Spring Cloud --- Sentinel 规则持久化

为什么要持久化 一旦我们重启微服务应用,sentinel 规则将消失,生产环境需要将配置规则进行持久化 怎么实现持久化 将限流配置规则持久化进 Nacos 保存,只要刷新 8401 某个 rest 地址,sentinel 控制台的流控规则就能看到&#x…

keil新建工程HC32L176MATA

先看一下最后的文件夹结构(文件夹结构可以根据项目实际的需要去定义) keil内: 参考文章: KEIL平台下新建华大HC32F460单片机工程笔记_hc32f keil环境搭建-CSDN博客 (我根据需要,创建的文件夹结构和原文是有…

面试总结一

面试总结 1、自我介绍一下自己2.面试11、css常用布局有哪些2、css常用的属性3.js原型链4、开发中遇到的技术难点5、闭包6、ts了解什么呢7.git都用什么命令8、vue怎么打包9.vue启动一个项目需要什么10、vue怎么创建一个项目 2.面试21.vue2和vue3有什么区别2.复杂组件的封装&…

C#,自动驾驶技术,ASAM OpenDRIVE BS 1.8.0 规范摘要与C# .NET Parser

本文介绍自动驾驶技术的标准之一《ASAM OpenDRIVE》1.8.0 版本的规范摘要,及北京联高软件开发有限公司实现的 C# 版本 xodr 文件(XML) Parser 源代码。 本文档是 ASAM e.V. 的版权财产。 在更改常规许可条款时,ASAM 允许不受限制地…

gateway 整合 spring security oauth2

微服务分布式认证授权方案 在分布式授权系统中,授权服务要独立成一个模块做统一授权,无论客户端是浏览器,app或者第三方,都会在授权服务中获取权限,并通过网关访问资源 OAuth2的四种授权模式 授权码模式 授权服务器将授…

【原创】统信UOS如何安装最新版Node.js(20.x)

注意直接使用sudo apt install nodejs命令安装十有八九会预装10.x的老旧版本Node.js,如果已经安装的建议删除后安装如下方法重装。 在统信UOS系统中更新Node.js可以通过以下步骤进行: 1. 卸载当前版本的Node.js 首先,如果系统中已经安装了N…

Maven进阶——坐标、依赖、仓库

目录 1.pomxml文件 2. 坐标 2.1 坐标的概念 2.2 坐标的意义 2.3 坐标的含义 2.4 自己项目的坐标 2.5 第三方项目坐标 3. 依赖 3.1 依赖的意义 3.2 依赖的使用 3.3 第三方依赖的查找方法 3.4 依赖范围 3.5 依赖传递和可选依赖 3.5.1 依赖传递 3.5.2 依赖范围对传…

推荐一个开源非线性视频编辑器:Kdenlive

Kdenlive是一个开源的视频编辑软件,项目始于约2003年。它基于Qt和KDE框架库构建,大部分视频处理由MLT框架完成,同时依赖其他开源项目如FFmpeg、frei0r、movit、ladspa、sox等。 软件特点: - 多轨视频编辑:支持多个音频…

大数据新视界 -- 大数据大厂之大数据和增强现实(AR)结合:创造沉浸式数据体验

💖💖💖亲爱的朋友们,热烈欢迎你们来到 青云交的博客!能与你们在此邂逅,我满心欢喜,深感无比荣幸。在这个瞬息万变的时代,我们每个人都在苦苦追寻一处能让心灵安然栖息的港湾。而 我的…

2024 睿抗机器人开发者大赛(RAICOM)-【网络安全】CTF 部分WP

文章目录 一、前言二、MICS你是黑客么循环的压缩包Goodtime 三、WEBpy 四、Crypto变异凯撒RSAcrypto3 一、前言 WP不完整,仅供参考! 除WEB,RE,PWN外,其余附件均已打包完毕 也是一个对MISC比较友好的一个比赛~ 123网…

springboot066人事系统(论文+源码)_kaic

基于vue的人事系统 摘要 随着信息技术在管理上越来越深入而广泛的应用,作为学校以及一些培训机构,都在用信息化战术来部署线上学习以及线上考试,可以与线下的考试有机的结合在一起,实现基于vue的人事系统在技术上已成熟。本文介绍…

u盘装win10系统提示“windows无法安装到这个磁盘,选中的磁盘采用GPT分区形式”解决方法

我们在u盘安装原版win10 iso镜像时,发现在选择硬盘时提示了“windows无法安装到这个磁盘,选中的磁盘采用GPT分区形式”,直接导致了无法继续安装下去。出现这种情况要怎么解决呢?下面小编分享u盘安装win10系统提示“windows无法安装到这个磁盘…

信息安全工程师(53)网络安全审计机制与实现技术

前言 网络安全审计机制是指为了保护网络安全并发现潜在风险和漏洞而进行的一系列审计活动。审计的目的是检查并评估网络系统的安全性,以确保其符合相关法律法规和安全标准。 一、网络安全审计机制的重要性 网络安全审计机制对于保护组织的信息资产和敏感数据至关重要…

简单的 curl HTTP的POSTGET请求以及ip port连通性测试

简单的 curl HTTP的POST&GET请求以及ip port连通性测试 1. 需求 我们公司有一个演示项目,需要到客户那边进行项目部署,项目部署完成后我们需要进行项目后端接口的测试功能,但是由于客户那边么有条件安装类似于postman这种的测试工具&am…

CSS3文本阴影、文本换行、文本溢出、文本修饰、文本描边的使用

1.文本阴影:text-shadow 2.文本换行: white-space:pre(可以理解为按原文显示) white-space:pre-wrap(不会超出父容器) 3.文本溢出 text-overflow:ellipsis一般配合文本…

人工智能的未来:变革生活与工作的新篇章

随着人工智能(AI)技术的飞速发展,我们正站在一个前所未有的变革时代。AI不仅重新定义了医疗、企业运营和日常生活的各个方面,还潜移默化地改变着我们的思维方式和工作习惯。本文将深入探讨人工智能技术的应用前景,以及…