基于MATLAB的SVM支持向量机的数据分类仿真,包括训练和测试

Posted fpga和matlab

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了基于MATLAB的SVM支持向量机的数据分类仿真,包括训练和测试相关的知识,希望对你有一定的参考价值。

up目录

一、SVM理论基础

二、核心程序

三、测试结果


一、SVM理论基础

         支持向量机(Support Vector Machine, SVM)是一类按监督学习(supervised learning)方式对数据进行二元分类的广义线性分类器(generalized linear classifier),其决策边界是对学习样本求解的最大边距超平面(maximum-margin hyperplane) 。
       SVM使用铰链损失函数(hinge loss)计算经验风险(empirical risk)并在求解系统中加入了正则化项以优化结构风险(structural risk),是一个具有稀疏性和稳健性的分类器 。SVM可以通过核方法(kernel method)进行非线性分类,是常见的核学习(kernel learning)方法之一 。

       SVM是由模式识别中广义肖像算法(generalized portrait algorithm)发展而来的分类器,其早期工作来自前苏联学者Vladimir N. Vapnik和Alexander Y. Lerner在1963年发表的研究。1964年,Vapnik和Alexey Y. Chervonenkis对广义肖像算法进行了进一步讨论并建立了硬边距的线性SVM 。此后在二十世纪70-80年代,随着模式识别中最大边距决策边界的理论研究 、基于松弛变量(slack variable)的规划问题求解技术的出现,和VC维(Vapnik-Chervonenkis dimension, VC dimension)的提出,SVM被逐步理论化并成为统计学习理论的一部分 。1992年,Bernhard E. Boser、Isabelle M. Guyon和Vapnik通过核方法得到了非线性SVM。1995年,Corinna Cortes和Vapnik提出了软边距的非线性SVM并将其应用于手写字符识别问题,这份研究在发表后得到了关注和引用,为SVM在各领域的应用提供了参考。

        基于支持向量机(Support Vector Machines,SVM)的训练学习算法,其主要原理是通过统计学理论,使得其具备以较少数量的训练数据样本来完成分类器的训练。而传统的基于神经网络的学习理论,往往需要较大数量的样本作为训练数据,因此传统的神经网络学习方法其对样本数量的依赖性较大。所以,采用SVM支持向量机的分类方法优于采用神经网络的分类方法。通过SVM支持向量机的分类算法,其首先需要对数据进行预处理,将维度较高的特征数据转换为低维度的特征数据,然后通过一个非线性映射函数产生一个对数据进行分割的超平面。因此,基于SVM支持向量机的分类算法,其本质是通过样本数据对非线性映射函数的训练和学习,从而得到适用于当前训练样本的非线性映射函数。根据实现非线性映射函数的不同方式,SVM可以分为线性可分和非线性可分两种类型。下面对这两种SVM的基本原理进行介绍。

 

 

 

二、核心程序

clc;
clear;
close all;
warning off;



%第一步:
%第一步:
%第一步:
%为了简化计算,可对得到的图像特征数据进行标准化
%将数据通过函数变换映射到[0.1,1]
%二元化0表示“非火”,1表示“火”
Data_nfire0 = xlsread('train\\data1.xls','Sheet1','A2:CL983');
Data_fire0  = xlsread('train\\data2.xls','Sheet1','A2:CL1257');
%火与非火的特征标签名称
[Data_nfire_tmp,Data_nfire_Name,alldata] = xlsread('train\\data1.xls','Sheet1','A1:CL1');
[Data_fire_tmp,Data_fire_Name,alldata]  = xlsread('train\\data2.xls','Sheet1','A1:CL1');
%特征的名称
Data_nfire_Name;
Data_fire_Name;

%由于数据量较大, 可以将特征序列适当的缩短
%进行标准化处理使其值域在0.1~1之间
%先进行归一化
Data_nfire1 = (Data_nfire0-min(min(Data_nfire0)))/(max(max(Data_nfire0))-min(min(Data_nfire0)));
Data_fire1  = (Data_fire0-min(min(Data_fire0)))/(max(max(Data_fire0))-min(min(Data_fire0)));
%进行映射,最好采用线性映射
Data_nfire2 = (Data_nfire1 + 1)/2;
Data_fire2  = (Data_fire1  + 1)/2;
%分别对火和非火数据进行标记1和0
[m1,n1]     = size(Data_nfire2);
Data_nfire3 = [Data_nfire2,zeros(m1,1)];
[m2,n2]     = size(Data_fire2);
Data_fire3  = [Data_fire2,ones(m2,1)];


