大家好,欢迎来到IT知识分享网。
简介
回归分析(regression analysis)是确定两种或两种以上变量间相互依赖的定量关系的一种统计分析方法。LIBSVM可以用于解决分类和回归问题,上一篇博文中介绍了分类问题。在这里将对回归问题结合实例运用LIBSVM。回归分析按照涉及的变量的多少,分为一元回归和多元回归分析。这篇博文对于一元回归和多元回归,基于LIBSVM分别用两个例子进行讲解。
回归问题
核心函数svmtrain和svmpredict
调用格式
model = svmtrain(train_label, train_data, ‘options’); [predict_label, accuracy/mse, dec_value] = svmpredict(test_label, test_data,model);
LIBSVM options 训练参数设置
-s 选择SVM类型,回归分析只能选3或者4(默认值为0) 0:C - SVC 1:nu - SVC 2:one - class SVM 3:epsilon - SVR 4:nu - SVR - t 是选择核函数(默认值为2) 0:线性核函数 u'v 1:多项式核函数(r *u'v + coef0)^degree 2:RBF 核函数 exp( -r|u - v|^2) 3:sigmiod核函数 tanh(r * u'v + coef0) - d degree:核函数中的 degree 参数设置(针对多项式核函数,默认值为3) - g r(gama):核函数中的gama参数设置(针对多项式/sigmoid 核函数/RBF/,默认值为属性数目的倒数。即,k为属性的数目,则-g参数默认为 1/k) - r coef0:核函数中的coef0参数设置(针对多项式/sigmoid核函数,默认值为0) - c cost:设置 C - SVC,epsilon - SVR 和 nu - SVR的参数(默认值为1) - n nu:设置 nu-SVC ,one - class SVM 和 nu - SVR的参数(默认值为 0.5) - p epsilon:设置 epsilon - SVR 中损失函数的值(默认值为0.1) - m cachesize:设置 cache 内存大小,以 MB 为单位(默认值为100) - e eps:设置允许的终止阈值(默认值为0.001) - h shrinking:是否使用启发式,0或1(默认值为1) - wi weight:设置第几类的参数 C 为 weight * C(对于 C - SVC 中的 C,默认值为1) - v n将训练数据分成n份做交叉验证。默认为5
其中-s控制的就是训练类型,而当-s等于3或4的时候,就是回归模型SVR。-s 3 就是常用的带惩罚项的 SVR模型。
注意:当svmtrain使用-v参数时,返回的model不再是一个结构体,分类问题返回的是交叉验证下的平均分类准确率;回归问题返回的是交叉检验下的平均mse(均方根误差)。使用-v是在参数寻优时寻找最优参数所用的,在正常模型训练时不用-v参数。
以上这些参数设置可以按照SVM的类型和核函数所支持的参数进行任意组合,如果设置的参数在函数或SVM类型中没有也不会产生影响,程序不会接受该参数;如果应有的参数设置不正确,参数将采用默认值。
输出model
训练得到的模型,是一个结构体。假设一个model结构如下:
model = Parameters: [5x1 double] nr_class: 2 totalSV: 259 rho: 0.0514 Label: [2x1 double] ProbA: [] ProbB: [] nSV: [2x1 double] sv_coef: [259x1 double] SVs: [259x13 double]
首先先来看一下model.Parameters里面承装的都是什么:
model.Parameters ans = 0 2.0000 3.0000 2.8000 0
重要知识点:
model.Label model.nr_class
model.Label ans = 1 -1 >> model.nr_class ans = 2
model.totalSV model.nSV
model.totalSV ans = 259 >> model.nSV ans = 118 141
model.sv_coef model.SVs model.rho
sv_coef: [259x1 double] SVs: [259x13 double] model.rho = 0.0514
重要知识点:
model.sv_coef是一个2591的矩阵,承装的是259个支持向量在决策函数中的系数;
model.SVs是一个25913的稀疏矩阵,承装的是259个支持向量。
model.rho是决策函数中的常数项的相反数(-b)
最后我们来看一下,svmpredict得到的返回参数的意义都是什么?
% 利用建立的模型看其在训练集合上的分类效果 [PredictLabel,accuracy] = svmpredict(label,data,model); accuracy
假设运行可以看到:
model = Parameters: [5x1 double] nr_class: 2 totalSV: 259 rho: 0.0514 Label: [2x1 double] ProbA: [] ProbB: [] nSV: [2x1 double] sv_coef: [259x1 double] SVs: [259x13 double] Accuracy = 99.6296% (269/270) (classification) accuracy = 99.6296 0.0148 0.9851
svmpredict
svmpredict函数的使用更加简单,输入就是待测数据的特征矩阵和标签,输出有三个一个是predict_label,预测的测试集的标签,数据类型double;accuracy/mse是一个3*1的列向量,第一个数代表分类准确率(分类问题使用),第二个代表mse(回归问题使用),第三个数表示平方相关系数(回归问题使用)。注意,如果测试集的真实标签事先无法得知,则这个返回值没有意义。实际上我们真实做预测的时候,标签本来就是应该没有的,如果我们事先都知道的话,预测标签就没有意义了。之所以要用标签,就是为了测试我们训练得到的模型去做预测时效果好不好,这个返回值就是为了验证用的。一旦我们知道了我们的模型是可靠地,我们就可以真正用它来做预测了,那么这个返回值就没有任何意义了。另外需要说明的是,标签只是我们用来表示某个类别的一个符号而已,不具有真实的数据意义,只是我们要知道,这个数据代表的是哪一类。
数据归一化
归一化化就是要把你需要处理的数据经过处理后(通过某种算法)限制在你需要的一定范围内。首先归一化是为了后面数据处理的方便,其次是保正程序运行时收敛加快。为什么要用归一化呢?首先先说一个概念,叫做奇异样本数据,所谓奇异样本数据数据指的是相对于其他输入样本特别大或特别小的样本矢量。下面举例:
m=[0.11 0.15 0.32 0.45 30; 0.13 0.24 0.27 0.25 45];
其中的第五列数据相对于其他4列数据就可以成为奇异样本数据(下面所说的网络均值bp)。奇异样本数据存在所引起的网络训练时间增加,并可能引起网络无法收敛,所以对于训练样本存在奇异样本数据的数据集在训练之前,最好先进形归一化,若不存在奇异样本数据,则不需要事先归一化。是否一定要做归一化这个预处理才能提高最后的分类准确率呢?答案是否定的。并不是任何问题都必须要进行归一化预处理,要具体问题具体分析,进行试验测试表明,有时归一化后的预测准确率要比没有归一化的低好多,而且不同的归一化方式对最后的准确率也会有一定的影响。还要强调一点就是训练集是如何归一化的测试集也要如何归一化。
不同的归一化方式对最后的准确 率也会有一定的影响。但是否一定 要做归一化这个预处理才能提高最后的准确率呢?答案是否定的。并不是任何问题都必须事 先把原始数据进行归一化,要具体问题具体看待,测试表明有时候归一化后的预测准确率比没有归一化的预测准确率会低很多。
参数寻优
这里的参数是SVMtrain训练模型的参数,参数找的好,模型训练的就好,可以提高后面预测分类的准确率。不同的SVM类型需要寻优的参数不同。然后利用最优参数去训练模型model,得到模型后就可以利用svmpredict函数进行使用预测了。
采用 CV 的方法,在没有测试集标签的情况下可以找到一定意义下的最佳的参数 c 和 g.这里说的“一定意义下”指的是此时的最佳参数 c和 g是使得训练集在 CV思想下能够达到最 高分类准确率的参 数,但其不能保证会使得测试集也达到最高的分类准确率 。
实例1
这个例子里,测试数据为一元函数,y=f(x)形式。
clc clear all close all %% % 生成待回归的数据 x = (-1:0.1:1)'; y = -100*x.^3 + x.^2 - x + 1; % 增加噪声 y = y+ 20*rand(length(y),1); figure; plot(x,y,'o'); %% 最优参数选择 mse = 10^7; for log2c = -10:0.5:3 for log2g = -10:0.5:3 % -v 交叉验证参数:在训练的时候需要,测试的时候不需要,否则出错 options = ['-v 3 -c ', num2str(2^log2c), ' -g ', num2str(2^log2g) , ' -s 3 -p 0.4 -t 3']; cv = svmtrain(y,x,options); if (cv < mse) mse = cv; bestc = 2^log2c; bestg = 2^log2g; end end end %% 训练 options = ['-c ', num2str(2^bestc), ' -g ', num2str(2^bestg) , ' -s 3 -p 0.4 -n 0.1']; model = svmtrain(y,x,options) % model % 利用建立的模型看其在训练集合上的回归效果 [py,accuracy,dv] = svmpredict(y,x,model); hold on; plot(x,py,'g+'); %% % 进行预测新的x值 %-- 产生[-1 1]的随机数 testx = -2+(2-(-2))*rand(10,1); testy = zeros(10,1);% 理论y值无所谓 [ptesty,~,~] = svmpredict(testy,testx,model); hold on; plot(testx,ptesty,'r*'); legend('原始数据','回归数据','新数据'); grid on; % title('t=0:线性核') % title('t=1:多项式核') % title('t=2:径向基函数(高斯)') title('t=3:sigmod核函数')
这里的回归实验采用了一维数据,下面将进行多元数据回归分析。
实例2 多元函数回归
这个例子里,测试数据为多元函数,g=f(x,y,z,l)形式。假设我们有一组数据,x,y,z,l和相应的g数据,但是其函数形式未知,如何使用LIBSVM根据x,y,z,l反演g的数据呢?
假设二手奥迪A8价格price(万)与其使用年限years、里程miles(km)、有无事故(0 无 1有)有关,下面的例子就根据这些属性反演A8的价格。由于样本较少,反演效果一般。
clc clear all close all %% 假设二手奥迪A8价格price(万)与其使用年限years、里程miles(km)、有无事故(0 无 1有) price = [120; 110; 105; 80; 75; 71; 60; 56; 55; 50; 42; 40; 38; 35; 25]; proper = [0 0 0; 1 1 0; 1 5 0; 1 5 1;... 2 10 0; 2 10 1; 2 20 0; 2 20 1;... 3 30 0; 3 30 1; 3 40 0; 3 40 1;... 4 54 0; 4 60 0; 5 70 1] %% 最优参数选择 mse = 10^7; for log2c = -10:0.5:3 for log2g = -10:0.5:3 % -v 交叉验证参数:在训练的时候需要,测试的时候不需要,否则出错 options = ['-v 3 -c ', num2str(2^log2c), ' -g ', num2str(2^log2g) , ' -s 3 -p 0.4 -t 3']; cv = svmtrain(price,proper,options); if (cv < mse) mse = cv; bestc = 2^log2c; bestg = 2^log2g; end end end %% 训练 options = ['-c ', num2str(2^bestc), ' -g ', num2str(2^bestg) , ' -s 3 -p 0.4 -n 0.1']; model = svmtrain(price,proper,options) % model % 利用建立的模型看其在训练集合上的回归效果 [predict_p,accuracy,dv] = svmpredict(price,proper,model); figure plot(price,'o') hold on plot(predict_p,'.') test_proper = [4 60 0] test_price = 0; %这个随便给不影响预测的价格,但是会基于这个值计算预测准确率。 [predict_t,accuracy_t,dv_t] = svmpredict(test_price,test_proper,model); hold on plot(predict_t,'*') legend('原始价格','回归价格','新数据预测价格');
警告类型
这是一个limsvm缩小启发式的警告,缩小的启发式是为了加速优化。
迭代次数达到了上限,却没有达到收敛条件,所以训练结果可能会很差。
输出信息含义
// obj为SVM文件转换为的二次规划求解得到的最小值,rho为判决函数的偏置项
optimization finished, #iter = 7327 //iter为迭代次数 nu = 0. //nu是你选择的核函数类型的参数 obj = -., rho = 63. //obj为SVM文件转换为的二次规划求解得到的最小值,rho为判决函数的偏置项 nSV = 883, nBSV = 780 // nSV为标准支持向量个数,nBSV为边界上的支持向量个数(a[i]=c)
免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://haidsoft.com/113785.html