KNN分类算法的MATLAB实现以及可视化

一、KNN简介

KNN算法,即K-Nearest Neighbors,是一种常用的监督学习算法,可以用于分类问题,并且在实际应用中取得了广泛的成功。

二、KNN算法的基本原理

对于给定的测试样本,KNN算法首先计算它与训练集中所有样本的距离。然后,根据这些距离,选择最近的K个邻居进行投票。对于分类任务,通常取前K个样本中类别最多的作为预测结果。

2.1、距离的定义

2.2、K的取值

K的取值比较重要,那么该如何确定K取多少值好呢?答案是通过交叉验证(将样本数据按照一定比例,拆分出训练用的数据和验证用的数据,比如8:2拆分出部分训练数据和验证数据),从选取一个较小的K值开始,不断增加K的值,然后计算验证集合的准确率,最终找到一个比较合适的K值。 和K-means不一样,当K值更大的时候,错误率会更高。这也很好理解,比如说你一共就35个样本,当你K增大到30的时候,KNN基本上就没意义了。且K值一般取奇数,这样可以保证能够取到标签的众数。在下图中K值很明显取K = 3。

三、KNN是一种非参的,惰性的算法模型

非参的意思并不是说这个算法不需要参数,而是意味着这个模型不会对数据做出任何的假设,与之相对的是线性回归(我们总会假设线性回归是一条直线)。也就是说KNN建立的模型结构是根据数据来决定的,这也比较符合现实的情况,毕竟在现实中的情况往往与理论上的假设是不相符的。惰性又是什么意思呢?想想看,同样是分类算法,逻辑回归需要先对数据进行大量训(tranning),最后才会得到一个算法模型。而KNN算法却不需要,它没有明确的训练数据的过程,或者说这个过程很快。

四、KNN算法的优缺点

不对数据分布做出假设,完全基于距离度量对样本特征进行提取;不需要提前进行训练,直接可以进行分类;思想简单,应用广泛。然而,它也有一些缺点,如过度依赖距离度量函数和K值的选择、计算量大、所需内存大、可解释性差、预测速度慢等。

五、自己编写KNN算法的MATLAB实现并可视化

