图像识别5:LDA 与 SVM+神经网络+支持向量机实验
写在最前面
图像识别1:基于相似性度量的二分类实验
图像识别2:图像多分类实验
图像识别3:梯度下降和LDA线性模型实验
图像识别4:决策树+神经网络GUI+支持向量机实验
图像识别5:LDA 与 SVM+神经网络+支持向量机实验
图像识别6:综合
一、实验目的
熟练支持向量机的使用,掌握线性判别分析使用,以及 knn、k-means 聚类的使用方法。
二、 实验内容及结果
1、实验十一——线性判别分析 LDA 与支持向量机 SVM 的综合实验
(1) 根据多类人脸图,实现线性判别分析,求得投影矩阵 W;
(2) 将 W 作用在测试样本上,画出测试样本在投影后的分布图。(d’=2);
(3) 根据投影后的训练数据和测试数据,使用支持向量机获得分类精度;
(4) 找出使得支持向量机分类精度最高的 d’。
2、实验十二——KNN 分类器与支持向量机的对比实验
(1) 选取合适的数据集,进行训练集和测试集的划分;
(2) 使用支持向量机进行分类,分析参数的影响;
(3) 使用 KNN 分类器进行分类,分析参数的影响;
(4) 对比两种分类器的最优分类精度。
3、实验十三——K-means 聚类算法实验
(1)使用 k-means 聚类完成三维高斯分布数据的分类,以及结果可视化;
(2)使用 k-means 聚类实现鸢尾花数据的分类。
(1)LDA与SVM
读取和划分与实验十一样,因此直接读取数据集。
根据多类人脸图,实现LDA线性判别分析,求得投影矩阵 W。
结果可视化。这里首先取三原色随机数,然后通过eval函数调用不同的变量值。
取随机颜色的代码理论是生成3*40个点,40种不同的颜色每种颜色3个点,但由于’color’,[range,range,range]存在取到相同颜色的情况,因此看不出LDA降维后测试集的标签结果。尝试通过randperm函数强制让他取到不同的颜色。
可以看出,分类结果较好,颜色一样的基本都在一团
>> plot(mappedX(temp1,1),mappedX(temp1,2),'*','MarkerFaceColor',[c(1),d(1),e(1)])
>> plot(mappedX(temp2,1),mappedX(temp2,2),'*','MarkerFaceColor',[c(1),d(1),e(1)])
>> plot(mappedX(temp3,1),mappedX(temp3,2),'*','MarkerFaceColor',[c(1),d(1),e(1)])
读取数据集后对分类精度d’遍历,以找到最高的精度。
降维后导入支持向量机。
(2)KNN和支持向量机
选取的数据集为实验五的MIT室内场景数据集。使用支持向量机对其进行分类时,主要考虑参数’-s’svm类型和’-t’损失函数类型对分类精度的影响,对-s和-t参数循环取值为1到4。
可视化绘图。
使用 knn 对其进行分类,参数 k 取 1到10。
可视化绘图。
(3)Kmean聚类
使用高斯函数生成三维高斯的分布数据。
其他三类数据同理。
生成三维高斯分布数据并可视化。
中心点可视化。
可视化。
原来可视化的代码如下:
改进:将一维矩阵的eval函数改进为二维矩阵,读写速度更快且更方便。
将 iris 数据集导入后,使用 k-means 聚类对其进行分类。对于分类的每个类别,将其与原数据的类别进行对比,选取聚类类别个数的最多的为标准,将其作为这一项的分类类别。
准确率为88.666667%。
三、实验心得
通过本次实验,熟练支持向量机的使用,掌握线性判别分析使用,以及 knn、k-means 聚类的使用方法。通过实验发现了学习率的知识盲点,通过查阅文献及课本及时进行了查缺补漏。对数学与编程的应用中有了更深的理解,和同学交流后,代码的时空复杂度降低,并且复用性得到了较大的提升。
四、实验源码
实验十一:线性判别分析 LDA 与支持向量机 SVM
% 1.根据多类人脸图,实现线性判别分析,求得投影矩阵W 。
% 2.将W作用在测试样本上,画出测试样本在投影后的分布图。(d’=2)
% 3.根据投影后的训练数据和测试数据,使用支持向量机获得分类精度。
% 4.找出使得支持向量机分类精度最高的d’。
%% 设置参数
clc;clear;close all;
warning('off') %关掉警告
base_path = 'D:\Desktop\大三上\神经网络\11\ORL人脸库';
path = string();
subpath = dir( base_path );
a=10; %留出法次数
%% 读取指定路径单文件夹下,all文件夹内的all图像
all_imgnum=0;all_e=0;all_f=0;
for i = 1:length(subpath)-2 % 读取单文件夹下,all文件夹% 1,2分别是.和..% 先获取第一个子文件路径,然后获取第二个子文件路径
sub_path = fullfile(base_path, subpath(i+2).name);% disp(sub_path); % D:\Desktop\大三上\神经网络\11\ORL实验\s12
image_name = dir([sub_path,'\*.bmp']); % 获取文件夹里的所有.bmp格式图像信息% disp(image_name(1).name); % 1.bmp
img_num=length(image_name); % 文件夹里图像个数% disp(img_num); %
all_imgnum=all_imgnum+img_num;% disp(all_imgnum); % 608 1013 1210 1872
e=round(img_num*2/3); % 留出法划分比例
f=img_num-e;
all_e=all_e+e;
all_f=all_f+f;
%% 获取图片数据
for j = 1:img_num % 获取子文件夹下图片的路径
% fullfile函数利用文件各部分信息创建并合成完整文件名
img_path = fullfile(sub_path, image_name(j).name); % 子文件夹+图片名称
read_img = imread(img_path); % 读图
if(ndims(read_img)==3)
read_img = rgb2gray(read_img); % RGB图像转灰度图像
end
image = double(imresize(read_img, [1,2000])); % 图片统一大小,指定长宽[1,2000]
phi(all_imgnum-img_num+j,:)=image; % 存放每个图片data于phi矩阵中,一行存放一个图像
end
end
%% 留出法a次二划分互斥的训练集和测试集 数据
for k=1:a
c=1;d=1;
for m=1:length(subpath)-2
% 划分训练集和测试集比例(2:1划分)
num=randperm(img_num); %打乱列序列
train_num=num(1:e); %取打乱序列的前60%
test_num=num(e+1:end); %取打乱序列的后40% %end直到数组结尾
% 划分数据
for ai=1:length(train_num)
phi0(c,:)=phi((m-1)*img_num+train_num(ai),:);
c=c+1;
end
for bi=1:length(test_num)
phi1(d,:)=phi((m-1)*img_num+test_num(bi),:);
d=d+1;
end
%% 存放图片训练集label于矩阵Ltrain % 定义标签,1234
Ltrain(1,c-length(train_num):c-1)=m*ones(1,length(train_num));% 行拼接每个标签给对应的图片个数拼成一行
Ltest(1,d-length(test_num):d-1)=m*ones(1,length(test_num));
end
Xtrain{1,k}=phi0;%第k次留出法的训练集
Xtest{1,k}=phi1;
end
%% 保存划分后的数据集
save('Xtrain11.mat','Xtrain'); % 存数据
save('Xtest11.mat','Xtest');
save('Ltrain11.mat','Ltrain');% 存标签
save('Ltest11.mat','Ltest');
%% 2.将W作用在测试样本上,画出测试样本在投影后的分布图。(d’=2)
%% 读取数据集
clear;clc
load Xtrain11.mat
load Xtest11.mat
load Ltrain11.mat
load Ltest11.mat
a=size(Xtrain);
a1=a(2);
% 绘图点的颜色取三原色随机数
c=randperm(1000,40)/1000; % 取40个[0,1]之间不重复的随机数
d=randperm(1000,40)/1000;
e=randperm(1000,40)/1000;
for i = 1:a1
% xtrain=Xtrain(1,i);
xtest=cell2mat(Xtest(1,i)); % 元胞数组转化为矩阵
xtrain=cell2mat(Xtrain(1,i));
b=size(xtest);
figure(i)
%% LDA多分类
[mappedX1,mapping1,W]=FisherLDA2(xtrain,Ltrain,2); %xtrain:120*2000double W:2000*2double
mappedX=xtest*W;
%% 结果可视化
for k = 1:40 %40种标签
eval(['temp',num2str(k),'=','find(Ltest==k)','''']); %自动给变量赋名和赋值 [1;2;3]
plot(mappedX(eval(['temp',num2str(k)]),1),mappedX(eval(['temp',num2str(k)]),2),'*','MarkerFaceColor',[c(k),d(k),e(k)])
hold on
end
end
%% 4.找出使得支持向量机分类精度最高的d’。
% 读取数据集
clear;clc
load Xtrain11.mat
load Xtest11.mat
load Ltrain11.mat
load Ltest11.mat
a=size(Xtrain);
a1=a(2);
d = 1:50;
for j=1:length(d)
for i = 1:a1
% xtrain=Xtrain(1,i);
xtest=cell2mat(Xtest(1,i)); % 元胞数组转化为矩阵
xtrain=cell2mat(Xtrain(1,i));
%% LDA多分类
[mappedX1,mapping1]=lda222(xtrain,Ltrain,d(j)); %xtrain:120*2000double W:2000*2double
mappedX=xtest*mapping1.M;
%% 3.根据投影后的训练数据和测试数据,使用支持向量机获得分类精度。
svmStruct = svmtrain(Ltrain',mappedX1,['-s '+ 1,'-g'+1]);
[prelabel,accuracy,decision_values]=svmpredict(Ltest',mappedX,svmStruct); %预测 1*120 120*2
accuracy1(i)=accuracy(1)/100;
end
acc(j)=mean(accuracy1);
end
disp(acc);
plot(d,acc,'-*b')
axis([0 50 0 1]) % 设置坐标格
grid on;
set(gca,'FontSize',15); xlabel('t','fontsize',17); % 设置字体格式
ylabel('分类精度','fontsize',17);
title('精度曲线图');
实验十二:支持向量机与KNN
%% 1.选取合适的数据集,进行训练集和测试集的划分。
% 根据两类人脸图,实现二分类实验
clc;clear;close all;
warning('off') %关掉警告
base_path = 'D:\Desktop\大三上\机器学习\10\人脸图';
path = string();
subpath = dir( base_path );
%% 训练阶段
%读取样本并计算hog特征
all_imgnum=0;
for i = 1:length(subpath)-2 % 读取单文件夹下,all文件夹% 1,2分别是.和..% 先获取第一个子文件路径,然后获取第二个子文件路径
sub_path = fullfile(base_path, subpath(i+2).name);% disp(sub_path); % D:\Desktop\大三上\神经网络\数据\MIT室内场景\airport_inside
image_name = dir(sub_path); % 获取文件夹里的所有图像信息% disp(image_name(3).name); % airport_inside_0001.jpg
img_num=length(image_name)-2; % 文件夹里图像个数% disp(img_num); % 608 405 197 662
all_imgnum=all_imgnum+img_num;% disp(all_imgnum); % 608 1013 1210 1872
%% 获取图片数据
for j = 1:img_num % 获取子文件夹下图片的路径
% fullfile函数利用文件各部分信息创建并合成完整文件名
img_path = fullfile(sub_path, image_name(j+2).name); % 子文件夹+图片名称
read_img = imread(img_path); % 读图
image = imresize(read_img, [64,64]); % 图片统一大小,指定长宽[64,64]
if(ndims(read_img)==3)
read_img = rgb2gray(read_img); % RGB图像转灰度图像
end
hog =hogcalculator(image);
data(all_imgnum-img_num+j,1:1764)=hog;
end
% 存放图片label % 定义标签,0:负样本 1:正样本
label(all_imgnum-img_num+1:all_imgnum,1)=(i-1)*ones(img_num,1);
end
%% 2.使用支持向量机进行分类,分析参数的影响。
for i = 1:5
[m,n]=size(data);
%[Train, Test] = crossvalind('LeaveMOut',N, M);
% 该命令返回一个逻辑值的标记向量,从N个观察样本中随机选取M个样本作为测试集。M的缺省值为1。值得注意的是,LeaveMOut在循环中使用不能保证产生的是互补集合,即每次循环的随机选取是独立的。如果要用互补的话还是使用Kfold命令。
[train,test]=crossvalind('LeaveMOut',m,10);
svmStruct = svmtrain(label(train),data(train,:),['-s '+ 4,'-v'+10,'-t'+i-1]);
[prelabel,accuracy,decision_values]=svmpredict(label(test),data(test,:),svmStruct); %预测
accuracy1(i)=accuracy(1)/100;
end
subplot(2,1,1); % top subplot
x=[1:5];
plot(x,accuracy1,'-*b')
axis([0 5 0 1])
% 设置坐标格
grid on;
% 设置字体格式
set(gca,'FontSize',15); xlabel('t','fontsize',17);
ylabel('分类精度','fontsize',17);
title('svm精度曲线图1');
%% 3.使用KNN分类器进行分类,分析参数的影响。
for k = 1:5
[m,n]=size(data);
[train,test]=crossvalind('LeaveMOut',m,10);
[Class] = cvKnn(data(test,:)', data(train,:)', label(train)',k);
count = 0;labeltest=label(test);
for i = 1:length(Class)
if(Class(i)==labeltest(i))
count = count + 1;
end
end
accs(k) = count / length(labeltest);
end
subplot(2,1,2);
plot([1:5],accs,'-*r');
axis([0 5 0 1])
% 设置坐标格
grid on;
% 设置字体格式
set(gca,'FontSize',15); xlabel('t','fontsize',17);
ylabel('分类精度','fontsize',17);
title('cvKnn精度曲线图2');
实验十三:k-means聚类
%% 1、使用k-means聚类完成三维高斯分布数据的分类,以及结果可视化;
%% 生成三维高斯分布数据
% data = generate_data_GMM(3, 1, 10, 1, 1);
data = generate_GMM(); %三类数据
%% 分类
d = data(:,1:3);
N = 3; %数据一共分3类
[u re] = kmeans(d, N);
%% 可视化
% 绘图点形状
b = ['s','^','o','d','p','h','<'];
% 绘图点的颜色取三原色随机数
c=randperm(1000,40)/1000; % 取40个[0,1]之间不重复的随机数
d=randperm(1000,40)/1000;
e=randperm(1000,40)/1000;
% 中心点可视化
for i = 1:length(u)
scatter3(u(i,1),u(i,2),u(i,3),'MarkerFaceColor','red','LineWidth',5,'MarkerEdgeColor','r');
hold on;
end
% 表明中心点位置
text(u(:,1),u(:,2),u(:,3), '中心点', 'fontsize', 15);
% 数据可视化
for i = 1:length(re)
for j = 1:N
if(re(i,4)==j)
scatter3(re(i,1),re(i,2),re(i,3),b(j),'filled','MarkerFaceColor',[c(j) d(j) e(j)]);
hold on;
end
end
end
%% 2、使用k-means聚类实现鸢尾花数据的分类;
clear;clc
load iris.mat;
d2 = iris(:,1:4);
iris(1:50,5)=1;
iris(51:100,5)=2;
iris(101:150,5)=3;
l = iris(:,5);
classes = ['Iris-setosa','Iris-versicolor','Iris-virginica'];
N = 3;
[u1 re] = kmeans(d2, N);
sum2 = 0;
a1 = zeros(2,3);
for j = 1:3
a1 = tabulate(re(50*(j-1)+1:50*j,5));
b1 = (a1(:,2))
sum2 = sum2 + max(b1);
end
fprintf("准确率为%f%%",sum2/150*100);