本文已参与「新人创作礼」活动,一起开启掘金创作之路。
对于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);
运行结果:
% 训练样本蓝点,测试样红,错误的红星号,这里选的是两个
特征值大的对应的特征向量,所以错误率相对较小
选择数值比较小的特征值对应的特征向量进行投影:可以看错,分类效果很差
\