机器学习——K最近邻算法(KNN)

news2024/12/23 17:55:36

机器学习——K最近邻算法(KNN)

文章目录

  • 前言
  • 一、原理
  • 二、距离度量方法
    • 2.1. 欧氏距离
    • 2.2. 曼哈顿距离
    • 2.3. 闵可夫斯基距离
    • 2.4. 余弦相似度
    • 2.5. 切比雪夫距离
    • 2.6. 马哈拉诺比斯距离
    • 2.7. 汉明距离
  • 三、在MD编辑器中输入数学公式(额外)
  • 四、代码实现
    • 2.1. 用KNN算法进行分类
    • 2.2. 用KNN算法进行回归
  • 五、模型的保存和加载
  • 总结


前言

在传统机器学习中,KNN算法是一种基于实例的学习算法,能解决分类和回归问题,而本文将介绍一下KNN即K最近邻算法。


在这里插入图片描述

一、原理

K最近邻(KNN)算法是一种基于实例的学习算法,用于分类和回归问题。它的原理是根据样本之间的距离来进行预测
核心思想是通过找到与待分类样本最相似的K个训练样本,来确定待分类样本的类别或者预测其数值。

假设存在一个样本数据集(训练集),并且样本集中每个数据都存在标签(即知道样本集中数据的分类情况)
KNN算法的步骤如下:

  1. 计算距离:对于给定的未知样本(没有标签值的测试集),计算它与训练集中每个样本的距离。常用的距离度量方法有欧氏距离、曼哈顿距离等。

  2. 选择K值:选择一个合适的K值,即要考虑的最近邻的数量。

  3. 选择最近邻:从训练集中选择K个距离最近的样本。

  4. 进行投票或计算平均值:对于分类问题,根据最近邻的标签进行投票,选取票数最多的标签作为预测结果。对于回归问题,根据最近邻的值计算平均值作为预测结果。

按我的理解其实就是将待分类的样本与训练集中的每个样本去计算距离,然后从训练集中选择K个与待分类样本最靠近的几个样本,然后再根据选取得最靠近的几个样本得标签值进行投票来分类。
对于回归问题,则统计K个最近邻样本的数值,然后通过平均或加权平均的方式计算出待分类样本的数值。

如图所示(可看出K值的选择对结果有很大的影响):
在这里插入图片描述

当K=3时,根据距离计算,待分类的样本点被划为黄色那一类;(因为2>1)
当K=5时, 根据距离计算,待分类的样本点被划为红色那一类;(因为3>2)

二、距离度量方法

参考文献
https://zhuanlan.zhihu.com/p/354289511

以下是一些常见的距离度量方法:

2.1. 欧氏距离

欧氏距离(Euclidean Distance):欧氏距离是最常见的距离度量方法,它是两个向量之间的直线距离。对于两个n维向量x和y,欧氏距离的计算公式为:

d ( x , y ) = ∑ i = 1 n ( x i − y i ) 2 d(x,y) = \sqrt{\sum_{i=1}^{n}(x_{i}-y_{i})^{2}} d(x,y)=i=1n(xiyi)2

其中,xi和yi分别表示向量x和y的第i个元素。
例如当n = 2 时,这就是中学学的二维平面中两点之间距离公式的计算了。

2.2. 曼哈顿距离

曼哈顿距离(Manhattan Distance):曼哈顿距离是两个向量之间的城市街区距离,也称为L1距离。对于两个n维向量x和y,曼哈顿距离的计算公式为:
d ( x , y ) = ∑ i = 1 n ∣ x i − y i ∣ d(x,y) = \sum_{i=1}^{n} |x_{i} -y_{i}| d(x,y)=i=1nxiyi

2.3. 闵可夫斯基距离

闵可夫斯基距离(Minkowski Distance):闵可夫斯基距离是欧氏距离和曼哈顿距离的一般化形式,它可以根据参数p的不同取值变化为不同的距离度量方法。对于两个n维向量x和y,闵可夫斯基距离的计算公式为:
d ( x , y ) = ∑ i = 1 n ∣ x i − y i ∣ p p d(x,y) = \sqrt[p]{\sum_{i=1}^{n}|x_{i}-y_{i}|^{p}} d(x,y)=pi=1nxiyip

其中,xi和yi分别表示向量x和y的第i个元素,p为参数,当p=2时,闵可夫斯基距离等价于欧氏距离;当p=1时,闵可夫斯基距离等价于曼哈顿距离。

2.4. 余弦相似度

