【机器学习】K近邻

2. K近邻

K近邻算法(KNN)的基本思想是通过计算待分类样本与训练集中所有样本之间的距离,选取距离最近的 K 个样本,根据这些样本的标签进行分类或回归。KNN 属于非参数学习算法,因为它不假设数据的分布形式,主要依赖距离度量来进行决策。

优点

  • 简单易懂:KNN算法非常直观,容易理解和实现。
  • 无假设:KNN算法对数据没有假设,适用于复杂分布的数据集。
  • 适用于多类分类问题:KNN能够处理多类分类问题,只需在投票过程中考虑不同的类别即可。

缺点

  • 计算复杂度高:对于大规模数据集,KNN算法的计算复杂度较高,需要计算每个测试样本与所有训练样本之间的距离,耗时较长。
  • 对数据的尺度和噪声敏感:KNN对数据的尺度敏感,通常需要对数据进行标准化或归一化处理。此外,KNN对噪声敏感,可能会受到

异常值的影响。

  • 需要大存储空间:由于需要存储整个训练集,KNN算法占用较大的内存空间。

2.1 基本模型

对于分类问题,KNN 模型可以表示为:

f ( x ) = argmax c ∑ i = 1 K 1 ( y i = c ) f(\mathbf{x}) = \underset{c}{\text{argmax}} \sum_{i=1}^K \mathbf{1}(y_i = c) f(x)=cargmaxi=1K1(yi=c)

其中:

  • x \mathbf{x} x 是待分类的输入样本。
  • y i y_i yi 是 K 个邻近样本的标签。
  • 1 ( ⋅ ) \mathbf{1}(\cdot) 1() 是指示函数,当条件为真时取值为 1,否则为 0。
  • c c c 是所有可能的类别。

对于回归问题,KNN 模型的预测可以通过 K 个邻近样本的标签值的平均来实现:

y ^ = 1 K ∑ i = 1 K y i \hat{y} = \frac{1}{K} \sum_{i=1}^K y_i y^=K1i=1Kyi

或使用加权平均:

y ^ = ∑ i = 1 K w i ⋅ y i ∑ i = 1 K w i \hat{y} = \frac{\sum_{i=1}^K w_i \cdot y_i}{\sum_{i=1}^K w_i} y^=i=1Kwii=1Kwiyi

其中 w i w_i wi 是样本 y i y_i yi 的权重,通常可以根据距离的倒数或其他方式定义。

2.2 距离度量

KNN 算法中,距离度量是核心部分,决定了如何选择邻近样本。常用的距离度量方法包括:

欧氏距离(Euclidean Distance):

欧氏距离是最常见的距离度量方法,适用于特征尺度相同的场景。对于两个样本 x i \mathbf{x}_i xi x j \mathbf{x}_j xj,欧氏距离定义为:

d ( x i , x j ) = ∑ k = 1 n ( x i k − x j k ) 2 d(\mathbf{x}_i, \mathbf{x}_j) = \sqrt{\sum_{k=1}^n (x_{ik} - x_{jk})^2} d(xi,xj)=k=1n(xikxjk)2

其中:

  • n n n是特征的维度数。
  • x i k x_{ik} xik x j k x_{jk} xjk分别是样本 x i \mathbf{x}_i xi x j \mathbf{x}_j xj 在第 k 个维度上的特征值。

曼哈顿距离(Manhattan Distance):

曼哈顿距离适用于高维空间且特征不相关的情况。曼哈顿距离定义为:

d ( x i , x j ) = ∑ k = 1 n ∣ x i k − x j k ∣ d(\mathbf{x}_i, \mathbf{x}_j) = \sum_{k=1}^n |x_{ik} - x_{jk}| d(xi,xj)=k=1nxikxjk

曼哈顿距离计算的是两个样本在各个维度上的绝对差值之和。

闵可夫斯基距离(Minkowski Distance):

闵可夫斯基距离是欧氏距离和曼哈顿距离的泛化形式,定义为:

d ( x i , x j ) = ( ∑ k = 1 n ∣ x i k − x j k ∣ p ) 1 / p d(\mathbf{x}_i, \mathbf{x}_j) = \left(\sum_{k=1}^n |x_{ik} - x_{jk}|^p\right)^{1/p} d(xi,xj)=(k=1nxikxjkp)1/p

