KNN(K-Nearest Neighbor)算法Matlab实现

应用背景:最近邻分类器(KNN)是机器学习中一种最简单的分类方法,作用对象一般是通过前期的预处理、特征提取并进行降维后的N维样本特征,待识别测试集中的样本同带有标签的训练集样本一一匹配(通常是某种相似性度量方法,如距离测度(欧式距离)),将匹配距离最小、出现次数最多的训练集标签作为预测输出。
基本步骤:
这种分类方法基本分为3步:

  • 定义待分类样本与已分类样本之间的关系,本文中通过计算它们之间的距离实现
  • 筛选出距离最近的K个已分类样本(获得其分类标签)
  • 预测输出:从这K个样本中找出出现次数最多的类所对应标签,即为待分类样本所属的类标签

实际问题:在掌纹识别项目中,起初拟定的SVM分类器由于其算法的复杂性,model的训练和参数寻优需要较高的时间成本和硬件成本,最近邻分类器不失为一种简约高效的分类手段。
下面编写了MATLAB算法实现代码:

function [rec_rate,pre_label] = basicKNN(Traindata,Trainlabel,Testdata,Testlabel,k)
    % KNN algorithm implementation
    num_train = size(Traindata,1);
    num_test = size(Testdata,1);
    pre_label = zeros(num_test,1);
    for i = 1:num_test
        % Calculate Euclidean distance
        temp = repmat(Testdata(i,:),[num_train,1]);
        diff = Traindata - temp;
        % Extracting diagonal elements
        Euc_dist = sqrt(diag(diff*diff'));
        % Ascending order
        [~,index] = sort(Euc_dist);
        k_label = Trainlabel(index(1:k));
        % focus on the function tabulate
        table = tabulate(k_label);
        value = table(:,1);
        count = table(:,2);
        [~,ind] = max(count);
        pre_label(i) = value(ind);
    end
        Err = sum(predict ~= Testlabel);
        rec_rate = 1 - Err / length(Testlabel);
end

实验中每个手掌采集10张图片,原定7张作为训练集,3张作为测试集,取参数k=7,效果还挺好,其中求取欧式距离的时候通过矩阵略微简化了一下,使用了一个循环,好像还可以不通过循环实现,MATLAB中的tabulate在最后获得最高频次label的时候帮了不少忙(其实还是比较懒吧)

tabulate函数使用介绍
MATLAB如何获取向量中出现最多频次的数据?

1.tabulate(X)
%返回一个矩阵:第一列为元素值,第二列为相应元素出现个数,第三列为相应元素个数占所有元素个数百分比

>>X = [1 1 2 4];
>>tabulate(X)
    Value    Count    Percent
       1       2       50%
       2       1       25%
       3       0        0%
       4       1       25%        
posted @ 2020-03-08 20:06  别把梦弄脏  阅读(614)  评论(0)    收藏  举报