余弦相似度(Cosine Similarity):余弦相似度是衡量两个向量方向相似程度的度量方法,它计算两个向量之间的夹角余弦值。对于两个n维向量x和y,余弦相似度的计算公式为:

c o s ( θ ) = ∑ i = 1 n ( x i ∗ y i ) ∑ i = 1 n ( x i ) 2 ∗ ∑ i = 1 n ( y i ) 2 cos(\theta ) = \frac{\sum_{i=1}^{n}(x_{i} * y_{i})}{\sqrt{\sum_{i=1}^{n}(x_{i})^{2}}*\sqrt{\sum_{i=1}^{n}(y_{i})^{2}}} cos(θ)=i=1n(xi)2 i=1n(yi)2 i=1n(xiyi)

2.5. 切比雪夫距离

切比雪夫距离(Chebyshev Distance):切比雪夫距离是两个向量之间的最大绝对差距。对于两个n维向量x和y,切比雪夫距离的计算公式为:
d ( x , y ) = m a x i ( ∣ p i − q i ∣ ) d(x,y) = \underset{i}{max}(|p_{i} -q_{i}|) d(x,y)=imax(piqi)

2.6. 马哈拉诺比斯距离

马哈拉诺比斯距离(Mahalanobis Distance):马哈拉诺比斯距离是一种考虑特征之间相关性的距离度量方法。它首先通过计算协方差矩阵来衡量特征之间的相关性,然后计算两个向量在经过协方差矩阵变换后的空间中的欧氏距离。对于两个n维向量x和y,马哈拉诺比斯距离的计算公式为:

d = ( x ⃗ − y ⃗ ) T S − 1 ( x ⃗ − y ⃗ ) d = \sqrt{(\vec{x}-\vec{y})^{T}S^{-1}(\vec{x}-\vec{y})} d=(x y )TS1(x y )

其中,x和y分别表示向量x和y,S为x和y的协方差矩阵。

2.7. 汉明距离

汉明距离(Hamming Distance):汉明距离是用于比较两个等长字符串之间的差异的度量方法。对于两个等长字符串x和y,汉明距离的计算公式为:
d = 1 N ∑ i = 1 n 1 x i ≠ y i d = \frac{1}{N}\sum_{i=1}^{n}1_{x_{i}\neq y_{i}} d=N1i=1n1xi=yi

三、在MD编辑器中输入数学公式(额外)

在使用markdown文本编辑器时,对于数学公式的书写一般是使用到LaTeX这个排版系统,基于latex语法构建数学公式。

这对我这种刚开始接触的初学者是不友好的(在这之前还要学习LateX语法…)。
$$

$$
在这之间填入数学公式对应的LaTeX语法,就能获得对应的数学公式

对应的LaTeX语法可以从另一个编辑器——富文本编辑器 中获得:

在这里插入图片描述
将LaTeX公式复制过来,d(x,y) = \sqrt{\sum_{i=1}{n}(x_{i}-y_{i}){2}}
$$

$$
放于这两个之间,可以得到对应公式:

d ( x , y ) = ∑ i = 1 n ( x i − y i ) 2 d(x,y) = \sqrt{\sum_{i=1}^{n}(x_{i}-y_{i})^{2}} d(x,y)=i=1n(xiyi)2

嗯…,其实我也不太清楚为何我的Mardown编辑器中没有像富文本编辑器中那样的公式编辑器,(或许是要下载插件吗?),不用管这么多,能用就行。

四、代码实现

2.1. 用KNN算法进行分类

from sklearn.neighbors import KNeighborsClassifier
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score

# 加载数据集
iris = load_iris()
X = iris.data
y = iris.target

# 划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.4, random_state=42)

# 创建KNN分类器
knn = KNeighborsClassifier(n_neighbors=3)
#metric= "minkowski",距离度量默认是闵可夫斯基距离


# 拟合模型
knn.fit(X_train, y_train)

# 预测
y_pred = knn.predict(X_test)

# 计算准确率
accuracy = accuracy_score(y_test, y_pred)
print("Accuracy:", accuracy)
Accuracy: 0.9833333333333333

2.2. 用KNN算法进行回归

from sklearn.neighbors import KNeighborsRegressor
from sklearn.datasets import load_boston
from sklearn.model_selection import train_test_split
from sklearn.metrics import mean_squared_error

# 加载数据集
boston = load_boston()
X = boston.data
y = boston.target

# 划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
# 创建KNN回归器
knn = KNeighborsRegressor(n_neighbors=3)
# 拟合模型
knn.fit(X_train, y_train)
# 预测
y_pred = knn.predict(X_test)

