机器学习:k近邻算法(KNN)介绍

2023-11-19

k近邻算法是一种最简单最经典的机器学习算法之一。该算法的原理为:当对测试样本进行分类时,首先通过扫描训练样本集,找到与该测试样本最相似的k个训练样本,根据这个样本的类别进行投票确定测试样本的类别。也可以通过个样本与测试样本的相似程度进行加权投票。如果需要以测试样本对应每类的概率的形式输出,可以通过个样本中不同类别的样本数量分布来进行估计。

以下通过一个例子了解k近邻算法。

 利用k近邻算法确认紫圆为哪个类别。若k=1,则找到离图中紫圆最近的1个样本,这个样本为红色正方形,故紫圆属于红色正方形类别;若k=7,则找到离紫圆最近的7个样本,这7个样本中有5个绿色三角形和两个红色正方形,其中类数三角形数量比红色正方形多,故紫圆属于绿色三角形。由以上例子可知k近邻算法对样本的分类及其依赖于k的取值。

 当然k近邻算法对距离的计算方式有多种,其中以Manhattan 距离与Euclidean 距离为主。

我们一般采用Euclidean 距离。

 

在上述介绍中我们得知k近邻算法对样本的分类及其依赖于k的取值。k值不可取过大或过小。

  • k值越大,模型的偏差越大,对噪声数据越不敏感,当k值很大时,可能造成欠拟合;
  • k值越小,模型的方差就会越大,当k值太小,就会造成过拟合。 

以下为k值取值过大或过小时的例子。

 如图当k=1时在图中紫色图层中夹杂了参差不齐的绿色图层,该训练结果并非很好的划分了红绿紫三个区域,造成了过拟合现象。

如图当k=150时由于无论取图上哪个点都是紫色点投票最多,故该点必被分类为紫色一类,造成了欠拟合现象。

因此k的取值因满足以下两个条件:

1.近邻点要有相同/相近的类别

2.特征维度的尺度(范围)要具备一致性

接下来看一例子:

 如上图,若我们用传统的Euclidean 距离作为k近邻算法判断距离的标准,我们会惊讶的发现每年获得的飞行常客里程数将占到距离的绝大部分比重,也就是说样本的分类基本上只与每年获得的飞行常客里程数相关联了。所以我们要进行数值归一化的处理,使得上图中三个特征的权重相等。

数据归一化的处理方法有很多种,比如0-1标准化、Z-score标准化、Sigmoid压缩法等等,在这里我们使用最简单的0-1标准化,公式如下: 

 

 接下来调用鸢尾花Iris数据集,利用k近邻算法训练该数据集并评估模型准确率。

1.鸢尾花Iris数据集介绍

· Iris (/ˈaɪrɪs/) 数据集是机器学习任务中常用的分类实验数据集,由Fisher在1936年整理。

· Iris :Anderson’s Iris data set, 中文名称:安德森鸢尾花数据集

· Iris 数据集一共包含150个样本,分3类,每类50个数据,每个数据包含4个特征。4个特征分别为: Sepal.Length(花萼长度)、Sepal.Width(花萼宽度)、Petal.Length(花瓣长度)、Petal.Width(花瓣宽度),特征值都为正浮点数,单位为厘米。根据4个特征预测鸢尾花属于 Iris Setosa(山鸢尾)、Iris Versicolour(杂色鸢尾),Iris Virginica(维吉尼亚鸢尾)
数据集结构与数据大致如下:

from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.neighbors import KNeighborsClassifier
import numpy as np

iris = load_iris()
print(iris)

 

 其中前部分为特征: Sepal.Length(花萼长度)、Sepal.Width(花萼宽度)、Petal.Length(花瓣长度)、Petal.Width(花瓣宽度)后部分为标签:Iris Setosa(山鸢尾)、Iris Versicolour(杂色鸢尾),Iris Virginica(维吉尼亚鸢尾)(分别利用0,1,2代替原有标签名)。

