分类分析|KNN分类模型及其Python实现

KNN分类模型及其Python实现

  • 1. KNN算法思想
  • 2. KNN算法步骤
    • 2.1 KNN主要优点
    • 2.2 KNN主要缺点
  • 3. Python实现KNN分类算法
    • 3.1 自定义方法实现KNN分类
    • 3.2 调用scikit-learn模块实现KNN分类
  • 4. K值的确定

在之前文章 分类分析|贝叶斯分类器及其Python实现中,我们对分类分析和分类模型进行了介绍,这里

1. KNN算法思想

 KNN(K-Nearest Neighbor)最邻近分类算法是一种基于类比学习的分类算法,其指导思想是”近朱者赤,近墨者黑“,即由你的邻居来推断出你的类别。其算法原理是在训练数据集中找出K个与预测样本距离最近且最相似的样本,这些样本大部分属于哪个类别,则该预测样本也属于哪个类别。
 KNN分类算法的实现原理:为了判断未知样本的类别,以所有已知类别的样本作为参照,计算未知样本与所有已知样本的距离,从中选取与未知样本距离最近的K个已知样本,根据少数服从多数的投票法则(majority-voting),将未知样本与 K K K个最邻近样本中所属类别占比较多的归为一类。

k k k最近邻分类主要的问题是确定样本集、距离函数、组合函数和 k k k值。

在这里插入图片描述

2. KNN算法步骤

  1. 计算预测数据样本与各个训练数据样本之间的距离;
  2. 按照距离的递增关系进行排序;
  3. 选取距离最小的K个数据样本(前面K个);
  4. 确定前K个数据样本所在类别的出现频率;
  5. 前K个数据样本中出现频率最高的类别作为预测数据样本的类别。

2.1 KNN主要优点

(1) 简单好用,容易理解,精度高,理论成熟,既可以用来做分类也可以用来做回归。
(2) 可用于数值型数据和离散型数据。
(3) 训练时间复杂度为 O ( n ) O(n) O(n),无数据输入假定。
(4) 对异常值不敏感。

2.2 KNN主要缺点

KNN算法是目前较为常用且成熟的分类算法,但是KNN算法也有一定的不足:
(1) 计算复杂性高、空间复杂性高。
(2) 当样本不平衡(有些类别的样本数量很大,而其它样本的数量又很少)时,容易产生误分。
(3) 一般样本数量很大的时候不用KNN,因为计算量很大。但是数据样本量又不能太少,此时容易产生误分。
(4) 无法给出数据的内在含义。

3. Python实现KNN分类算法

3.1 自定义方法实现KNN分类

 下例中,假设训练集数据为学生各门课程测验成绩,标签为综合等级评价。利用KNN方法对样本进行分类预测。

#trainData-训练集、testData-测试集、labels-分类
def knn(trainData, testData, labels, k):
    rowSize = trainData.shape[0] #计算训练样本的行数
    diff=np.tile(testData,(rowSize,1))-trainData #计算训练样本和测试样本的差值
    sqrDiff = diff ** 2  #计算差值的平方和
    sqrDiffSum = sqrDiff.sum(axis=1)
    distances = sqrDiffSum ** 0.5  #计算距离
    sortDistance = distances.argsort() #对所得的距离从低到高进行排序
    count = {}
    for i in range(k):
        vote = labels[sortDistance[i]]
        count[vote] = count.get(vote, 0) + 1
        sortCount = sorted(count.items(),reverse=True) #对类别出现的频数从高到低进行排序
    return sortCount[0][0] #返回出现频数最高的类别
import numpy as np
trainData = np.array([[100,100,100],[90,98,97],[90,90,85],
[100,90,93],[80,90,70],[100,80,100],[95,95,95],[95,90,80],
[90,75,90],[95,95,90],[100,100,95]])
labels = ['优', '良', '中', '良','中','良','优','中','中','良','优']
testData = [97,96,92]
X = knn(trainData, testData, labels, 3)
print(X)
输出结果:良

3.2 调用scikit-learn模块实现KNN分类

 在scikit-learn 中,与KNN法这一大类相关的类库都在sklearn.neighbors包之中。当使用函数KNeighborsClassifier()进行分类时,需要导入相关的类库,语句为:from sklearn import neighbors。常用形式为:
KNeighborsClassifier(n_neighbors=5,weights=’uniform’)

