模式识别matlab实现PCA并用最近邻法将投影后的样本分类

143 阅读2分钟

​本文已参与「新人创作礼」活动,一起开启掘金创作之路。

 对于PCA(主成分分析)和最近邻法分类不了解的可以参考这位优秀博主的博客模式识别(Pattern Recognition)学习笔记(七)——线性分类器及线性判别函数_eternity1118_的博客-CSDN博客  在里面找他写的PCA和最近邻相关的博客。

这里贴下我写的笔记,觉得乱可以直接不看

接下来是matlab实现:

先说明已知数据格式:2,3,4,5行是一个样本的特征,第一行是表示属于第几类。前50个是第一类,51到100是第二类,101到150属于第三类。我们选每类的前25个做训练样本,后25个做测试样本。

%%
clear;clc;
fid = fopen('Iris.txt','r','n','UTF-8');
test1 = fopen('Iris.txt');
T2=textscan(test1,'%f%f%f%f%f','Delimiter',{':',';'});
Iris_Matri = [T2{1,2},T2{1,3},T2{1,4},T2{1,5}];
Iris_xun = [Iris_Matri(1:25,:);Iris_Matri(51:75,:);Iris_Matri(101:125,:)];
Iris_test =[Iris_Matri(26:50,:);Iris_Matri(76:100,:);Iris_Matri(126:150,:)];
S_cov = cov(Iris_xun);
[ eigen_matri,eigenvalue ]  = eig(S_cov,'nobalance');
%这里在D个特征中找d个特征,找大的,应该是用查找算法去写的,这里省事直接找了两个,
%而且需要按大小排好
eigenvalue_1 = [eigenvalue(4,4),eigenvalue(3,3)];
%求相应的d个特征向量
eigen_matri_1 = [eigen_matri(:,4),eigen_matri(:,3)];
%求训练样本投影
map_matri_xun = eigen_matri_1'*Iris_xun';
%求测试样本的投影
map_matri_test = eigen_matri_1'*Iris_test';
temp_vect = zeros(75,1);
temp = 0; temp_index = 0;
error = 0;
for i =1:75   %i表示第几个测试样本
    for j =1:75  %j代表了训练样本的下标
        temp_vect(j) =sqrt( ( map_matri_test(1,i)-map_matri_xun(1,j) )^2   + ( map_matri_test(2,i)-map_matri_xun(2,j) )^2  );
    end
    [temp,temp_index] = min(temp_vect);
    if(temp_index<25)
        fprintf('第%d个样本是第一类\n',i);
        if(i>25)
            error = error+1;
            flag =1;
        end
    elseif(temp_index<50  )
            fprintf('第%d个样本是第二类\n',i);
            if(i<=25 ||i>50)
                error = error+1;
                flag =1;
            end
    else
            fprintf('第%d个样本是第三类\n',i);
            if(i<=50)
                error = error+1;
                flag = 1;
            end
    end
    % 训练样本蓝点,测试样红,错误的红星号
    plot( map_matri_xun(1,i), map_matri_xun(2,i),'bo' );
    if(flag)
         plot( map_matri_test(1,i), map_matri_test(2,i),'rx' );
         flag =0;
    else
         plot( map_matri_test(1,i), map_matri_test(2,i),'ro' );
    end
    hold on;
end
fprintf('错误率为 %f%%',error*100/i);

运行结果:

 % 训练样本蓝点,测试样红,错误的红星号,这里选的是两个

特征值大的对应的特征向量,所以错误率相对较小

选择数值比较小的特征值对应的特征向量进行投影:可以看错,分类效果很差

\