clear;clc;clf;
% 假设我们有一些训练数据和测试数据
train_data = [1.0,1.2;1.2,1.2;1.35,1.8;1.3,1.6;1.33,1.5;1.7,2.0;2.2,2.0;2.1,2.5;2.3,4.3;2.5,4.1;2.7,3.0;3.2,4.4;3.5,4.1;4.1,5.0;3.9,4.2;3.7,4.4;3.5,4.0;4.2,1.2;4.3,1.3;5.0,2.6;5.6,3.6;5.4,4.0;]; % 训练数据的特征矩阵
train_labels = [0;0;0;0;0;0;0;0;0;0;0;1;1;1;1;1;1;2;2;2;2;2]; % 训练数据的标签向量
test_data = [ 5.8,3.6;3.0,3.0;1.1,2.3;1.0,1.0;1.2,4.0;5.2,2.0;3.7,4.0;]; % 测试数据的特征矩阵
K = [3,5,7,9,11];
accuracy_value = zeros(1,5);
rng(111) %固定随机数种子
for j = 1:5% 假设 X 是你的特征矩阵,大小为 [NxD],其中 N 是样本数,D 是特征数% 假设 Y 是你的标签向量,大小为 [Nx1]% 设定k折交叉验证的k值k = K(j); % 创建k折交叉验证的分区cvp = cvpartition(size(train_data, 1), 'KFold', k);% 初始化用于存储结果的变量accuracy = zeros(1, k); % 用于存储每次迭代的准确率% 循环进行k次训练和测试for i = 1:cvp.NumTestSets% 训练集和测试集的索引trainingIdx = training(cvp, i);testIdx = test(cvp, i);% 从原始数据中分离训练和测试数据XTrain = train_data(trainingIdx, :);YTrain = train_labels(trainingIdx);XTest = train_data(testIdx, :);YTest = train_labels(testIdx);% 假设你已经有了预测标签,存储在变量 predictedLabels 中predictedLabels =  knn_classifier(XTrain,YTrain,XTest,k);% 计算准确率correct = sum(predictedLabels == YTest);accuracy(i) = correct / length(YTest);end% 计算平均准确率meanAccuracy = mean(accuracy);accuracy_value(j) = meanAccuracy;
end
figure(1)
plot(K,accuracy_value,'LineWidth',1.5,'Marker','*')
xlabel('k')
ylabel('accuracy')
[L,I] = max(accuracy_value);
K = K(I);
% 调用KNN分类器函数
predicted_labels = knn_classifier(train_data, train_labels, test_data, K);
% 显示预测结果
disp(predicted_labels);
figure(2)
indices1 = find(train_labels==0);
indices2 = find(train_labels==1);
indices3 = find(train_labels==2);
h1 = scatter(train_data(indices1,1),train_data(indices1,2),25,"red","filled");
hold on
h2 = scatter(train_data(indices2,1),train_data(indices2,2),25,"blue","filled");
h3 = scatter(train_data(indices3,1),train_data(indices3,2),25,"green","filled");
indices11 = find(predicted_labels==0);
indices22 = find(predicted_labels==1);
indices33 = find(predicted_labels==2);
h11 = scatter(test_data(indices11,1),test_data(indices11,2),"red","o",'LineWidth',1.5);
h22 = scatter(test_data(indices22,1),test_data(indices22,2),"blue","o",'LineWidth',1.5);
h33 = scatter(test_data(indices33,1),test_data(indices33,2),"green","o",'LineWidth',1.5);
% % 创建网格以可视化决策边界   
xMin = min(train_data(:,1));  
xMax = max(test_data(:,1));  
yMin = min(test_data(:,2));  
yMax = max(train_data(:,2));
h = 0.02;  
[xx, yy] = meshgrid(xMin:h:xMax, yMin:h:yMax);  
% 预测网格点的标签  
labels = knn_classifier(train_data, train_labels,[xx(:), yy(:)],K);  
labels = reshape(labels, size(xx));
alpha = 0.2;
contourf(xx, yy, labels, 'LineWidth',1.5,'FaceAlpha',alpha); % 绘制决策边界  
title(['KNN Decision Boundary (K = ' num2str(K) ')']);  
xlabel('Feature 1');  
ylabel('Feature 2'); 
box onfunction label = knn_classifier(train_data, train_labels, test_data, K)
% train_data: 训练数据的特征矩阵,大小为 [NxD],其中N是样本数,D是特征维度
% train_labels: 训练数据的标签向量,大小为 [Nx1]
% test_data: 测试数据的特征矩阵,大小为 [MxD]
% K: 最近邻居的数量
% label: 测试数据的预测标签向量,大小为 [Mx1]
%——————————————————————————————————————————————————————————————
% 初始化预测标签向量
label = zeros(size(test_data, 1), 1);
% 遍历测试数据集中的每个样本
for i = 1:size(test_data, 1)% 计算测试样本到所有训练样本的距离% 距离函数d(x,y)需要满足三个条件:% ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~% d(x,y)>=0,d(x,y)==0<=>x==y(正定性)% d(x,y)==d(y,x)(对称性)% d(x,y)<=d(x,z)+d(z,y)(三角不等式)%~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~distances = sum((train_data - test_data(i, :)).^2, 2); %欧氏距离
%   distances = sum(abs(train_data - test_data(i, :)),2); %曼哈顿距离% 获取距离排序后的索引[~,sortedDistIndices] = sort(distances); %默认升序排列% 找出最近的K个邻居的索引neighbors_indices = sortedDistIndices(1:K);% 提取这K个邻居的标签neighbors_labels = train_labels(neighbors_indices);% 统计并找出最常见的标签[most_common_label, ~] = mode(neighbors_labels); %众数% 将最常见的标签赋给测试样本label(i) = most_common_label;
end
end

分别运用欧氏距离和曼哈顿距离的运行结果如下图:

 六、KNN算法的适用范围:

  1. 数据特征明确且重要:当数据的特征空间具有清晰的边界,且特征对分类结果有显著影响时,KNN算法通常能表现出色。这是因为KNN直接基于特征空间中的距离来进行分类,所以特征的选择和表示对于算法性能至关重要。

  2. 样本数量适中:对于中等大小的数据集,KNN算法通常是一个有效的选择。然而,当数据集非常大时,KNN的计算成本可能会显著增加,因为需要计算每个查询点与所有训练点之间的距离。在这种情况下,可能需要考虑使用更高效的算法或数据结构来加速距离计算。

  3. 数据分布不均匀:KNN算法对数据的分布没有严格的假设,因此它适用于那些不符合正态分布或其他特定分布的数据集。特别是在数据分布不均匀或存在多个类别的情况下,KNN算法能够很好地处理这些复杂情况。

  4. 类别决策边界复杂:当类别的决策边界非常复杂或不规则时,KNN算法可能是一个好选择。由于KNN算法是基于实例的,它可以很好地捕捉数据中的局部结构和模式,从而在处理复杂决策边界时表现出色。

  5. 实时更新:KNN算法在需要实时更新分类模型的情况下非常有用。由于它不需要显式的训练阶段,只需存储训练数据即可,因此当新的数据点出现时,可以很容易地将其纳入分类过程中。

