闭着眼学机器学习——K近邻分类

news2024/11/24 15:23:17

引言:
在正文开始之前,首先给大家介绍一个不错的人工智能学习教程:https://www.captainbed.cn/bbs。其中包含了机器学习、深度学习、强化学习等系列教程,感兴趣的读者可以自行查阅。


1. 算法介绍

K近邻(K-Nearest Neighbors, KNN)算法 是一种简单而有效的监督学习算法,主要用于分类和回归任务。KNN的核心思想是"物以类聚",即相似的数据点在特征空间中应该靠近。在分类任务中,KNN通过找到待分类点周围最近的K个邻居,然后通过多数表决来决定待分类点的类别。

2. 算法原理

KNN算法的工作原理可以概括为以下步骤:

  1. 计算待分类点与训练集中所有点的距离
  2. 选择距离最近的K个点
  3. 统计这K个点的类别
  4. 将待分类点归为出现次数最多的类别

距离计算通常使用欧氏距离,其公式为:

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

其中 x x x y y y 是两个n维向量。

K值的选择对算法性能有重要影响。较小的K值可能导致过拟合,而较大的K值可能导致欠拟合。通常通过交叉验证来选择最优的K值。

3. 案例分析

在本案例中,我们生成一个二维的模拟数据集,包含300个样本和两个类别。我们使用scikit-learn库中的KNeighborsClassifier来实现KNN算法。主要步骤如下:

  1. 数据准备:生成模拟数据并划分训练集和测试集。

  2. 选择最佳K值:使用交叉验证来选择最优的K值

  3. 模型训练与预测:使用最佳K值创建KNN模型,在训练集上训练,并对测试集进行预测。

  4. 模型评估:计算准确率并打印详细的分类报告。

  5. 可视化:

    • K值与准确率关系图:展示不同K值对应的交叉验证准确率。
    • K近邻分类结果图:展示分类决策边界,训练集和测试集的分布,以及错误分类的点。
    • 混淆矩阵:直观显示分类结果的正确性和错误类型。

完整代码:

import numpy as np
import matplotlib.pyplot as plt
from sklearn.neighbors import KNeighborsClassifier
from sklearn.model_selection import train_test_split, cross_val_score
from sklearn.metrics import accuracy_score, classification_report, confusion_matrix
import seaborn as sns

# 设置中文字体
plt.rcParams['font.sans-serif'] = ['SimSun']  # 使用宋体
plt.rcParams['axes.unicode_minus'] = False  # 解决负号显示问题

# 生成模拟数据
np.random.seed(42)
X = np.random.randn(300, 2)
y = np.logical_xor(X[:, 0] > 0, X[:, 1] > 0)

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

# 使用交叉验证选择最佳的K值
k_range = range(2, 11)
k_scores = []
for k in k_range:
    knn = KNeighborsClassifier(n_neighbors=k)
    scores = cross_val_score(knn, X_train, y_train, cv=5, scoring='accuracy')
    k_scores.append(scores.mean())

# 找到最佳的K值
best_k = k_range[k_scores.index(max(k_scores))]
print(f"最佳的K值: {best_k}")

# 使用最佳的K值创建并训练KNN模型
knn = KNeighborsClassifier(n_neighbors=best_k)
knn.fit(X_train, y_train)

# 预测
y_pred = knn.predict(X_test)

# 计算准确率
accuracy = accuracy_score(y_test, y_pred)
print(f"准确率: {accuracy:.2f}")

# 打印分类报告
print("分类报告:")
print(classification_report(y_test, y_pred, target_names=['类别 0', '类别 1']))

# 绘制K值与准确率的关系图
plt.figure(figsize=(10, 6))
plt.plot(k_range, k_scores)
plt.xlabel('K值')
plt.ylabel('交叉验证准确率')
plt.title('K值与准确率的关系')
plt.show()

# 创建K近邻分类结果图
plt.figure(figsize=(10, 8))

# 创建网格点
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, 0.02),
                     np.arange(y_min, y_max, 0.02))

# 预测网格点的类别
Z = knn.predict(np.c_[xx.ravel(), yy.ravel()])
Z = Z.reshape(xx.shape)

# 绘制决策边界
plt.contourf(xx, yy, Z, alpha=0.8, cmap=plt.cm.RdYlBu)

# 绘制训练点
plt.scatter(X_train[y_train == 0][:, 0], X_train[y_train == 0][:, 1], c='red', label='训练集类别 0', edgecolors='k')
plt.scatter(X_train[y_train == 1][:, 0], X_train[y_train == 1][:, 1], c='blue', label='训练集类别 1', edgecolors='k')