2.sklearn中 neighbors.KNeighborsClassifier参数说明

sklearn库中,KNeighborsClassifier是实现K近邻算法的一个类,一般都使用欧式距离进行测量。

KNeighborsClassifier(n_neighbors=5,weights=’uniform’,algorithm=’auto’,leaf_size=30,p=2,metric=’minkowski’,metric_params=None,n_jobs=1,**kwargs)

n_neighbors: int, 可选参数(默认为 5)用于kneighbors查询的默认邻居的数量;

weights(权重): str or callable(自定义类型), 可选参数(默认为 ‘uniform’)用于预测的权重函数;

algorithm(算法): {‘auto’, ‘ball_tree’, ‘kd_tree’, ‘brute’}, 可选参数(默认为 ‘auto’)计算最近邻居用的算法;

leaf_size(叶子数量): int, 可选参数(默认为 30),传入BallTree或者KDTree算法的叶子数量;

p: integer, 可选参数(默认为 2)用于Minkowski metric(闵可夫斯基空间)的超参数。p = 1, 相当于使用曼哈顿距离 (l1),p = 2, 相当于使用欧几里得距离(l2);

metric(矩阵): string or callable, 默认为 ‘minkowski’用于树的距离矩阵。默认为闵可夫斯基空间,如果和p=2一块使用相当于使用标准欧几里得矩阵;

metric_params(矩阵参数): dict, 可选参数(默认为 None),给矩阵方法使用的其他的关键词参数;

n_jobs: int, 可选参数(默认为 1)用于搜索邻居的,可并行运行的任务数量。如果为-1, 任务数量设置为CPU核的数量。不会影响fit方法.

  • 方法:

 

3. 编写代码,实现对iris数据集的k近邻算法分类及预测

一:引入库

from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.neighbors import KNeighborsClassifier
import numpy as np

二:加载数据集,定义区分特征与标记

iris = load_iris()
#date为特征数据集
data = iris.get("data")
#target为标记数据集
target = iris.get("target")

三:划分测试集与训练集

#划分测试集占20%
x_train, x_test, y_train, y_test = train_test_split(data, target, test_size=0.2, random_state=0)

四:定义k值

#定义k值
KNN = KNeighborsClassifier(n_neighbors=5)

五:评价模型的准确率

test_score = KNN.score(x_test, y_test)
print("模型的准确率:", test_score)


六:使用模型预测未知种类样本

#定义三个测试数据
X1 = np.array([[1.9, 2.8, 4.7, 1.1], [5.8, 2.7, 4.1, 1.5], [3.6, 2.5, 3.1, 2.1]])
prediction = KNN.predict(X1)
#根据预测值找出对应花名
a = iris.get("target_names")[prediction]
print("第一朵花的种类为:", a[0])
print("第二朵花的种类为:", a[1])
print("第三朵花的种类为:", a[2])

 完整代码

from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.neighbors import KNeighborsClassifier
import numpy as np
if __name__ == '__main__':
    iris = load_iris()
    #date为特征数据集
    data = iris.get("data")
    #target为标记数据集
    target = iris.get("target")
    #划分测试集占20%
    x_train, x_test, y_train, y_test = train_test_split(data, target, test_size=0.2, random_state=0)
    #定义k值
    KNN = KNeighborsClassifier(n_neighbors=5)
    KNN.fit(x_train, y_train)
    train_score = KNN.score(x_train, y_train)
    test_score = KNN.score(x_test, y_test)
    print("模型的准确率:", test_score)
    #定义三个测试数据
    X1 = np.array([[1.9, 2.8, 4.7, 1.1], [5.8, 2.7, 4.1, 1.5], [3.6, 2.5, 3.1, 2.1]])
    prediction = KNN.predict(X1)
    #根据预测值找出对应花名
    a = iris.get("target_names")[prediction]
    print("第一朵花的种类为:", a[0])
    print("第二朵花的种类为:", a[1])
    print("第三朵花的种类为:", a[2])

