MATLAB 基于平均距离改进的kNN

function [A_kNN_ave,label_kNN_ave,P_kNN_ave]=f_kNN_ave(tr,te,k)

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%函数名称:基于平均距离的k近邻学习器 f_knn_ave.m
%%入口参数:训练数据 tr   测试数据 te   数据形式 特征+标签   近邻数 k
%%出口参数:精度 A_kNN_ave   预测标签 label_kNN_ave    对所有种类的概率 P_kNN_ave
%%函数说明:
    %%对于测试样本,搜寻最近的每一种训练样本各k个,通过平均距离进行分类
    %%适合用于不均衡分类,在均衡分类中,也表现不俗
    %%缺点,速度慢,不能提前建模
    %%其它,可以精确估计运行时间,概率可信度高
%%by Sebastian Li, 2020.10.28, ZZU
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%



if ~exist('k', 'var')
     k = 3;
end               % 如果没有输入k值,取k=3
                  % 也很有意思,取3总不会太差


    
n=size(tr,2);
m1=size(tr,1);
m2=size(te,1);    % m1为训练样本数,m2为测试样本数

trd=tr(:,1:n-1);
trl=tr(:,n);
ted=te(:,1:n-1);
tel=te(:,n);      % -d(data)为数据,-l(label)为标签

L=unique(trl);      % 统计种类
ls=size(L,1);       % 统计类别总数

probability=zeros(size(te,1),ls); 
label_kNN_ave=zeros(m2,1);         % 预设运行空间

for j=1:m2   % 对每一个测试样本
    distance=zeros(m1,1);
    for i=1:m1   % 对每一个训练样本
        distance(i)=norm(ted(j,:)-trd(i,:));    %计算测试数据与每个训练数据的欧式距离 
    end
    [distance1,index]=sort(distance);  % 对所有距离进行排序
    x1=trl(index);
    distance1(:,2)=x1;      % distance1的第一列是距离,第二列是标签
    di=zeros(ls,2);
for w=L'   % 对每个种类
    x2=find(distance1(:,2)==w);
    x2=x2(1:k,:);
    dis=distance1(x2,1);
    dis=sum(dis)/k;
    di(w,1)=dis;
    di(w,2)=w;
end                      % 把每一种标签都找出距离最近的k的样本,并计算平均距离
di(di(:,1)==0,:)=[];   % 处理标签不连续

c=sum(di(:,1))./di(:,1)';
c=c/max(c,[],2);
c(isnan(c)) = 0;   % 如果出现NaN,转化为0
probability(j,:)=c;      % 输出概率:距离的总和除以各个距离,然后除以其中最大值,得类概率

b=sortrows(di,1);
label_kNN_ave(j,1)=b(1,2);  % 平均距离最近的标签为预测标签
end
P_kNN_ave=[probability,label_kNN_ave];
bj=(label_kNN_ave==tel);
a=nnz(bj);
A_kNN_ave=a/m2;                % 输出识别率
end

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值