%第二步:
%第二步:
%第二步:
%图像特征集合中信息特征的筛选:包括单因素方差分析和巴氏距离分析两个并行子模块。
%该步骤是数据进行初步筛选,剔除非信息特征,获得各自相应的信息特征,为下一步研究做铺垫。
%也就是说,假设某个特征对于火焰图像样本和干扰源图像样本的数据分析结果基本没有区别,
%那么则认为这个特征与火焰识别是无关的,将其归类为非信息特征中。
Len = min(m1,m2);
for i = 1:n1
    [p1,table1,stats1] = anova1([Data_nfire2(1:Len,i),Data_fire2(1:Len,i)]);
    [c1,m0,h1,gnames1] = multcompare(stats1); 
    Stds(i)            = c1(4);
    ppi              = abs(Stds(i));
    close all;
end
Stds_abs    = abs(Stds);
level       = mean(Stds_abs);
indexs      = find(Stds_abs < level);
Data_nfire4 = [Data_nfire3(:,indexs),Data_nfire3(:,end)];
Data_fire4  = [Data_fire3(:,indexs),Data_fire3(:,end)];

%将火每个特征的概率p保存到p.xls中
values  = Data_fire0(:,indexs);
headers = Data_fire_Name(indexs);
xlswrite('p1.xls', headers,'sheet1','A1');
xlswrite('p1.xls', values,'sheet1','A2');
%将非火每个特征的概率p保存到p.xls中
values  = Data_nfire0(:,indexs);
headers = Data_fire_Name(indexs);
xlswrite('p0.xls', headers,'sheet1','A1');
xlswrite('p0.xls', values,'sheet1','A2');






%巴氏距离分析.
for i = 1:n1
    bdistance(i) = func_bhattacharyya_distance(Data_nfire2(:,i),Data_fire2(:,i));
    pp2i       = bdistance(i);
end
level2      = mean(bdistance);
indexs2     = find(bdistance < level2);
Data_nfire5 = [Data_nfire3(:,indexs2),Data_nfire3(:,end)];
Data_fire5  = [Data_fire3(:,indexs2),Data_fire3(:,end)];

%将火每个特征的概率p保存到b.xls中
values  = Data_fire0(:,indexs2);
headers = Data_fire_Name(indexs2);
xlswrite('b1.xls', headers,'sheet1','A1');
xlswrite('b1.xls', values,'sheet1','A2');
%将非火每个特征的概率p保存到b.xls中
values  = Data_nfire0(:,indexs2);
headers = Data_fire_Name(indexs2);
xlswrite('b0.xls', headers,'sheet1','A1');
xlswrite('b0.xls', values,'sheet1','A2');




%取他们的交集,从而获得代表非火的特征序列
p = 0;
for i = 1:length(indexs)
    for j = 1:length(indexs2)
        if indexs(i) == indexs2(j)
           p = p + 1;
           indexs0(p) = indexs(i);
        end
    end
end
Data_nfire6 = [Data_nfire3(:,indexs0),Data_nfire3(:,end)];
Data_fire6  = [Data_fire3(:,indexs0),Data_fire3(:,end)];

%将火和非火的交集分别保存到pb1.xls中和pb0.xls中
headers_tmp = Data_fire_Name(indexs0);
xlswrite('pb.xls',headers_tmp);
%将标签转换为标号,同时写入到xls文件中
headers_tmp1 = indexs0;
values1      = Data_fire2(:,indexs0);
xlswrite('pb1.xls',[headers_tmp1;values1]);

headers_tmp0 = indexs0;
values0      = Data_nfire2(:,indexs0);
xlswrite('pb0.xls',[headers_tmp0;values0]); 







 
%第三步:
%第三步:
%第三步:
%K均值聚类与有效特征子集的生成:包括K均值聚类子模型和主特征选择子模型。
%该步骤对上一步骤的结果做进一步处理,产生多个有效特征子集。
Is_fire_0 = values0;
Is_fire_1 = values1;
 
Cluster_Num = 4;
%对非火数据计算得到了四类不同特征的特征集合 
Data        = Is_fire_0(:,1:end-1);
[row,col]   = size(Data);
Step        = 100;
%将特征数据分为4类,每类表示不同的特征值域
%聚类中心的初始化
Center      = Data(:,1:Cluster_Num);
%进行初始的迭代
[KindData,KindNum] = func_Kmeans_Cluster(Center,Data);
NewCenter          = func_NewCenter(KindData,KindNum,row);
while (sum(sum(NewCenter ~= Center))) & Step
    Center             = NewCenter;
    [KindData,KindNum] = func_Kmeans_Cluster(Center,Data);
    NewCenter          = func_NewCenter(KindData,KindNum,row);
    Step               = Step-1;
end

%对非火数据计算得到了四类不同特征的特征集合 
Is_fire_0_feature = KindData;

 