需要注意的是,虽然KNN算法在某些情况下表现良好,但它也有一些局限性。例如,它对特征的缩放和噪声敏感,可能需要进行特征预处理和参数调优以获得最佳性能。此外,KNN算法的计算成本随着数据集的增长而增加,因此在处理大型数据集时可能不够高效。在选择是否使用KNN算法进行分类时,需要综合考虑这些因素。

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

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

相关文章

Vue - 你知道Vue2中对象动态新增属性,视图无法更新的原因吗

难度级别:中高级及以上 提问概率:55% 这道题面试官会这样描述,比如有这样一个场景,一个对象里有name属性,可以正常显示在页面中。但后续动态添加了一个age属性,通过调试打印发现对象里的age属性已经添加了上了,但试图中却没有展示出来,…

Axure案例分享—垂直手风琴(附下载地址)

今天分享的案例是Axure8(兼容9和10)制作的垂直手风琴 一、功能介绍 折叠或展开多个面板内容&#xff0c;默认为展开一项内容&#xff0c;点击任一收起的选项&#xff0c;展开面板&#xff0c;其他面板收起二、制作过程 原型是由矩形组件以及动态面板构成&#xff0c; 拖入一…

Collection与数据结构 二叉树(一):二叉树的性质与基本操作

1. 树形结构 1.1 概念1 (了解) 树是一种非线性的数据结构&#xff0c;它是由n&#xff08;n>0&#xff09;个有限结点组成一个具有层次关系的集合。把它叫做树是因为它看起来像一棵倒挂的树&#xff0c;也就是说它是根朝上&#xff0c;而叶朝下的。它具有以下的特点&#…

C语言单链表

1. 单链表的概念和结构 概念&#xff1a;链表是一种物理存储结构上非连续、非顺序的存储结构&#xff0c;数据元素的逻辑顺序是通过链表 中的指针链接次序实现的 。 链表与顺序表都属于线性表&#xff0c;顺序表在物理存储结构上是线性的&#xff0c;但是链表在物理存储结构上…

基于springboot+vue+Mysql的学习平台

开发语言&#xff1a;Java框架&#xff1a;springbootJDK版本&#xff1a;JDK1.8服务器&#xff1a;tomcat7数据库&#xff1a;mysql 5.7&#xff08;一定要5.7版本&#xff09;数据库工具&#xff1a;Navicat11开发软件&#xff1a;eclipse/myeclipse/ideaMaven包&#xff1a;…

Centos 下载地址

下载镜像地址&#xff1a; 1、官网地址&#xff1a;The CentOS Project 2、阿里镜像站&#xff1a;centos安装包下载_开源镜像站-阿里云 3、清华镜像源&#xff1a;Index of /centos/ | 清华大学开源软件镜像站 | Tsinghua Open Source Mirror 3.、CentOS搜狐镜像&#xff1…

Spark-Scala语言实战(13)

在之前的文章中&#xff0c;我们学习了如何在spark中使用键值对中的keys和values,reduceByKey,groupByKey三种方法。想了解的朋友可以查看这篇文章。同时&#xff0c;希望我的文章能帮助到你&#xff0c;如果觉得我的文章写的不错&#xff0c;请留下你宝贵的点赞&#xff0c;谢…

JavaSE:图书管理系统

目录 一、前言 二、内容需求 三、类的设计 &#xff08;一&#xff09;图书类 1.Book 类 2.BookList 类 &#xff08;二&#xff09;操作类 1.添加图书AddOperation类 2.借阅图书BorrowOperation类 3.删除图书DelOperation类 4.显示图书ShowOperation类 5.退出系统Ex…

【三十六】【算法分析与设计】综合练习(3),39. 组合总和,784. 字母大小写全排列,526. 优美的排列

目录 39. 组合总和 对每一个位置进行枚举 枚举每一个数出现的次数 784. 字母大小写全排列 526. 优美的排列 结尾 39. 组合总和 给你一个 无重复元素 的整数数组 candidates 和一个目标整数 target &#xff0c;找出 candidates 中可以使数字和为目标数 target 的 所有 不…