结果

 接下来改变k值观察模型准确率。

当k=100时:

当 k=50时:

当k=120时:

 

可以看出当k值越来越高至接近样本总数150时它的准确率越来越低,这吻合了上文介绍的k值过大造成的欠拟合现象。 

 k近邻算法优缺点

优点:

1. 简单有效

2.重新训练的代价低(没有构建模型)

3.适合类域交叉样本:KNN方法主要靠周围有限的邻近的样本,而不是靠判别类域的方法来确定所属类别的,因此对于类域的交叉或重叠较多的待分样本集来说,KNN方法较其他方法更为适合。
4.适合大样本自动分类:该算法比较适用于样本容量比较大的类域的自动分类,而那些样本容量较小的类域采用这种算法比较容易产生误分。
 

缺点:

1.惰性学习:KNN算法是懒散学习方法(lazy learning,基本上不学习),一些积极学习的算法要快很多
2.类别评分不是规格化:不像一些通过概率评分的分类
3.输出可解释性不强:例如决策树的输出可解释性就较强
4.对不均衡的样本不擅长:当样本不平衡时,如一个类的样本容量很大,而其他类样本容量很小时,有可能导致当输入一个新样本时,该样本的K个邻居中大容量类的样本占多数。该算法只计算“最近的”邻居样本,某一类的样本数量很大,那么或者这类样本并不接近目标样本,或者这类样本很靠近目标样本。无论怎样,数量并不能影响运行结果。可以采用权值的方法(和该样本距离小的邻居权值大)来改进。
5.计算量较大:目前常用的解决方法是事先对已知样本点进行剪辑,事先去除对分类作用不大的样本。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

机器学习:k近邻算法(KNN)介绍 的相关文章