%对火数据计算得到了四类不同特征的特征集合 
Data        = Is_fire_1(:,1:end-1);
[row,col]   = size(Data);
Step        = 100;
%将特征数据分为4类,每类表示不同的特征值域
%聚类中心的初始化
Center      = Data(:,1:Cluster_Num);
%进行初始的迭代
[KindData,KindNum] = func_Kmeans_Cluster(Center,Data);
NewCenter          = func_NewCenter(KindData,KindNum,row);
while (sum(sum(NewCenter ~= Center))) & Step
    Center             = NewCenter;
    [KindData,KindNum] = func_Kmeans_Cluster(Center,Data);
    NewCenter          = func_NewCenter(KindData,KindNum,row);
    Step               = Step-1;
end

%对非火数据计算得到了四类不同特征的特征集合 
Is_fire_1_feature = KindData;

 

 
%获得特征数据中的非0值
for ii = 1:Cluster_Num
    tmp0              = Is_fire_0_feature(:,:,ii);
    tmp0s             = tmp0(tmp0~=0);   
    Feature_0ii     = tmp0s;
    clear tmp0 tmp0s
end 

for ii = 1:Cluster_Num
    tmp1              = Is_fire_1_feature(:,:,ii);
    tmp1s             = tmp1(tmp1~=0);   
    Feature_1ii     = tmp1s;
    clear tmp1 tmp1s
end

%处理,获得非0部分,即所需要的特征值
for j = 1:Cluster_Num
    IND0 = min(find(Is_fire_0_feature(1,:,j) == 0))-1;
    IND1 = min(find(Is_fire_1_feature(1,:,j) == 0))-1;

    Final_Fire0j = Is_fire_0_feature(:,1:IND0,j);
    Final_Fire1j = Is_fire_1_feature(:,1:IND1,j);
end

%将每个特征对应的名称保存到K1.xls和K0.xls这两个文件中
Name0 = func_find_name(Data_nfire2,n1,Cluster_Num,Final_Fire0);
Name1 = func_find_name(Data_fire2 ,n2,Cluster_Num,Final_Fire1);

%将分类后的类别保存到XLS文件中
headers_tmp = Data_fire_Name(Name01);
xlswrite('K01.xls',headers_tmp);
headers_tmp = Data_fire_Name(Name02);
xlswrite('K02.xls',headers_tmp);
headers_tmp = Data_fire_Name(Name03);
xlswrite('K03.xls',headers_tmp);
headers_tmp = Data_fire_Name(Name04);
xlswrite('K04.xls',headers_tmp);

headers_tmp = Data_fire_Name(Name11);
xlswrite('K11.xls',headers_tmp);
headers_tmp = Data_fire_Name(Name12);
xlswrite('K12.xls',headers_tmp);
headers_tmp = Data_fire_Name(Name13);
xlswrite('K13.xls',headers_tmp);
headers_tmp = Data_fire_Name(Name14);
xlswrite('K14.xls',headers_tmp);


%第四步:
%第四步:
%第四步:
%使用支持向量机和神经网络以及统计方法对上面的多个特征子集合进行识别仿真,得到效果最NB的特征子集
%将分组后的火特征数据以及非火特征数据组合成一个数据,然后再加入1和0的标志位进行训
%由于Final_Fire0,Final_Fire1是MXN类型的数据,所以将其转换为1XM的数据



for k = 1:Cluster_Num
    [ms,ns]        = size(Final_Fire0k);
    Feature_0sk  = (reshape(Final_Fire0k,1,ms*ns))';
end
for k = 1:Cluster_Num
    [ms,ns]        = size(Final_Fire1k);
    Feature_1sk  = (reshape(Final_Fire1k,1,ms*ns))';
end
for k = 1:Cluster_Num
    datak   = [Feature_1sk;Feature_0sk];%由于每一个子集的特征向量的行列均不同,因此将同一子集的数据合并为一个一维的数据
                                              %然后对每一列新的特征数据集合进行标志,进行下一步的计算
    Targetk = [ones(length(Feature_1sk),1);-1*ones(length(Feature_0sk),1)];
end

% SVM
% %注意,采用支持向量机的方法,这里由于数据量较大,普通计算机无法处理,故直接采用神经网络和统计的方法分析识别率
% C       = 0.1719;
% ker     = struct('type','linear');
% svm     = svmTrain('svc_c',datak,Targetk,ker,C); 



%神经网络
%首先使用设计网络的方法对四个特征子集合进行训练
for k = 1:Cluster_Num
    t1                      = clock;                              %计时开始
    net                     = fitnet(33);
    net.trainParam.epochs   = 5000;                               %设置训练次数
    net.trainParam.goal     = 0.05;                               %设置性能函数
    net.trainParam.show     = 1;                                  %每10显示
    net.trainParam.Ir       = 0.05;                               %设置学习速率
    net                     = train(net,(datak)',(Targetk)'); %训练BP网络
    datat                   = etime(clock,t1);
    Netsk                 = net;