KNeighborsClassifier函数一共有8个参数,参数说明:

  1. n_neighbors:KNN中的k值,int,默认为5。
  2. weights: 默认是uniform,参数可以是uniform、distance,也可以是用户自己定义的函数(直接weights=函数名就行)。uniform是均等的权重,就说所有的邻近点的权重都是相等的。distance是不均等的权重,距离近的点比距离远的点的影响大。用户自定义的函数,接收距离的数组,返回一组维数相同的权重。
  3. algorithm: {‘auto’, ‘ball_tree’, ‘kd_tree’, ‘brute’}, default=’auto’。快速k近邻搜索算法,默认参数为auto,可以理解为算法自己决定合适的搜索算法。除此之外,用户也可以自己指定搜索算法ball_tree、kd_tree、brute方法进行搜索,brute是蛮力搜索,也就是线性扫描,当训练集很大时,计算非常耗时。kd_tree,构造kd树存储数据以便对其进行快速检索的树形数据结构,kd树也就是数据结构中的二叉树。以中值切分构造的树,每个结点是一个超矩形,在维数小于20时效率高。ball tree是为了克服kd树高纬失效而发明的,其构造过程是以质心C和半径r分割样本空间,每个节点是一个超球体。
  4. leaf_size: int ,default=30。leaf_size:默认是30,这个是构造的kd树和ball树的大小。这个值的设置会影响树构建的速度和搜索速度,同样也影响着存储树所需的内存大小。需要根据问题的性质选择最优的大小。
  5. metric: str or callable, default=’minkowski’。用于距离度量,默认度量是minkowski(也就是闵氏距离,当p=2时为欧氏距离(欧几里德度量)。
  6. p: 距离度量公式。即设置metric里闵氏距离的参数p,这个参数默认为2,也就是默认使用欧式距离公式进行距离度量。也可以设置为1,使用曼哈顿距离公式进行距离度量。
  7. metric_params: 距离公式的其他关键参数,这个基本不用,使用默认的None即可。
  8. n_jobs:并行处理设置。默认为1,临近点搜索并行的工作数。如果为-1,那么CPU的所有cores都用于并行工作。

例: 对鸢尾花数据集进行分类

import matplotlib.pyplot as plt
import numpy as np
from matplotlib.colors import ListedColormap
from sklearn import neighbors, datasets
n_neighbors = 11 #取k=11
iris = datasets.load_iris()  #导入鸢尾花数据集
x = iris.data[:,:2]  #取前两个feature,方便在二维平面上画图
y = iris.target
h = .02  #网格中的步长
cmap_light = ListedColormap(['#FFAAAA', '#AAFFAA', '#AAAAFF'])# 创建彩色的图
cmap_bold = ListedColormap(['#FF0000', '#00FF00', '#0000FF'])
for weights in ['uniform', 'distance']: #绘制两种weights参数的KNN效果图  
    clf = neighbors.KNeighborsClassifier(n_neighbors, weights=weights)  # 创建了一个KNN分类器的实例,并拟合数据
    clf.fit(x, y)
    # 绘制决策边界。为此,将为每个数据对分配一个颜色来绘制网格中的点 [x_min, x_max]、[y_min, y_max]
    x_min, x_max = x[:, 0].min() - 1, x[:, 0].max() + 1
    y_min, y_max = x[:, 1].min() - 1, x[:, 1].max() + 1
    xx, yy = np.meshgrid(np.arange(x_min, x_max, h),
                         np.arange(y_min, y_max, h))
    Z = clf.predict(np.c_[xx.ravel(), yy.ravel()])
    # 将结果放入一个彩色图中
    Z = Z.reshape(xx.shape)
    plt.figure()
    plt.pcolormesh(xx, yy, Z, cmap=cmap_light)
    # 绘制训练点
    plt.scatter(x[:, 0], x[:, 1], c=y, cmap=cmap_bold)
    plt.xlim(xx.min(), xx.max())
    plt.ylim(yy.min(), yy.max())
    plt.title("3-Class classification (k = %i, weights = '%s')"
             % (n_neighbors, weights))
plt.show()

在这里插入图片描述

4. K值的确定

 KNN算法中只有一个超参数K,K值的确定对KNN算法的预测结果有着至关重要的影响。
 如果K值比较小,相当于在较小的领域内训练样本并对实例(预测样本)进行预测。这时,算法的近似误差会比较小,因为只有与实例相近的训练样本才会对预测结果起作用。但是,它也有明显的缺点:算法的估计误差比较大,预测结果会对邻近点十分敏感,如果邻近点是噪声点的话,预测就会出错。因此,K值过小容易导致KNN算法的过拟合。
 同理,如果K值选择较大的话,距离较远的训练样本也能够对实例预测结果产生影响。这时候,模型相对比较鲁棒,不会因为个别噪声对最终预测结果产生影响。但是缺点也十分明显:算法的邻近误差会偏大,距离较远的点(与预测实例不相似)也会同样对预测结果产生影响,使得预测结果产生较大偏差,此时模型容易发生欠拟合。
  在实际工程实践中,一般采用交叉验证的方式选取K值。通过以上分析可知,一般尽量在较小范围内选取K值,同时把测试集上准确率最高的那个K值确定为最终算法的参数K。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

DHCP的原理与配置

一.了解DHCP服务 1. DHCP (Dynamic Host Configuration Protocol)动态主机配置协议 是由Internet工作小组设计开发的,专门用于为TCP/IP网络中的计算机自动分配TCP/IP参数的协议 DHCP协议采用的是UDP作为传输协议,是给网络内的客户机自动分配IP地址&…

Redis入门到通关之Redis实现Session共享

文章目录 ☃️前期概要☃️基于Session实现登录方案☃️现有方案存在的问题☃️Redis代替Session的业务流程❄️❄️设计key的结构❄️❄️设计key的具体细节❄️❄️整体访问流程 欢迎来到 请回答1024 的博客 🍓🍓🍓欢迎来到 请回答1024的博…

羊大师分析,羊奶和牛奶哪个更适合夏天喝?

羊大师分析,羊奶和牛奶哪个更适合夏天喝? 羊奶和牛奶都是营养丰富的饮品,适合不同人群在不同季节饮用。在夏天,选择羊奶还是牛奶主要取决于个人的体质、口味偏好以及需求。 羊奶的营养价值较高,含有丰富的蛋白质、矿物…

ESP8266+STM32+阿里云保姆级教程(AT指令+MQTT)

前言:在开发过程中,几乎踩便了所有大坑小坑总结出的文章,我是把坑踩满了,帮助更过小白快速上手,如有错误之处,还麻烦各位大佬帮忙指正、 目录 一、ESP-01s介绍 1、ESP-01s管脚功能: 模组启动模…

元数据管理和数据目录对于现代数据平台的重要性——Lakehouse架构(四)

文章目录 前言解读元数据技术元数据业务元数据 元存储和数据目录如何协同工作?数据目录的特点查询、检索和发现数据数据分类数据治理数据血缘 前言 Lakehouse 架构中的存储层负责存储整个平台的数据,要查询存储的这些数据,我们需要一个数据目…

xgp怎么取消续费 微软商店xgp会员取消自动续费详细教程

xgp怎么取消续费 微软商店xgp会员取消自动续费详细教程 XGP这个游戏平台小伙伴们并不陌生吧,它是微软Xbox游戏部门推出的游戏租赁制会员服务,主要用于主机和PC两个平台。这个平台的会员就可以免费享受多款大制作游戏,而且每个月还会自动更新…

ruoyi-nbcio-plus基于vue3的flowable收回任务后重新进行提交表单的处理

更多ruoyi-nbcio功能请看演示系统 gitee源代码地址 前后端代码: https://gitee.com/nbacheng/ruoyi-nbcio 演示地址:RuoYi-Nbcio后台管理系统 http://122.227.135.243:9666/ 更多nbcio-boot功能请看演示系统 gitee源代码地址 后端代码&#xff1a…

JAVA毕业设计137—基于Java+Springboot+Vue的物流快递仓库管理系统(源代码+数据库)

毕设所有选题: https://blog.csdn.net/2303_76227485/article/details/131104075 基于JavaSpringbootVue的物流快递仓库管理系统(源代码数据库)137 一、系统介绍 本项目前后端分离,分为员工、销售员、仓库员、商品管理员、超级管理员五种角色 1、员工…

Linux 的情况下实现贪吃蛇 -- 第二十八天

1. 打印地图 keypad(stdsrc,1) 参数表示是否接收,1表示接收指令 2.思路:初始化initNcurses(), 封装地图函数实现地图gamePic() 分三部分实现:2.1: 在第0行:打印 "--",&quo…

矩阵连乘算法

矩阵连乘&#xff1a; #include<iostream> #define inf 0x7fffffff using namespace std; int a[256] { 0 };//存储矩阵的行和列 int m[256][256] { 0 };//存储i到j的最少计算次数 int s[256][256] { 0 };//存储i到j的中转站k void m_print(int i, int j) {if (i …

javaWeb项目-房屋房租租赁系统功能介绍

项目关键技术 开发工具&#xff1a;IDEA 、Eclipse 编程语言: Java 数据库: MySQL5.7 框架&#xff1a;ssm、Springboot 前端&#xff1a;Vue、ElementUI 关键技术&#xff1a;springboot、SSM、vue、MYSQL、MAVEN 数据库工具&#xff1a;Navicat、SQLyog 1、JSP技术 JSP(Jav…

数据结构-二叉树-链式

一、链式二叉树的结构 typedef int BTNodeDataType; typedef struct BTNode {BTNodeDataType data;struct BTNode* left;struct BTNode* right; }BTNode; 二叉树的前中后序遍历 前序&#xff1a;根左右 中序&#xff1a;左根右 后序&#xff1a;左右根 void PreOrder(BTNo…

栈 、队列

1.stack的介绍和使用 1.1stack的介绍 stack是一种容器适配器&#xff0c;专门用在具有后进先出操作的上下文环境中&#xff0c;其删除只能从容器的一端进行元素的插入与提取操作。 1.2 stack的使用 函数说明 接口说明 stack() 构造空的栈 empty() 检测stack是否为空 size…

Opencv | 边缘检测 轮廓信息

目录 一. 边缘检测1. 边缘的定义2. Sobel算子 边缘提取3. Scharr算子 边缘提取4. Laplacian算子 边缘提取5. Canny 边缘检测算法5.1 计算梯度的强度及方向5.2 非极大值抑制5.3 双阈值检测5.4 抑制孤立弱边缘 二. 轮廓信息1. 获取轮廓信息2. 画轮廓 一. 边缘检测 1. 边缘的定义…

【QT】Ubuntu22.04 配置 QT6.5 LTS

【QT】Ubuntu22.04 配置 QT6.5 LTS 文章目录 【QT】Ubuntu22.04 配置 QT6.5 LTS1.注册QT Group的账号2.安装QT Creator3.启动QT Creator报错from 6.5.0, xcb-cursor0 or libxcb-cursor0 is needed to load the Qt xcb platform plugin.4.运行QT的demoReference 1.注册QT Group的…

mysql buffer pool详解

介绍 缓冲池是InnoDB在访问表和索引数据时缓存的主内存区域。缓冲池允许直接从内存访问频繁使用的数据&#xff0c;这加快了处理速度。在专用服务器上&#xff0c;通常会将多达80%的物理内存分配给缓冲池。 为了提高大容量读操作的效率&#xff0c;缓冲池被划分为可能包含多行…

类与对象(三) 拷贝构造与赋值运算符重载

目录 1.拷贝构造 2.运算符重载&#xff08;日期类举例&#xff09; 1. 2.和 3. > > < < 4.赋值运算符重载 5.- 与- 6. -- 7.日期 - 日期 3.const成员函数 4.<<和>>重载 5.取地址重载 1.拷贝构造 拷贝构造也是一个构造函数。我们前…

Linux:动静态库介绍

动静态库 库的介绍开发环境 & 编译器库存在的意义库的实现库的命名静态库制作和使用总结 动态库的制作和使用动态库的使用方法方法一方法二方法三 库加载问题静态库加载问题动态库的加载问题与位置无关码 C/C静态库下载方式 库的介绍 静态库&#xff1a;程序在编译链接的时…

C++初识--------带你从不同的角度理解引用的巧妙之处

1.对于展开的理解 我们这里的展开包括命名空间的展开和头文件的展开&#xff0c;两者的含义是不一样的&#xff1a; 头文件的展开就是把头文件拷贝到当前的文件里面&#xff1b; 命名空间的展开不是拷贝&#xff0c;而是因为编译器本身默认是到全局里面去找&#xff0c;当我…

一些常见的Windows命令

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言看版本号查找端口启动程序杀死某个端口查看全部端口看ip进入目录就是总结 前言 提示&#xff1a;这里可以添加本文要记录的大概内容&#xff1a; 例如&#x…