一、实验目的

        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

精彩链接

评论可见,请评论后查看内容,谢谢!!!
 您阅读本篇文章共花了: