一、实验目的
Iris数据集是常用的分类实验数据集,由Fisher, 1936收集整理。Iris也称鸢尾花卉数据集,是一类多重变量分析的数据集。数据集包含150个数据样本,分为3类,每类50个数据,每个数据包含4个属性。可通过花萼长度,花萼宽度,花瓣长度,花瓣宽度4个属性预测鸢尾花卉属于(Setosa,Versicolour,Virginica)三个种类中的哪一类。
实验的目的就是利用分类算法实现Iris数据集中三种不同品种的鸢尾花卉分类。通过学习近邻法的相关知识,我们使用k近邻分类算法对数据集进行分类。Iris数据集含有150个样本,我们将采用两种不同比例的训练集和测试集,并采用近邻分类算法实现Iris数据集的分类。实验过程所使用的编程软件为MATLAB仿真软件,利用MATLAB实现算法及分类。
二、实验内容
对鸢尾花数据集运用k最近邻分算法实现分类任务,并计算测试集准确率。
三、实验数据
在‘Iris.data’文件中,每一行代表一种鸢尾的样本,共有150个样本;一共5列,其中第5列为类别标志属性,共有3类,分别标记为‘1’、‘2’、‘3’,对于三种不同的鸢尾花;类别‘1’共有50个样本,类别‘2’共有50个样本,类别‘3’共有50个样本。
由于数据集中每个样本的数据都是完整的,没有空缺值,所以没有对该数据集进行必要的数据清洗工作。
四、实验要求
对程序作注示。数据划分:
划分1:每类随机选取40个样本用作训练,余下的10个样本用作测试;
划分2:每类随机选取25个样本用作训练,余下的25个样本用作测试。
注:实验报告需要附上每类训练样本和测试样本的序号。
3.对训练样本和测试样本分别选取两组不同的划分,同时匹配k的6种不同取值,即1、3、4、7、9。实验结果填入下表,并画实验结果的二维曲线图或柱形图(横坐标为k的取值,纵坐标为识别率)。
k取值 1 3 5 7 9 25 40 划分1识别率(%) 86.67 93.33 100.00 96.67 96.67 90.00 96.67 划分2 识别率(%) 97.33 94.67 94.67 98.67 98.67 90.67 89.33
4.收集上表的最佳结果,填入下表的相应位置,并画实验结果的二维曲线图或柱形图(横坐标为训练样本数(或划分方案),纵坐标为识别率)。
划分1 划分2 每类训练样本数 40 25 每类测试样本数 10 25 最高识别率(%) 100 98.67
5.根据实验结果作分析,在可能情况下,对所给的程序作修改和补充。
五、实验报告要求
项目报告(必须用给定的报告封面)(电子版和打印板)内容:
第一部分:近邻法的介绍,包括简单的现状和最近邻法和k 近邻法的原理;
第二部分:近邻法算法的流程图;
第三部分:代码+注示;
第四部分:结果和分析
3.格式参照模板
六、实验步骤
第一部分:近邻法的介绍,包括简单的现状和最近邻法和k-近邻法的原理;
(1)简单的现状:
近邻法包括最近邻法、k近邻法、剪辑近邻法和压缩近邻法。其属于分类算法,其中分类过程可看作是从数据集到一组类别的函数(映射),大致分为两个阶段:训练阶段和测试阶段。
(2)最近邻法和k-近邻法的原理:
k近邻法实际上就是近邻法的延伸,最近邻法的是k近邻法,k=1时的特例。其算法原理是先确定一个k值,然后计算所有样本点与已知训练样本之间的距离装入一个矩阵中,然后将这些距离再有小到大的进行排列。取得前k个值,然后距离最近的这前k个值,进行“多数表决”,即前k个距离中哪一类样本占多,就将未知样本分到该类中。当k=1时,该方法就称为最近邻法,相比k近邻法,最近邻法更加简单。在使用k近邻法将分类完成后,统计结果,分析训练样本中和测试样本中分类错误的个数,计算各自错误率,来分析对Iris数据进行近邻法分类编程是否有较好的可信度。
第二部分:近邻法算法的流程图
第三部分:代码+注示:主函数代码注释如下
%clear;
% for binary_case problem, in this procedure, Male is the first class; Female is the second class.
clear;clc %清除工作区所有变量为零,并清除命令行窗口的数据
t0=clock; %获取当前时间赋值给t0
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
load iris.data.txt %下载样本的数据集,每一行的前4个为特征值,最后一个为类别号
%iris_data=iris;
% partion the original data into two part, each part has the smae sample number.
z1=iris_data(:,1:4)'; %将数据集的前四列提取出来作为一个特征矩阵并将其转置为4行150列的矩阵
Class_Sample_NUM=50; %规定每个类别有50个样本
Class_NUM=3; %有三个类别
Dim=4; %定义矩阵有四个维度
Class_Train_NUM=25 % can be changed !!!!!!可以改变训练的样本数量
Class_Test_NUM=Class_Sample_NUM-Class_Train_NUM; %测试样本数等于每个类别的样本数减去训练样本数
Train_NUM=Class_Train_NUM*Class_NUM; %总的训练样本数等于每个训练样本数乘于类别数
Test_NUM=Class_Test_NUM*Class_NUM; %总的测试样本数等于每个测试样本数乘于类别数
Total_Sample_NUM=Class_NUM*Class_Sample_NUM; %总的样本数等于类别数乘于每个类别的样本数
China_char=zeros(Dim,Class_Sample_NUM,Class_NUM); %创建一个4×50×3的三维零矩阵
China_char(:,:,1)=z1(:,1:50); %将类别1的数据赋值给China_char的第一维
China_char(:,:,2)=z1(:,51:100); %将类别2的数据赋值给China_char的第二维
China_char(:,:,3)=z1(:,101:150); %将类别3的数据赋值给China_char的第三维
%======================
Train_DAT=zeros(Dim,Class_Train_NUM,Class_NUM); %创建一个4×Class_Train_NUM×3的零矩阵用来存储训练数据
Test_DAT=zeros(Dim,Class_Test_NUM,Class_NUM); %创建一个4×Class_Test_NUM×3的零矩阵用来存储测试数据
%[2 7 9 11 45 6 8 12 15 .....] %1~50 random
%a=randperm(50) %生成一个1~50的随机排列
for k=1:Class_NUM
a=randperm(50) %生成一个1~50的随机排列
%按照a的排序将该类别前Class_Train_NUM个样本作为训练数据集赋值给Train_DAT矩阵的第k维
Train_DAT(:,:,k)=China_char(:,a(1:Class_Train_NUM),k);
%按照a的排序将该类别剩余的样本作为测试数据集赋值给Test_DAT矩阵的第k维
Test_DAT(:,:,k)=China_char(:,a(Class_Train_NUM+1:Class_Sample_NUM),k);
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% testing
fprintf(' Recognition Accuracy:\n');
%Distance_mark : ['Euclidean', 'L2'| 'L1' | 'Cos']
Distance_mark='Euclidean'; %定义计算距离的方式为欧氏距离
K=40; %可以更改不同的距离值
%调用Classifier_K_NN_f()函数,输入训练和测试数据,以及计算距离的方式,输出错误的分类数量
Miss_NUM=Classifier_K_NN_f(Train_DAT,Test_DAT,K,Distance_mark);
%输出分类准确率
Recognition_rate=(Test_NUM-Miss_NUM)/Test_NUM;
Test_NUM %输出测试样本数
Miss_NUM %输出错误分类数量
Recognition_rate %输出正确率
etime(clock,t0)
Classifier_K_NN_f.m文件代码注释如下:
function Miss_NUM=Classifier_K_NN_f(Train_DAT,Test_DAT,K, Distance_mark)
% K-Nearest neighbor classifier
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
if nargin < 3, %异常处理
error('Not enought arguments!');
elseif nargin < 4 %参数小于4,选择L2范数
Distance_mark='L2'; %#ok
end
%取出Train_DAT和Test_DAT矩阵的行数、列数和维数
[DIM, Class_Train_NUM, Class_NUM]=size(Train_DAT);
[DIM, Class_Test_NUM, Class_NUM]=size(Test_DAT);
Train_NUM=Class_NUM*Class_Train_NUM; %计算出训练样本数
%返回与Train_DAT相同元素的DIM×Train_NUM维数组
Train_DAT=reshape(Train_DAT,[DIM,Train_NUM]);
if K>Train_NUM; %异常处理
K=Train_NUM; % note that K<=Train_NUM
end
%创建一个Class_Train_NUM×Class_NUM零矩阵
Train_Sample_Class_Index=zeros(Class_Train_NUM, Class_NUM);
for t=1:Class_NUM
Train_Sample_Class_Index(:,t)=t*ones(Class_Train_NUM,1);
end
Train_Sample_Class_Index=reshape(Train_Sample_Class_Index, [Train_NUM,1]);
% classification
Miss_NUM=0;
%计算欧氏距离
for k=1:Class_NUM
for m=1:Class_Test_NUM
Test=Test_DAT(:,m,k);
distance_V=zeros(Train_NUM,1);
for t=1:Train_NUM
Train=Train_DAT(:,t);
V=Test-Train;
switch Distance_mark
case {'Euclidean', 'L2'} %选择L2范数
dist=norm(V,2); % Euclead (L2) distance
case 'L1'
dist=norm(V,1); % L1 distance
case 'Cos'
dist=acos(Test'*Train/(norm(Test,2)*norm(Train,2))); % cos distance
otherwise
dist=norm(V,2); % Default distance
end
distance_V(t)=dist;
end
[sorted,neighborhood] = sort(distance_V,'ascend' );
First_K_Neighbors_Index_V= Train_Sample_Class_Index(neighborhood(1:K));
Class_Index_Count_V=histc(First_K_Neighbors_Index_V,1:Class_NUM);% histc(X,V) is to count the number of values in X falls within V
[Max_Val, Class_No]=max(Class_Index_Count_V);
if Class_No~=k % strncmp is to compare the first n characters of two strings
Miss_NUM=Miss_NUM+1;
end
end
end
第四部分:结果和分析:
(1)划分1:每类随机选取40个样本用作训练,余下的10个样本用作测试
当K=1, 每类训练样本和测试样本的序号有:
类别1:
训练序号=[ 46 11 40 26 8 19 49 10 7 50 15 23 28 31 44 34 32 1 48 38 16 22 29 47 24 17 25 4 12 30 39 27 45 33 21 3 6 14 5 2]
测试序号=[ 37 43 35 20 42 13 41 18 36 9]
类别2:
训练序号=[ 48 8 40 9 23 2 19 25 42 35 41 24 26 37 10 18 45 50 13 1 22 27 29 4 31 28 11 17 3 49 20 33 7 12 43 38 47 36 39 5]
测试序号=[ 6 15 21 46 14 44 30 32 34 16]
类别3:
训练序号=[2 10 25 38 14 11 23 17 35 37 19 49 21 24 7 15 44 46 4 29 40 41 5 3 9 13 28 26 39 16 50 33 30 31 42 45 32 27 36 12]
测试序号=[18 22 6 43 8 48 47 1 20 34]
同理当K=3,5,7,9,25,40时也会生成随机40个训练序号个10个测试序号。
(2)划分2:每类随机选取25个样本用作训练,余下的25个样本用作测试
当K=1, 每类训练样本和测试样本的序号有:
类别1:
训练序号=[ 32 10 19 48 45 49 24 29 13 15 31 50 22 23 21 38 33 1 16 6 14 47 30 17 37]
测试序号=[ 8 39 46 11 36 18 20 42 5 2 35 44 34 12 28 43 40 41 27 7 9 4 3 26 25]
类别2:
训练序号=[ 5 43 11 15 25 49 41 24 39 36 30 31 46 4 35 7 27 32 22 38 34 10 37 2 40]
测试序号=[ 47 16 50 6 48 44 23 17 28 42 20 12 1 18 3 19 21 45 13 9 33 8 29 14 26]
类别3:
训练序号=[ 28 50 25 14 39 38 13 2 20 9 15 49 40 7 45 44 35 26 23 36 6 27 41 31 30]
测试序号=[ 21 12 11 48 1 18 43 19 29 8 37 34 22 32 3 5 46 16 33 17 47 10 4 42 24]
同理当K=3,5,7,9,25,40时也会生成随机25个训练序号个25个测试序号。
得到结果如下:
k取值 1 3 5 7 9 25 40 划分1识别率(%) 86.67 93.33 100.00 96.67 96.67 90.00 96.67 划分2 识别率(%) 97.33 94.67 94.67 98.67 98.67 90.67 89.33
收集上表的最佳结果,填入下表的相应位置,并画实验结果的二维曲线图或柱形图(横坐标为训练样本数(或划分方案),纵坐标为识别率)。
划分1 划分2 每类训练样本数 40 25 每类测试样本数 10 25 最高识别率(%) 100 98.67
划分1的柱形图如下图1所示:
图1
划分2的柱形图如下图2所示:
图2
精彩链接
发表评论