# 绘制测试点
plt.scatter(X_test[y_test == 0][:, 0], X_test[y_test == 0][:, 1], c='red', marker='^', label='测试集类别 0', edgecolors='k')
plt.scatter(X_test[y_test == 1][:, 0], X_test[y_test == 1][:, 1], c='blue', marker='^', label='测试集类别 1', edgecolors='k')

# 标记错误分类的点
plt.scatter(X_test[y_pred != y_test][:, 0], X_test[y_pred != y_test][:, 1], 
            c='green', marker='x', s=100, label='错误分类')

plt.title(f'K近邻分类结果 (K={best_k})')
plt.xlabel('特征1')
plt.ylabel('特征2')
plt.legend()

plt.show()

# 创建混淆矩阵图
plt.figure(figsize=(8, 6))
cm = confusion_matrix(y_test, y_pred)
sns.heatmap(cm, annot=True, fmt='d', cmap='Blues')
plt.title('混淆矩阵')
plt.xlabel('预测类别')
plt.ylabel('真实类别')
plt.xticks([0.5, 1.5], ['类别 0', '类别 1'])
plt.yticks([0.5, 1.5], ['类别 0', '类别 1'])

plt.show()

通过运行上述代码,可以得到以下结果:

K值与准确率的关系图:

KNN分类结果的可视化:

混淆矩阵:

4. 总结

K近邻算法是一种简单而强大的分类算法,易于理解和实现。它不需要训练过程,属于"懒惰学习"的范畴。然而,KNN也有其局限性,如计算复杂度高、对特征尺度敏感等。在实际应用中,可能需要结合特征选择、降维等技术来提高KNN的效率和性能。

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

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

相关文章

ScriptableObject基本使用

使用方法 自定义类继承ScriptableObject 可以在类内部增加数据或者数据类,一般用于配置 注意事项 给继承ScriptableObject的类增加CreateAssetMenu特性。 CreateAssetMenu一般默认三个参数 第一个参数是父目录 第二个参数是父目录的子选项 第三个参数是可以…

虚幻闪烁灯光材质

创建一个材质 材质域改成光照函数 , Time让材质动起来 参数B用来控制速度 , Sine 让灯光闪烁 , Frac 增加了闪烁细节 把材质放到灯光材质上 效果还是挺不错的! 可以用于一些恐怖游戏~

FileZilla的简单使用

FileZilla的下载与安装以及简单使用(有图解超简单)-CSDN博客 参考这篇文章。 我在Window下安装了客户端,在虚拟机下启动Ubuntu,启用了Ubuntu的FTP服务。 按照该文章的流程进行下去,成功的把客户端上的文件上传到了F…

STM32学习--6-1 定时器定时中断

定时器电路图 第一步:RCC开启时钟,基本上每个代码都是第一步 第二步:选择时基单元的时钟源(内部时钟) 第三步:配置时基单元,包括预分频器、自动重装器、计数模式等,通过结构体配置…

Dockerfile(Jenkins)

1.创建⼀个jenkins的Dockerfile mkdir tomcat cd tomcat 2、上传需要的安装包 apache-tomcat-8.5.47.tar.gz jdk-8u211-linux-x64.tar.gz jenkins.war 3、编写Dockerfile vim Dockerfile # This my first jenkins Dockerfile # Version 1.0 FROM centos:7 MAINTAINER l…

Echarts+vue3+高德渲染地图

Echartsvue3高德渲染地图 一&#xff1a;安装 npm install echarts二&#xff1a;渲染地图 1. html <template><div class"content"><div ref"myChartsRef" id"map" style"width: 100%;height: 560px;" ></d…

JAVA自动化测试TestNG框架

1.TestNG简介 JAVA自动化测试最重要的基石。官网&#xff1a;https://testng.org 使用注解来管理我们的测试用例。 发现测试用例 执行测试用例 判断测试用例 生成测试报告 2.创建Maven工程 2.1创建一个maven工程 2.2设置maven信息 2.3设置JDK信息 2.4引入testng依赖 <dep…

Linux下Docker方式Jenkins安装和配置

一、下载&安装 Jenkins官方Docker仓库地址&#xff1a;https://hub.docker.com/r/jenkins/jenkins 从官网上可以看到&#xff0c;当前最新的稳定版本是 jenkins/jenkins:lts-jdk17。建议下在新的&#xff0c;后面依赖下不来 所以&#xff0c;我们这里&#xff0c;执行doc…

达梦数据库性能优化