其中:

  • p p p 是参数,决定距离度量的形式。
  • p = 2 p=2 p=2 时,闵可夫斯基距离即为欧氏距离;当 p = 1 p=1 p=1 时,即为曼哈顿距离。

2.3 决策规则

KNN 的决策规则基于多数投票或加权投票的原则:

分类问题:

  • 对于分类任务,KNN 会根据 K 个邻近样本中出现频率最高的类别来决定待分类样本的类别。若出现频率相同,则可以随机选择,或考虑引入距离的权重来打破平局。

回归问题:

  • 对于回归任务,KNN 会取 K 个邻近样本标签的平均值或加权平均值作为预测结果。加权时,权重 w i w_i wi 通常与样本 x i \mathbf{x}_i xi 和待分类样本 x \mathbf{x} x 之间的距离的倒数成正比:

w i = 1 d ( x i , x ) w_i = \frac{1}{d(\mathbf{x}_i, \mathbf{x})} wi=d(xi,x)1

2.4 K值选择

K 值是 KNN 算法中的重要参数,决定了选择多少个邻近样本参与投票。K 值的选择通常通过交叉验证来确定。一般来说:

  • 较小的 K 值:模型对训练数据的拟合度较高,但可能会受到噪声影响,导致过拟合。
  • 较大的 K 值:模型变得平滑,减少了过拟合的风险,但也可能导致欠拟合。

2.5 KD树(K-Dimensional Tree)

为了加速 KNN 的搜索过程,可以使用 KD 树进行优化。KD 树是一种对 k 维空间数据进行分割的树形数据结构,通过这种数据结构可以有效地减少搜索空间,从而提高查找效率。

KD树的构建过程:

  1. 选择分割维度:选择一个维度将数据按照该维度的中位数分割成两部分。选择的维度通常是通过计算当前节点数据在各维度的方差,选择方差最大的维度进行划分。
  2. 分割数据:在选定的分割维度上,以中位数为分割点,将数据集划分为两部分,分别作为左右子节点的数据。
  3. 递归构建:对每个子节点递归进行上述步骤,直到每个子节点的样本数达到预定阈值或所有样本在某一维度上的值都相同。
  4. 节点表示:每个节点存储一个样本点及其对应的分割维度。

KD树的搜索过程:

  1. 递归搜索叶节点:从根节点开始,比较目标点与当前节点在分割维度上的值,决定进入左子树还是右子树,直到到达叶节点。
  2. 回溯搜索:到达叶节点后,计算当前叶节点样本与目标点之间的距离,并更新当前最近邻居。如果当前节点的父节点到目标点的距离小于当前最近邻居的距离,则有可能在兄弟子树中找到更近的邻居,需要回溯检查。
  3. 剪枝操作:如果兄弟子树的区域与目标点之间的最小距离大于当前已知最近邻居的距离,则可以剪枝,即不需要搜索该子树。
  4. 返回最近邻居:最终返回 K 个最近邻居。

优缺点:

  • 优点:KD 树在低维空间中能显著减少 KNN 搜索的计算量,提高查询效率。对于静态数据集,KD 树是一种非常有效的加速工具。
  • 缺点:在高维空间中,KD 树的性能会下降,尤其是当维度数接近样本数时,KD 树的效率可能退化为线性搜索。此外,KD 树不适用于动态数据集,因为在插入或删除样本后需要重建树结构。

KNN 的时间复杂度较高,特别是在大规模数据集上,因为需要计算待分类样本与训练集中所有样本之间的距离。对于 N 个训练样本,每次分类的时间复杂度为 O ( N × D ) O(N \times D) O(N×D),其中 D 为特征维度。这使得 KNN 在大规模数据集或高维空间中不太适用。

2.6 代码实现

以下是KNN算法的简单实现:

