MATLAB实现快速近邻法(KNN)分类数学建模算法

本文详细介绍了KNN(K-NearestNeighbors)分类算法,包括其基本思想、步骤,以及其优点(如易于理解和实现、适用于非线性数据)和缺点(计算复杂度高,处理大型数据和高维数据慢)。它在模式识别、图像识别和推荐系统等领域有广泛应用。
摘要由CSDN通过智能技术生成

快速近邻法(KNN)是一种常见的分类算法,它基于实例的学习,通过计算待分类样本与训练集中样本的距离来进行分类。KNN算法的基本思想是,如果一个样本在特征空间中的k个最相似(即距离最近)的样本中的大多数属于某一个类别,则该样本也属于这个类别。

KNN算法的步骤如下:

1. 计算待分类样本与训练集中每个样本的距离,通常使用欧氏距离、曼哈顿距离或闵可夫斯基距离等。
2. 选取与待分类样本距离最近的k个样本。
3. 根据这k个样本的类别,通过多数表决或加权多数表决的方式确定待分类样本的类别。

KNN算法的优点是简单易懂,易于实现,并且对于非线性的数据具有较好的分类性能。然而,KNN算法的缺点是计算复杂度高,对于大型数据集和高维数据的分类速度较慢。

在实际应用中,KNN算法常用于模式识别、图像识别、推荐系统等领域。对于一些简单的分类问题,KNN算法可以提供一个快速而有效的解决方案。

% ==========================快速近邻算法===============================
% ================聚类过程所使用的主要变量==============================
% X:  随机产生的样本集 
% l:   划分的子集数目
% L:   水平数目
% Xp:  节点p对应的样本子集
% Mp:   各类的均值
% Rp:   从Mp到Xi的最远距离
% =============树搜索过程所使用的重要变量=================================
% CurL:  当前水平
% p:     当前结点
% CurTable:  当前目录表中的子样本集
% CurPinT:   在当前目录表中的子样本结点
% RpCur:     当前目录表中结点p对应的Rp
% x:        待判样本
% ======================================================================

% ======================================================================
% ---首先进行聚类---
clear,close all;
% tic
X = [randn(200,2)+ones(200,2);...
     randn(200,2)-2*ones(200,2);...
     randn(200,2)+4*ones(200,2);];
% ---每个水平均划分为l个子集---
[row,col]=size(X);
all_idx=0;L=3;l=3;    
%计算总节点的数目
for i=1:L
    all_idx=all_idx+l^i;
end
Xp=cell(all_idx,1);
Mp=zeros(all_idx,col);
Rp=zeros(all_idx,1);
p=1;
for i=1:L
   if i==1
       [IDX,C,sumd,D] = kmeans(X,l);
        for j=1:l
            Xp(p)={X((IDX==j),:)};
            Mp(p,:)=C(j,:);
            Rp(p)=max(D((IDX==j),j));
            p=p+1;
        end   
   else
       endk=p-1;begink=endk-l^(i-1)+1;       
       for k=begink:endk           
           [IDX,C,sumd,D] = kmeans(Xp{k,1},l);
           X1=Xp{k,1};
           for j=1:l                
                Xp(p)={X1((IDX==j),:)};
                Mp(p,:)=C(j,:);
                Rp(p)=max(D((IDX==j),j));
                p=p+1;
           end   
       end
   end
end
% ====================================================================
% ---进行树搜索---
tic
x=randn(1,2);%待判样本
B=inf;CurL=1;p=0;TT=1;
while TT==1 %步骤2
    Xcurp=cell(1);
    CurTable=cell(l,1);
    CurPinT=zeros(l,1);
    Dx=zeros(l,1);
    RpCur=zeros(l,1);
    %当前节点的直接后继放入目录表   
    for i=1:l   
        CurTable(i,1)=Xp(i+p*l,1);
        CurPinT(i)=i+p*l;
        Dx(i)=norm(x-Mp(i+p*l,:))^2;
        RpCur(i)=Rp(i+p*l);
    end    
    
    while 1 %步骤3
        [rowT,colT]=size(CurTable);
        for i=1:rowT                   
            if Dx(i)>B+RpCur(i)+eps%从目录表中去掉当前节点p
                CurTable(i,:)=[];
                CurPinT(i)=[];
                Dx(i)=[];
                RpCur(i)=[];
                break;
            end
        end
        [CurRowT,CurColT]=size(CurTable);
        if CurRowT==0
           CurL=CurL-1;p=floor((p-1)/3);
           if CurL==0
              TT=0; break;  
           else
               %转步骤3
           end
        elseif CurRowT>0
            [Dxx,Dxind]=sort(Dx,'ascend');
            p1=CurPinT(Dxind(1));
            p=p1;
            %从当前目录表去掉p1
            for j=1:CurRowT
                if CurPinT(j)==p1
                    Xcurp(1,1)=CurTable(j,1);
                    CurTable(j,:)=[];
                    CurPinT(j)=[];
                    CurD=Dx(j);%记录D(x,Mp)
                    Dx(j)=[];
                    RpCur(j)=[];                    
                    break;
                end
            end
            if CurL==L
                XcurpMat=cell2mat(Xcurp);
                [CurpRow,CurpCol]=size(XcurpMat);
                CurpMean=Mp(p,:);
                for k=1:CurpRow
                    Dxi=norm((XcurpMat(k,:)-CurpMean))^2;
                    if CurD>Dxi+B+eps
                        
                    else
                        Dxxi=norm((x-XcurpMat(k,:)))^2;
                        if Dxxi<B+eps
                            B=Dxxi;Xnn=XcurpMat(k,:);
                        end
                    end
                end
            else
                CurL=CurL+1;
                break;
            end
        end
    end
end
B,Xnn,NN=find(X(:,1)==Xnn(1))
time1=toc
% ====================================================================
figure, plot(X(1:200,1),X(1:200,2),'m.')
hold on,plot(X(201:400,1),X(201:400,2),'b.')
hold on,plot(X(401:600,1),X(401:600,2),'g.')   
hold on,plot(Xnn(1),Xnn(2),'kx ','MarkerSize',10,'LineWidth',2)
hold on,plot(x(1),x(2),'r+','MarkerSize',10,'LineWidth',2)
legend('Cluster 1','Cluster 2','Cluster 3','NN','x','Location','NW')


运行结果如下图所示:

  • 10
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

AI Dog

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值