随机推荐

  • find命令详解

    前言 find命令是我们日常工作中比较常用的Linux命令 全面的掌握这个命令可以使很多操作达到事半功倍的效果 如果对find命令有以下这些疑惑 本文都能帮你解决 find命令的格式是什么 参数中出现 或 号是什么意思 比如find mti
  • JAVA-WEB项目中,前后台结合AES和RSA对数据加密处理

    实际项目中为了系统安全 我们经常需要对请求数据和响应数据做加密处理 这里以spring后台 vue前台的java web为例 记录一个实现过程 一 为什么要结合AES和RSA 因为AES是对称加密 即加密解密用的秘钥是一样 这样一来AES的
  • SQLyog连接mysql

    mysql 64位客户端下载地址 https pan baidu com s 1bYd1YQ 启动mysql安装 cmd 用户名mysql80 密码 123456 安装SQLyog 官网地址 或者装客户端 名称随意 注册码 ccbfc13e
  • C# ASP.NET 如何判断DropdownList是否为空

    程序运行时 鼠标下拉 DropdownList控件 发现下拉列表为空 参见下图 如何判断 DropdownList控件为空呢 参见下述代码 if DropDownList1 Items Count 0 Response Write retu
  • 【win】引用的账户当前已经锁定,且可能无法登陆

    错误信息 错误原因 原保留的登录账号已失效 解决方法 1 打开控制面板 gt 选择 用户账户 2 选择 管理你的凭据 3 选择 windows凭据 展开10 10 0 2登入项 选择 删除 或 编辑 即编辑为现在可用的账户和密码 5 运行
  • Android Studio 中Gradle Build时报错:请求的操作无法在使用用户映射区域打开的文件上

    今天在运行Android项目 Android Studio 中Gradle Build时报错 请求的操作无法在使用用户映射区域打开的文件上执行 1 问题描述 Error java io FileNotFoundException F And
  • 大模型学习 -- CLIP

    本文是CLIP算法的学习笔记 从CLIP算法介绍到具体实现原理 再到应用方法和后续一些优化策略来学习CLIP系列算法 CLIP是什么 CLIP全称是Contrastive Language Image Pre training 一种基于对比
  • 堆叠查询注入攻击

    堆叠注入原理及介绍 Stacked injections 堆叠注入 从名词的含义就可以看到应该是一堆sql语句 多条 一起执行 而在真实的运用中也是这样的 我们知道在mysql中 主要是命令行中 每一条语句结尾加 表示语句结束 这样我们就想
  • 极速入门体验Qt5软件开发,从安装到打包,少走弯路,Qt入门指南,串口调试助手开发实战

    文章目录 前言 一 成果先行 二 下载安装 1 安装QT 三 项目开发实战 1 创建新项目 2 UI设计 3 编写widget h头文件 4 编写widget cpp源文件 四 编译运行 五 项目打包 1 编译发布版 2 绿色版打包 3 安
  • python 调用matlab的.m文件

    最近在找算法的时候扒到一篇有用matlab写的算法 但我平时用的都是python 所以在网上找了有关python调用matlab m文件的教程 但或多或少都有点问题 经过不断尝试总算成功了 先说下软件版本我用matlab是R2020a py
  • 为多用户安装conda_Conda在中文用户名下运行

    让Conda在中文用户名下运行 本实验仅测试于Windows10系统中 理论上这个方法可以适应任何系统 核心是修改 condarc文件中的参数路径 使其脱离中文 关于如何使用conda anaconda miniconda 可以参照我这个博
  • SSM + Activiti5 简单OA系统

    介绍 本项目是为简单版自动化办公流程 项目内置 出差报销流程 可以作为熟悉了解Activit流程引擎学习项目 软件涉及技术 Spring4 SpringMVC4 MyBatis3 MySQL8 Pagehelper 分页控件 Activit
  • python-pickle模块

    python3 pickle持久化的储存数据 python程序运行中得到了一些字符串 列表 字典等数据 想要长久的保存下来 方便以后使用 而不是简单的放入内存中关机断电就丢失数据 python模块大全中pickle模块就排上用场了 他可以将
  • 最先进的深度学习:Mask R-CNN简介

    介绍 Introduction From my experience as a time traveller I can confidently say that autonomous driving is was will be all
  • android dm-verity 功能

    Android dm verity 实现原理深入研究 思维导图 dm verity 说明 源码基于 SC20 平台 Android5 1 Android dm verify overview 目录 Android dm verify ove
  • 协方差矩阵的实例与意义

    协方差矩阵的实例与意义 在机器学习中经常需要计算协方差矩阵 本科时没学过这个概念 一直对此非常头疼 现在试图通过实例的计算 图形化的表示来梳理一下什么是协方差矩阵 A numerical example 问题 有一组数据 如下 分别为二维向
  • Visual Studio 2022配置PCL1.12.1版本点云库

    说明 这个配置步骤是当时自己参考2019配置的 当时网上还没有VS2022的配置步骤 我在自己电脑上是配置成功了 所以我将配置过程记录了下来 仅供参考 1 软件下载 Microsoft Visual Studio 2022 Pro http
  • Kali 实现ARP断网攻击_arp断网攻击_arp欺骗

    1 安装软件包 在中端中执行 apt install dsniff ssldump 2 搜索局域网内的ip地址 nmap sn 192 168 0 这里的192 168 0 有的是192 168 1 执行结果 Nmap scan repor
  • SQLite外键(Foreign Key) 的使用例子

    从SQLite 3 6 19 开始支持 外键约束 sqlite gt PRAGMA foreign keys 0 sqlite gt PRAGMA foreign keys ON sqlite gt PRAGMA foreign keys
  • 机器学习:k近邻算法(KNN)介绍

    k近邻算法是一种最简单最经典的机器学习算法之一 该算法的原理为 当对测试样本进行分类时 首先通过扫描训练样本集 找到与该测试样本最相似的k个训练样本 根据这个样本的类别进行投票确定测试样本的类别 也可以通过个样本与测试样本的相似程度进行加权