end


for k = 1:Cluster_Num
    view(Netsk);
end
%进行测试
for k = 1:Cluster_Num
    net       = Netsk;
    Resultk = sim(net,(datak)');  
end
figure;
subplot(221);plot(Result1);
subplot(222);plot(Result2);
subplot(223);plot(Result3);
subplot(224);plot(Result4);

%计算识别率
thershold = 0.5;%识别率误差门限
tmp       = 0;
rates     = zeros(Cluster_Num,1);
for k = 1:Cluster_Num
    for j = 1:length(Resultk)
        if abs(Resultk(j) - Targetk(j)) <= abs(thershold*Targetk(j))
           tmp      = tmp + 1;
           rates(k) = tmp;
        else
           tmp      = tmp;
           rates(k) = tmp;           
        end
    end
    rates(k) = rates(k)/length(Resultk);
    tmp      = 0;
end

disp('识别率为:');
rates'

[Max_value,Max_index] = max(rates);

disp('最佳的特征子集合为:第');
Max_index
disp('集合');


headers_tmp0 = Name0Max_index;
values0      = Data_nfire0(:,Name0Max_index);
xlswrite('best0.xls',[headers_tmp0;values0]); 

headers_tmp1 = Name1Max_index;
values1      = Data_fire0(:,Name1Max_index);
xlswrite('best1.xls',[headers_tmp1;values1]); 
%显示出具体的名称
Best_Name0 = Data_nfire_Name(headers_tmp0);
Best_Name1 = Data_fire_Name(headers_tmp1);



%统计模型
thershold = 0.01;%识别率误差门限
tmp       = 0;
rates     = zeros(Cluster_Num,1);
for k = 1:Cluster_Num
    for j = 1:length(Resultk)
        if abs((datak(j)-mean(datak)) * Targetk(j)) <= abs(thershold*Targetk(j))
           tmp      = tmp + 1;
           rates(k) = tmp;
        else
           tmp      = tmp;
           rates(k) = tmp;           
        end
    end
    rates(k) = rates(k)/length(Resultk);
    tmp      = 0;
end

disp('识别率为:');
rates'

[Max_value,Max_index] = max(rates);

disp('最佳的特征子集合为:第');
Max_index
disp('集合');


headers_tmp0 = Name0Max_index;
values0      = Data_nfire0(:,Name0Max_index);
xlswrite('best0.xls',[headers_tmp0;values0]); 

headers_tmp1 = Name1Max_index;
values1      = Data_fire0(:,Name1Max_index);
xlswrite('best1.xls',[headers_tmp1;values1]); 
%显示出具体的名称
Best_Name0 = Data_nfire_Name(headers_tmp0);
Best_Name1 = Data_fire_Name(headers_tmp1);
up84

三、测试结果

通过matlab2021a仿真结果如下:

 步骤如下:

基于MATLAB的SVM支持向量机的数据分类,包括训练,测试,以及数据库 B.程序实现流程:

第一步: 为了简化计算,可对得到的图像特征数据进行标准化 将数据通过函数变换映射到[0.1,1]

第二步: 图像特征集合中信息特征的筛选:包括单因素方差分析和巴氏距离分析两个并行子模块。 该步骤是数据进行初步筛选,剔除非信息特征,获得各自相应的信息特征,为下一步研究做铺垫。也就是说,假设某个特征对于火焰图像样本和干扰源图像样本的数据分析结果基本没有区别,那么则认为这个特征与火焰识别是无关的,将其归类为非信息特征中。

第三步: K均值聚类与有效特征子集的生成:包括K均值聚类子模型和主特征选择子模型。该步骤对上一步骤的结果做进一步处理,产生多个有效特征子集。

第四步: 使用支持向量机和神经网络以及统计方法对上面的多个特征子集合进行识别仿真,得到效果最NB的特征子集。将分组后的火特征数据以及非火特征数据组合成一个数据,然后再加入1和0的标志位进行训由于Final_Fire0,Final_Fire1是MXN类型的数据,所以将其转换为1XM的数据

以上是关于基于MATLAB的SVM支持向量机的数据分类仿真,包括训练和测试的主要内容,如果未能解决你的问题,请参考以下文章

基于SVM支持向量机的车牌分割识别算法matlab仿真——详细版

基于SVM支持向量机的车牌分割识别算法matlab仿真

基于SVM支持向量机和HOG特征的交通标志检测算法matlab仿真

基于CIFAR10图像数据集和SVM的图像分类算法matlab仿真

SVM基于matlab的SVM支持向量机训练和测试仿真

FPGA教程案例94机器学习1——基于FPGA的SVM支持向量机二分类系统实现之理论和MATLAB仿真