import numpy as np
from collections import Counterdef knn_predict(X_train, y_train, X_test, k=3):predictions = []for x_test in X_test:# 计算测试样本与所有训练样本之间的距离distances = np.linalg.norm(X_train - x_test, axis=1)# 获取距离最近的 k 个样本的索引k_indices = np.argsort(distances)[:k]# 获取这些样本的标签k_nearest_labels = y_train[k_indices]# 投票选择出现频率最高的标签most_common = Counter(k_nearest_labels).most_common(1)predictions.append(most_common[0][0])return predictions

如果需要在大规模数据集上提高效率,可以使用 KD树 优化的版本。以下是构建 KD 树的伪代码:

class KDNode:def __init__(self, point, left=None, right=None):self.point = pointself.left = leftself.right = rightdef build_kdtree(points, depth=0):if not points:return Nonek = len(points[0])  # 维度axis = depth % k  # 选择分割维度points.sort(key=lambda x: x[axis])median = len(points) // 2  # 选择中位数# 递归构建 KD 树return KDNode(point=points[median],left=build_kdtree(points[:median], depth + 1),right=build_kdtree(points[median + 1:], depth + 1))

KNN算法是一种简单直观且有效的分类和回归方法,但其计算复杂度较高,特别是在高维空间和大规模数据集上。通过引入 KD树,可以在低维空间中显著提高KNN的效率。然而,在高维空间中,KD树的效果会减弱。因此,在实际应用中,需要根据数据集的具体特征选择合适的优化技术。

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

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

相关文章

海外合规|新加坡网络安全认证计划简介(三)-Cyber Trust

一、 认证简介: Cyber Trust标志是针对数字化业务运营更为广泛的组织的网络安全认证。该标志针对的是规模较大或数字化程度较高的组织,因为这些组织可能具有更高的风险水平,需要他们投资专业知识和资源来管理和保护其 IT 基础设施和系统。Cy…

开源 AI 智能名片 O2O 商城小程序:引入淘汰机制,激发社交电商新活力

摘要:本文深入探讨在社交电商领域中,开源 AI 智能名片 O2O 商城小程序如何通过设置淘汰机制,实现“良币驱逐劣币”,激励士气,为社交电商企业注入新的活力。通过分析缺乏淘汰机制的弊端以及设置淘汰机制的优势&#xff…

用python发送邮件

用python发送邮件需要smtplib,email包,例子如下: import smtplib from email.mime.text import MIMEText from email.mime.multipart import MIMEMultipartdef send_email():# 邮件的基本信息sender_email "xx.com" # 发送方邮箱receiver_e…

CAAC无人机飞行执照理论培训课程详解

CAAC(中国民用航空局)无人机飞行执照的理论培训课程是确保无人机飞手全面掌握飞行和应用技能的重要环节。以下是对该理论培训课程的详细解析: 一、课程目标 理论培训课程的主要目标是使学员: 了解并掌握无人机相关的法律法规、…

Java基于微信小程序的家庭财务管理系统,附源码

博主介绍:✌Java徐师兄、7年大厂程序员经历。全网粉丝13w、csdn博客专家、掘金/华为云等平台优质作者、专注于Java技术领域和毕业项目实战✌ 🍅文末获取源码联系🍅 👇🏻 精彩专栏推荐订阅👇🏻 不…

EmguCV学习笔记 VB.Net 8.4 pyrMeanShiftFiltering

版权声明:本文为博主原创文章,转载请在显著位置标明本文出处以及作者网名,未经作者允许不得用于商业目的。 EmguCV是一个基于OpenCV的开源免费的跨平台计算机视觉库,它向C#和VB.NET开发者提供了OpenCV库的大部分功能。 教程VB.net版本请访问…

Spark2.x 入门:逻辑回归分类器

方法简介 逻辑斯蒂回归(logistic regression)是统计学习中的经典分类方法,属于对数线性模型。logistic回归的因变量可以是二分类的,也可以是多分类的。 示例代码 我们以iris数据集(iris)为例进行分析。i…

Java项目:137 springboot基于springboot的智能家居系统

作者主页:源码空间codegym 简介:Java领域优质创作者、Java项目、学习资料、技术互助 文中获取源码 项目介绍 本基于Springboot的智能家居系统提供管理员、用户两种角色的服务。 总的功能个人中心、基础数据管理、家具管理、任务管理和用户管理。本系统…

