一、实验目的
熟练支持向量机的使用,掌握线性判别分析使用,以及 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);