# 计算均方误差
mse = mean_squared_error(y_test, y_pred)
print("MSE:", mse)
MSE: 21.65955337690632

#计算R方值
print(knn.score(X_test,y_test))
0.7046442656646525

#绘图展示
import matplotlib.pyplot as plt
plt.style.use("ggplot")
plt.scatter(y_test,y_pred)
plt.plot([min(y_test),max(y_test)],[min(y_pred),max(y_pred)],"k--",color = "green", lw = 2,)
plt.xlabel("y_test")
plt.ylabel("y_pred")
plt.show()


在这里插入图片描述

均方误差:

M S E = ∑ i = 1 n ( y t − y p ) 2 n MSE = \frac{\sum_{i=1}^{n}(y_t - y_p)^{2}}{n} MSE=ni=1n(ytyp)2

再用线性回归试一下:

from sklearn.linear_model import LinearRegression
model = LinearRegression()
model.fit(X_train, y_train)
coefficients = model.coef_
intercept = model.intercept_

# 构建回归公式
equation = f"y = {intercept} + {coefficients[0]}*x1 + {coefficients[1]}*x2 + ..."

# 计算R^2值
r2_score = model.score(X_test, y_test)
print("R^2值:", r2_score)
R^2值: 0.6687594935356289

这些模型都是十分简单的模型,还未经过参数的调优和算法的优化。

五、模型的保存和加载

#模型的保存和加载
import pickle
with open("model.pkl","wb") as f:
    pickle.dump(knn,f)
with open("model.pkl","rb") as f:
    knn_loaded = pickle.load(f)

print(knn_loaded.score(X_test,y_test))
0.7046442656646525

总结

本文从KNN算法的原理:(根据样本之间的距离来预测)出发,介绍了一些常见的距离度量方法,另外也介绍了一下在Markdown编辑器中输入数学公式,最后就是KNN算法在python中的分类和回归代码的实现。最后的最后就是模型的保存和加载。

道可道,非常道;名可名,非常名。

–2023-9-10 筑基篇

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

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

相关文章

C++数据结构X篇_11_C++栈的应用-后缀表达式求解

上篇C栈的应用-中缀转后缀中我们介绍了我们所熟知的中缀表达式转为后缀表达式,那么如何通过后缀表达式获得原表达式的值呢?本篇将会参考博文栈的应用-后缀表达式求解介绍计算机是如何基于后缀表达式计算的? 文章目录 1. 后缀表达式求解计算规…

【MySQL】一文带你理解索引事务及其原理

MySQL- 索引事务 文章目录 MySQL- 索引事务索引操作索引原理 事务操作并发执行 索引 索引是一种特殊的文件,包含着对数据表里所有记录的引用指针。可以对表中的一列或多列创建索引,并指定索引的类型,各类索引有各自的数据结构实现。 通俗来…

C++项目实战——基于多设计模式下的同步异步日志系统-④-日志系统框架设计

文章目录 专栏导读模块划分日志等级模块日志消息模块日志消息格式化模块日志消息落地模块日志器模块日志器管理模块异步线程模块 模块关系图 专栏导读 🌸作者简介:花想云 ,在读本科生一枚,C/C领域新星创作者,新星计划导…

新知同享 | Web 开发性能提升,优化体验

更加强大且开放的 Web 可以简化开发工作并支持 AI 一起来看 2023 Google 开发者大会上 Web 开发值得重点关注的升级与成果 了解 Web 如何实现加速开发,更加便捷 精彩大会现场一览 Web 开发不断发展,每年都带来性能提升和功能迭代,开启丰富多…

【多线程】volatile 关键字

volatile 关键字 1. 保证内存可见性2. 禁止指令重排序3. 不保证原子性 1. 保证内存可见性 内存可见性问题: 一个线程针对一个变量进行读取操作,另一个线程针对这个变量进行修改操作, 此时读到的值,不一定是修改后的值,即这个读线…

用python实现基本数据结构【01/4】

说明 如果需要用到这些知识却没有掌握,则会让人感到沮丧,也可能导致面试被拒。无论是花几天时间“突击”,还是利用零碎的时间持续学习,在数据结构上下点功夫都是值得的。那么Python 中有哪些数据结构呢?列表、字典、集…

Linux 下spi设备驱动

参考: Linux kernel 有关 spi 设备树参数解析 Linux kernel 有关 spi 设备树参数解析 - 走看看 Linux SPI驱动框架(1)——核心层 Linux SPI驱动框架(1)——核心层_linux spi驱动模型_绍兴小贵宁的博客-CSDN博客 Linux SPI驱动框架(2)——控制器驱动层 Linux SPI驱…