手写Spring框架

手写Spring框架 准备工作Spring启动和扫描逻辑实现依赖注入的实现Aware回调模拟实现和初始化机制模拟实现BeanPostProcessor (Bean的后置处理器) 模拟实现Spring AOP 模拟实现Spring Bean生命周期源码分析 Spring中两种生成代理的方式题外话 Spring事务相关Spring事务传播机制S…

C++——栈和队列容器

前言&#xff1a;这篇文章我们将栈和队列两个容器放在一起进行分享&#xff0c;因为这两个要分享的知识较少&#xff0c;而且两者在结构上有很多相似之处&#xff0c;比如栈只能在栈顶操作&#xff0c;队列只能在队头和队尾操作。 不同于前边所分享的三种容器&#xff0c;这篇…

HarmonyOS 应用开发-ArkUI(ets)仿“腾讯新闻”APP

一、效果演示 1、新闻列表页 2、新闻详情页、图片展示页 3、视频页 4、动态页 二、 流程图 –本来自定义了视频的控制栏的&#xff0c;但是发现VideoController()控制器的bug会导致控制器失效&#xff0c;所以没继续做。视频页先不搞了。 三、文件组织&#xff08;“我的页面…

网工内推 | 深信服、宁德时代,最高20K招安全工程师,包吃包住

01 深信服科技 招聘岗位&#xff1a;安全服务工程师 职责描述&#xff1a; 1.负责现场安全服务项目工作内容&#xff0c;包含渗透测试、安全扫描、基线核查、应急响应等&#xff1b; 2.协助用户完成安全测试漏洞整改、复测工作&#xff1b; 3.为用户提供网络、主机、业务系统等…

dg_mmld部分复现

Ours ( K ˆ \^{K} Kˆ2)复现结果– Photo&#xff1a;0.9634730538922156 (at Epoch 23) Art&#xff1a;0.8125 (at Epoch 23) Cartoon&#xff1a;0.7713310580204779 (at Epoch 18) 差距在可接受范围内 辅助信息 If you send 作者 an e-mail, 作者 will tell you a URL w…

2022年蓝桥杯省赛——重合次数

目录 题目链接&#xff1a;1.重合次数 - 蓝桥云课 (lanqiao.cn) 题目描述 答案提交 运行限制 思路 总结 题目链接&#xff1a;1.重合次数 - 蓝桥云课 (lanqiao.cn) 题目描述 在同一天中, 从上午 6 点 13 分 22 秒到下午 14 点 36 分 20 秒, 钟表上的 分针和秒针一共重合…

HTML - 请你谈一谈img标签图片和background背景图片的区别

难度级别:中级及以上 提问概率:65% 面试官当然不会问如何使用img标签或者background来加载一张图片,这些知识点都很基础,相信只要从事前端开发一小段时间以后,就可以轻松搞定加载图片的问题。但很多人习惯用img标签,很多人习惯用backgro…

Java 数据类型转换

String 转 char 数组 String str "abc"; char[] charArr str.toCharArray();char 数组转 String char[] charArr{a, b, c}; String str new String(charArr);char 字符转 String 使用 String.valueOf() 方法 char ch a; String str String.valueOf(ch);使…

element-ui的年份范围选择器,选择的年份需等于或小于当前年份,选择的年份范围必须在三年之内

写在前面 日期限制处理&#xff08;禁用&#xff09;&#xff0c;下面我以我这边的需求为例&#xff0c; 选择的年份需等于或小于当前年份 选择的年份范围必须在三年之内 1.限制起始日期小于截止日期 1&#xff09;根据用户选中的开始日期&#xff0c;置灰不可选的日期范围&…

【腾讯云 TDSQL-C Serverless 产品体验】饮水机式使用云数据库

云计算的发展从IaaS&#xff0c;PaaS&#xff0c;SaaS&#xff0c;到最新的BaaS&#xff0c;FasS&#xff0c;在这个趋势中serverless(去服务器化&#xff09; 计算资源发展Physical -> Virtualisation -> Cloud Compute -> Container -> Serverless。 一、背景介绍…

什么是电子邮件组,为什么要使用它们?

在当今时代&#xff0c;电子邮件无处不在&#xff0c;尤其是对于商业活动而言。电子邮件的重要性不容忽视&#xff0c;因为它在沟通中极为高效。然而&#xff0c;电子邮件也存在降低工作效率和阻碍流程的风险。在这种情况下&#xff0c;电子邮件群组就是最佳的解决方案。什么是…