【Matlab】利用LIBSVM工具箱进行非线性分类
1.核函数介绍
分类问题不一定是线性可分的。要解决一个非线性分类问题,可以设法将其通过非线性变换,转化为高维空间中的线性问题,再在这个变换空间中求最优分类面。核函数就是为了完成非线性变换而产生的,常用的核函数有4种:多项式核函数、Gauss核函数、Sigmoid核函数、线性核函数等。
非线性支持向量机,可以用如下所示的结构图表示。它由一个三层的网络组成:输入层、中间层和输出层。输入层是输入样本向量,中间层是基于 S 个支持向量 Xi , i = 1, 2, …, S 的非线性变换,即核函数 K ( X , Xi ) 。输出层是决策规则 d ( X )。
2.实例
试采用核函数方法对下列数据进行非线性分类。
x = [5 10 20 50 100 120 150 200 250 300];
y = [526.9253 891.0675 1304.9097 1975.3134 2515.8623 2491.0713 689.7942 2741.6093 2715.6158 2822.6647];
z = [-1 -1 -1 -1 1 1 1 1 -1 -1];
其中,(x,y)代表二维的数据点,z表示相应点的类型属性。Matlab代码实现如下所示。
x = [5 10 20 50 100 120 150 200 250 300];
y = [526.9253 891.0675 1304.9097 1975.3134 2515.8623 2491.0713 689.7942 2741.6093 2715.6158 2822.6647];
z = [-1 -1 -1 -1 1 1 1 1 -1 -1];
N = 5;%前N个为训练数据
% 随机选定训练集和测试集
data = [x',y',z'];
rn = randperm(10);
randdata = data(rn,:);
train_set = randdata(1:N,1:2);
train_set_labels = randdata(1:N,3);
test_set = randdata(1+N:end,1:2);
test_set_labels = randdata(N+1:end,3);
% 数据预处理,将训练集和测试集归一化到[0,1]区间
[mtrain,ntrain] = size(train_set);
[mtest,ntest] = size(test_set);
dataset = [train_set;test_set];
[datast,ps] = mapminmax(dataset',0,1);% mapminmax为MATLAB自带的归一化函数
datast = datast';
train_set = datast(1:mtrain,:);
test_set = datast( (mtrain+1):(mtrain+mtest),: );
%% SVM网络训练
model = svmtrain(train_set, train_set_labels,'kernel_function', 'rbf');
%% SVM网络预测
[predict_label] = svmclassify(model,test_set);
%计算准确率
correctrate = sum(test_set_labels == predict_label)/size(test_set,1)
%% 结果分析
figure;
hold on;
plot(test_set_labels,'o');
plot(predict_label,'r*');
xlabel('测试集样本','FontSize',12);
ylabel('类别标签','FontSize',12);
title('测试集的实际分类和预测分类图','FontSize',12);
grid on;
实验结果:由于实验是随机选择5个样本作为训练数据,剩余另外5个样本作为测试数据,所以每次实验结果不一样,仅展示一次实验结果。
>> correctrate =
0.8000
实验发现,对于小样本的学习,选择不同的训练样本进行训练,导致测试的准确率相差较大。