如何进行SEO优化数据分析?(掌握正确的数据分析方法,让您的网站更上一层楼!)

在互联网时代,SEO优化已经成为了每一个网站运营者必备的技能。而在SEO优化中,数据分析更是至关重要的一环。在本文中,我们将会详细介绍如何正确的进行SEO优化数据分析,让您的网站更上一层楼! 数据分析的重要性 数据分…

ROS2-IRON Ubuntu-22.0 源码下载失败解决方法 vcs import --input

ROS2 一.ROS2 IRON环境搭建1.设置系统字符集为UTF-82.将RO2 apt 库添加到系统中3.添加ROS2 GPG key4.添加ROS 2 的软件源安装开发工具 二.下载ROS2sh源代码编译 一.ROS2 IRON环境搭建 虚拟机系统:Ubuntu22.04 虚拟机:VMware-player-full-16.2.5-2090451…

YOLOv5算法改进(15)— 更换Neck之AFPN

前言:Hello大家好,我是小哥谈。在YOLOv5中添加AFPN(Adaptive Feature Pyramid Network)可以提高目标检测的准确性。AFPN是一种用于目标检测任务的功能增强模块,它能够自适应地融合来自不同层级的特征图,以提…

scss文件自动导入

正常使用scss文件,需要先导入再使用内部变量,自动导入可以免除手动导入的步骤,直接使用内部的变量。 步骤:装包 -> scss文件 -> 配置 1. 装包 npm i sass -D // -D 仅在开发环境中依赖 2. 新增一个 scss文件&#xff…

设计模式之单列模式

单列模式是一种经典的设计模式,在校招中最乐意考的设计模式之一~ 设计模式就是软件开发中的棋谱,大佬们针对一些常见的场景,总结出来的代码的编写套路,按照套路来写,不说你写的多好,至少不会太差~ 在校招中…

Java的环境配置

目录 window系统安装java下载JDK配置环境变量JAVA_HOME 设置PATH设置CLASSPATH 设置测试JDK是否安装成功 Linux,UNIX,Solaris,FreeBSD环境变量设置流行JAVA开发工具使用 Eclipse 运行第一个 Java 程序 window系统安装java 下载JDK 首先我们…

OLED透明屏触控:引领未来科技革命的创新力量

OLED透明屏触控技术作为一项颠覆性的创新,正在引领新一轮科技革命。它将OLED显示技术与触摸技术相结合,实现了透明度和触控功能的完美融合。 在这篇文章中,尼伽将通过引用最新的市场数据、报告和行业动态,详细介绍OLED透明屏触控…

Java知识总结(持续更新)

一、JDK、JRE、JVM三者之间的关系? 1. **JDK (Java Development Kit)**: JDK 是 Java 开发工具包,它包含了用于开发 Java 应用程序的所有必要工具和库。这包括 Java 编译器(javac)、Java 核心类库、开发工具&#x…

【Day-33慢就是快】代码随想录-二叉树-二叉搜索树中的搜索

给定二叉搜索树(BST)的根节点和一个值。 你需要在BST中找到节点值等于给定值的节点。 返回以该节点为根的子树。 如果节点不存在,则返回 NULL。 思路 什么是二叉搜索树: 二叉搜索树是一个有序树: 若它的左子树不空&a…

【NVIDIA CUDA】2023 CUDA夏令营编程模型(三)

博主未授权任何人或组织机构转载博主任何原创文章,感谢各位对原创的支持! 博主链接 本人就职于国际知名终端厂商,负责modem芯片研发。 在5G早期负责终端数据业务层、核心网相关的开发工作,目前牵头6G算力网络技术标准研究。 博客…

yolov7增加mobileone

代码地址:GitHub - apple/ml-mobileone: This repository contains the official implementation of the research paper, "An Improved One millisecond Mobile Backbone". 论文地址:https://arxiv.org/abs/2206.04040 MobileOne出自Apple&am…

IP403参考资料和引脚图

特性 支持串并联双LED驱动和GPIO控制器 串并联LED驱动器 支持一个串行输入56个并行led或三串行输入16个并行ed为每个串行输入。 支持4-16mA可调电流源驱动,无限流电阻 支持LED熄灭模式,实现省电功能 提供级联能力,提供更多的LED驱动输出…

go语言基础---8

Http请求报文格式分析 package mainimport ("fmt""net" )func main() {//监听listener, err : net.Listen("tcp", ":8000")if err ! nil {fmt.Println("listener err", err)return}defer listener.Close()//阻塞等待用户的…