【libsvm】svm实例(一)
来源:
BreastTissue_classify_matlab: 使用libsvm进行分类 (github.com)
使用的一般步骤
1 )按照 LIBSVM 软件包所要求的格式准备数据集;
2 )对数据进行简单的缩放操作;
3 )首要考虑选用 RBF 核函数;
4 )采用交叉验证选择最佳参数 C 与 g ;
5 )采用最佳参数 C 与 g 对整个训练集进行训练获取支持向量机模型;
6 )利用获取的模型进行测试与预测。
一、数据
BreastTissue_data.mat
这里给出了106个数据, 每一个数据都有9个特征和一个分类标签;用这些数据来生成测试集和训练集, 得到模型并且测试、分类。
label:1、2、3、4、5、6
二、代码流程
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 | %% I. 清空环境变量 clear all clc %% II. 导入数据 load BreastTissue_data.mat %% % 1. 随机产生训练集和测试集 n = randperm ( size (matrix,1)); %% % 2. 训练集——80个样本 train_matrix = matrix(n(1:80),:); train_label = label(n(1:80),:); %% % 3. 测试集——26个样本 test_matrix = matrix(n(81: end ),:); test_label = label(n(81: end ),:); %% III. 数据归一化 [Train_matrix,PS] = mapminmax(train_matrix'); Train_matrix = Train_matrix'; Test_matrix = mapminmax( 'apply' ,test_matrix',PS); Test_matrix = Test_matrix'; %% IV. SVM创建/训练(RBF核函数) %%参数 % 1. 寻找最佳c/g参数——交叉验证方法 [c,g] = meshgrid (-10:0.2:10,-10:0.2:10); [m,n] = size (c); cg = zeros (m,n); eps = 10^(-4); v = 5; bestc = 1; bestg = 0.1; bestacc = 0; for i = 1:m for j = 1:n cmd = [ '-v ' , num2str (v), ' -t 2' , ' -c ' , num2str (2^c( i , j )), ' -g ' , num2str (2^g( i , j ))]; cg( i , j ) = svmtrain(train_label,Train_matrix,cmd); if cg( i , j ) > bestacc bestacc = cg( i , j ); bestc = 2^c( i , j ); bestg = 2^g( i , j ); end if abs ( cg( i , j )-bestacc )<= eps && bestc > 2^c( i , j ) bestacc = cg( i , j ); bestc = 2^c( i , j ); bestg = 2^g( i , j ); end end end cmd = [ ' -t 2' , ' -c ' , num2str (bestc), ' -g ' , num2str (bestg)]; %% % 2. 创建/训练SVM模型 model = svmtrain(train_label,Train_matrix,cmd); %% V. SVM仿真测试 [predict_label_1,accuracy_1,prob_estimates] = svmpredict(train_label,Train_matrix,model); [predict_label_2,accuracy_2,prob_estimates2] = svmpredict(test_label,Test_matrix,model); result_1 = [train_label predict_label_1]; result_2 = [test_label predict_label_2]; %% VI. 绘图 figure plot (1: length (test_label),test_label, 'r-*' ) hold on plot (1: length (test_label),predict_label_2, 'b:o' ) grid on legend ( '真实类别' , '预测类别' ) xlabel ( '测试集样本编号' ) ylabel ( '测试集样本类别' ) string = { '测试集SVM预测结果对比(RBF核函数)' ; [ 'accuracy = ' num2str (accuracy_2(1)) '%' ]}; title (string) |
结果:
参数
输入:
cmin,cmax: 惩罚参数c的变化范围,在[2^cmin,2^cmax]范围内寻找最佳的参数c,默认值为cmin=-8,cmax=8。
gmin,gmax: RBF核参数g的变化范围,在[2^gmin,2^gmax]范围内寻找最佳的RBF核参数g,默认值为gmin=-8,gmax=8。
v:对训练集进行v-fold Cross Validation,默认为3。
cstep,gstep:进行参数寻优是c和g的步进大小,默认取值为cstep=1,gstep=1。
accstep:最后参数选择结果图中准确率离散化显示的步进间隔大小([0,100]之间的一个数),默认为4.5。
输出:
bestCVaccuracy:最终CV意义下的最佳分类准确率。
bestc:最佳的参数c。
bestg:最佳的参数g。
三、常用的几个概念:
1.归一化函数(mapminmax)
(1)[Y,PS] = mapminmax(X,YMIN,YMAX)
其中,YMIN是我们期望归一化后矩阵Y每行的最小值,YMAX是我们期望归一化后矩阵Y每行的最大值。
(2)[Y,PS] = mapminmax(X,FP)
FP是一个结构体成员,主要是FP.ymin(相当于YMIN), FP.ymax(相当于YMAX)。1和2处理效果一样,只不过参数的带入形式不同。
(3)Y = mapminmax('apply',X,PS)
PS是训练样本的映射,测试样本的预处理方式应与训练样本相同。只需将映射PS apply到测试样本。
(4)X = mapminmax('reverse',Y,PS)
将归一化后的Y反转为归一化之前
(5)dx_dy = mapminmax('dx_dy',X,Y,PS)
2.交叉验证(Cross-validation)
交叉验证将原始数据集分为两组,分别作为训练集和验证集。训练集用于训练模型,验证集用于评价训练模型的性能指标。
参数寻优的意义:参数的数值决定着模型的性能。
采用交叉验证方法保障验证数据集没有参与过模型的训练,可以给出较为准确的参数寻优结果。
几种常用交叉验证(cross validation)方式的比较【python】
优化算法有很多,如网格搜索算法、遗传算法、粒子群算法、蚁群算法、模拟退火算法等。
交叉验证来说,我们采取的是网格搜索算法,即在参数的一定的范围内,按照指定的步长对不同的参数进行排列组合,将每一组参数组合进行测试,取性能指标最优的那一组参数作为最终参数的值。如本例中(C,gamma)组成了一个二维网格,再与性能指标识别率组成三维模型,实现参数的最优选择。
1、Double cross-validation
Double cross-validation也称2-fold cross-validation(2-CV)
将数据集分成两个相等大小的子集,进行两回合的分类器训练。在第一回合,一个子集作为训练集,另一个作为测试集;在第二回合,则将训练集与测试集对换后,再次训练分类器,而其中我们比较关心的是两次测试集的识别率。
优点:容易实现,处理简单。
缺点:没有用到交叉的方法,验证数据集对于模型的训练没有任何贡献。
2、K-flod CV(k折交叉验证)
样本数据被分为k组,每次将一组作为验证数据集,其余的k−1组作为训练数据集。这样就会有k 个训练模型,这k个模型的验证准确率的平均值作为模型的性能指标。
优点:所有的样本都会被用于模型训练,评价结果可信。
缺点:相较于Hold one method,处理较为复杂。
3、Leave-One-Out CV(LOO-CV留一验证法)
设原始数据集中有K个样本,每次选择一个样本作为验证数据集,其余的K−1个样本作为训练数据集,这样就会有K个训练模型,这K个训练模型的验证准确率平均值为模型的性能指标。
优点:每次模型训练,几乎所有的样本都会应用到,结果最可信。
缺点:需要训练的模型较多,且训练数据集样本大,计算成本高。
3.rbf核函数最佳参数cg的选取w问题
C被称为惩罚因子,C越大说明对错误的容忍度越小,会导致过拟合(overfitting);C太小可能会导致容错率过高,会导致欠拟合。
一般是通过交叉验证的方法来确定C和gamma。
思路:将C和gamma参数在一定取值范围内按照一定的步长(默认为1)进行取值组合;在不同(C,gamma)的组合下,将训练集样本均分成k组,一组作为验证的数据样本,其余k-1组则用来作为训练的数据,每一组数据都轮流着作为验证数据样本,这样在一组(C,gamma)组合下,就需要进行K次计算,把这K次计算的模型测试准确率score的均值作为这组(C,gamma)下模型的得分。这样的话就能够得到不同(C,gamma)组合下模型的得分,取得分最高的那组(C,gamma)即可,如果碰到有相同分的,一般考虑参数C,取C小的,因为在保证模型的准确率的情况下,C越小模型容错率大,可以避免过拟合,若C也相同,则取先出现的那一组gamma。简单的说,网格法原理就是在一定的范围里面大步伐的,挨着试cg的参数,然后把该参数结果的精确度 绘制成等高线;再缩小cg的范围,用小步伐去试,所以运算量很大。
网格法的缺点就是慢,数据量稍微大一点根本就跑不了。详细的理论代码可以在《[MATAB神经网络30个案例分析].史峰》这本书的的十二十三章有讲解,数据量太大的真的跑不动。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
· 为什么 退出登录 或 修改密码 无法使 token 失效