1、SQL执行计划 拿到一条SQL的时候&#xff0c;首先要下达梦手册中提出的有效SQL规范&#xff0c;及是否命中了特殊OR子句的不规范&#xff0c;是否用了复杂的正则表达式&#xff0c;避免重复很高的索引&#xff0c;UINON ALL 是否可以替换UNION操作等,某些场景INSTR函数导致的…

FunASR离线文件转写服务开发指南-debian-10.13

FunASR离线文件转写服务开发指南-debian-10.13 服务器环境 debian10.13 64位 第一步 配置静态网卡 auto eth0 iface eth0 inet static address 192.168.1.100 netmask 255.255.255.0 gateway 192.168.1.1 dns-nameservers 8.8.8.8 8.8.4.4/etc/init.d/networking restart第…

C++面试速通宝典——25

473. HTTP如何减少重定向请求 重定向请求&#xff1a; ‌‌‌‌  服务器上的一个资源可能由于迁移、维护等原因从url1移至url2后&#xff0c;而客户端不知情&#xff0c;他还是继续请求url1&#xff0c;这时服务器不能粗暴地返回错误&#xff0c;而是通过302响应码和Locati…

甲方安全和乙方安全的区别

信息安全工作&#xff0c;总会被人分成甲方和乙方&#xff0c;甲乙方原本只是商务层面需方和供方的代称&#xff0c;在安全领域&#xff0c;成了做公司内部安全和为客户提供安全的区别。 通常意义上&#xff0c;什么是甲方安全人员呢&#xff1f;就是在非安全业务的公司从事信…

ROS2 通信三大件之动作 -- Action

通信最后一个&#xff0c;也是不太容易理解的方式action&#xff0c;复杂且重要 1、创建action数据结构 创建工作空间和模块就不多说了 在模块 src/action_moudle/action/Counter.action 下创建文件 Counter.action int32 target # Goal: 目标 --- int32 current_value…

[Python学习日记-45] Python 中模块的介绍与导入

[Python学习日记-45] Python 中模块的介绍与导入 简介 模块的概念与好处 模块的分类 模块导入和调用 自定义模块 模块的查找路径 简介 在前面的学习当中偶尔我们会看到 import ... 一个什么东西的&#xff0c;或者 from ... import ...&#xff0c;那时候并没有进行介绍&…

react+ts+vite 别名一直爆红问题

已经配置如下代码安装了types/node import path from "path"; // https://vitejs.dev/config/ export default defineConfig({plugins: [react()],server: {proxy: {"/api": {target: "http://localhost:3000",changeOrigin: true,rewrite: (pa…

如何选择安全的谷歌浏览器插件

在数字时代&#xff0c;浏览器插件为我们提供了极大的便利&#xff0c;增强了我们的浏览体验。然而&#xff0c;随着便利性的增加&#xff0c;安全性问题也日益凸显。选择安全的谷歌浏览器插件是保障个人信息安全的重要步骤。以下是详细的教程&#xff0c;帮助你选择和使用安全…

81 NAT-静态NAT

一 NAT 出口方向实验 1 配置接口的IP地址 2 配置nat 静态映射 3 测试 无法ping 通 202.38.1.100 4 接口上开启静态Nat映射规则 [FW-Router-BJ-GigabitEthernet0/1]nat static enable 6 5 查看配置 [FW-Router-BJ]display nat static 6 测试 7 查看NAT 会话状态 8 静态…

Qt自定义一个圆角对话框

如何得到一个圆角对话框&#xff1f; 步骤&#xff1a; 1、继承自QDiaglog 2、去掉系统自带的边框 3、设置背景透明,不设置4个角会有多余的部分出现颜色 4、对话框内部添加1个QWidget&#xff0c;给这个widget设置圆角&#xff0c;并添加到布局中让他充满对话框 5、后续对…

Redis协议详解及其异步应用

目录 一、Redis Pipeline&#xff08;管道&#xff09;概述优点使用场景工作原理Pipeline 的基本操作步骤C 示例&#xff08;使用 [hiredis](https://github.com/redis/hiredis) 库&#xff09; 二、Redis 事务概述事务的前提事务特征&#xff08;ACID 分析&#xff09;WATCH 命…

【HarmonyOS】HMRouter使用详解(二)路由跳转

路由跳转 HMRouter中使用HMRouterMgr的静态方法push()和replace()来实现路由跳转。使用pop()方法来实现页面返回 push &#xff1a;目标页面不会替换当前页&#xff0c;而是插入页面栈。可以使用pop实现页面的返回操作。replace&#xff1a;目标页面会替换当前页&#xff0c;并…