显微镜基础知识--脑机起步

一、显微镜类别 学生级、实验级、研究级生物显微镜单目型、双目型、三目型生物显微镜 二、显微镜基础原理 (1)光学显微镜 光学显微镜主要由目镜、物镜、载物台和反光镜(集光镜)组成。目镜和物镜都是凸透镜,焦距不同。物镜的凸透镜焦距小于…

Web攻防之应急响应(二)

目录 前提 🍔学习Java内存马前置知识 内存马 内存马的介绍 内存马的类型众多 内存马的存在形式 Java web的基础知识: Java内存马的排查思路: 🍔开始查杀之前的需要准备 1.登录主机启动服务器 2.生成jsp马并连接成功 …

MATLAB 仿真跳频扩频通信系统

1. 简介 跳频扩频(FHSS)是一种通过在不同的频率之间快速切换来对抗窄带干扰的技术。在这篇博客中,我们将使用 MATLAB 进行 FHSS 通信系统的仿真,模拟跳频过程、调制、解调以及信号在不同步骤中的变化。通过对仿真结果进行可视化&…

python-简单的dos攻击

前言 这个是DOS攻击学习(注意:千万别去攻击有商业价值的服务器或应用,不然会死的很惨(只有一个IP通过公网访问容易被抓),前提是网站没有攻击防御) 创建一个以python编写的后端web服务(好观察) 安装flask pip install flask from flask import Flaskapp …

打卡第60天------图论

加油!尽管前面的道路很困难,但是依然要坚持下去✊。 在算法训练营我学到了很多东西,对于算法的方法来说真的是涨知识了,对于我一个非科班出身,半路转行的干IT的人来说真的给予了我很大的帮助。我会继续回头看代码随想录…

前端入门了解

1. 网页 1.1 网页概述 1.2 超文本标记语言 1.3 网页的形成 2. 浏览器了解 网页需要通过浏览器来展示,下面是关于浏览器的两点; 国际上通用的浏览器有如下六个(百度,360,uc等是主要在国内使用), 3. We…

Apple 重發iOS 17.6.1 修正版

蘋果又再次替 iPhone 和 iPad 用戶釋出 iOS 17.6.1更新(21G101),這次更新與8日所推出的 iOS 17.6.1 正式版相同,官方在更新說明內也沒有提到任何修改,依舊是維持修正進階資料保護的問題 iOS 17.6.1 更新修正版內容重點…

面向切面编程

1. 增删改查 三层干啥 2. 文件上传 第三方api(接口) 调用准备 -- 官方代码 -- 工具类 3. 登录鉴权 登录(查询 密码) 鉴权(拦截器)登录完成后--后台生成token返回给浏览器--每次浏览器发请求时候携带token--服务器需要使用拦截器拦截请求,获取token--校验token生成 token校…

借老系统重构机会我写了个groovy规则引擎

公司老系统的重构计划早就有了,为了对Java硬编码的各种校验规则进行重构,特地参考了相关技术,最终选择了groovy进行了系统的学习,并编写了一个即插即用的轻量级规则引擎。 文章目录 项目背景技术选型groovy的性能groovy脚本执行线…

【拉取Git项目到本地,知识小记,后续再改】

前提:Git已经安装好 https://blog.csdn.net/mukes/article/details/115693833 安装至步骤2.2.4即可 第一步创建本地项目目录 第二步获取他人提供的项目git地址或者自己在网上找的他人项目的git地址 Git 全局设置: git init git config --global user.name “ASxx”…

1998-2023年上市公司金融/信贷/资本资源错配程度数据(含原始数据+计算代码+结果)

1998-2023年上市公司金融/信贷/资本资源错配程度数据(含原始数据计算代码结果) 1、时间:1998-2023年 2、来源:上市公司年报 3、指标:证券代码、year、应付账款、负债合计、利息支出、行业代码、是否ST或PT、上市日期…

Webpack详解与配置环境

webpack:webpack网址 1、工作原理: Webpack是一个非常强大的静态模块的打包工具。从文件入口开始,递归解析以来关系,然后将所有模块打包成一个或多个budle文件。 2、webpack核心概念: Entry:入口起点(en…