基于matlab平台的libsvm回归
由于项目需要建立一个SVR模型,记录一下libsvm的使用流程。
因为要做的是回归,所以我们应该有一些输入$x$(每一行代表一个样本),输出$y$,从而得到$y=f(x)$的关系用于预测;当$y$为多维时,逐维进行回归。
Step 1 对数据进行scaleing,训练数据和测试数据都需要!
这里提供一个自己写的scaling函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
2020/02/19 by Minghao Chen, this function is used to scale the data; %Usage: %for traindata: [traindata,minimums,ranges] = svm_scale(traindata), %it will return the minimums and ranges of traindata, which will be needed %in testdata scaling %For testdata: [testdata,minimums,ranges] = svm_scale(testdata,minimums,ranges) function [data,minimums,ranges] = svm_scale(data,minimums,ranges) if nargin == 1 minimums = min(data, [], 1); ranges = max(data, [], 1) - minimums; data = (data - repmat(minimums, size(data, 1), 1)) ./ repmat(ranges, size(data, 1), 1); else data = (data - repmat(minimums, size(data, 1), 1)) ./ repmat(ranges, size(data, 1), 1); end |
Step 2 首先考虑RBF核函数,通过grid search进行参数$C, \gamma$寻优,可以先粗后细(大区间到小区间)
在进行参数搜索时可以用交叉验证,中途会涉及数据的划分,这里提供一个自己写的数据划分的程序
1 2 3 4 5 6 7 |
function [train_data,train_target,valid_data,valid_target] = data_split(data,target,k) N = size(data,1); p = randperm(N)'; train_data = data(p(1:round(k*N)),:); valid_data = data(p(1+round(k*N):end),:); train_target = target(p(1:round(k*N)),:); valid_target = target(p(1+round(k*N):end),:); |
其中data放的就是$x$,target放的就是$y$,参数$k$取值$(0,1)$表示你要拿多少的数据用于训练
Step 3 用最优的超参数来训练模型
这里就需要用到libsvm里的训练函数了:
model = svmtrain(train_y,train_x,‘options’)
需要注意的是’options’, 直接给个例子在解释吧,比如:
1
|
model = svmtrain(train_y,train_x,'-s 3 -t 2 -p 0.01 -c 2 -g 2') |
其中各个缩写表示的含义为:
-s 类型 : set type of SVM (default 0)
1 2 3 4 5 6 7 8 9 |
0 -- C-SVC 1 -- nu-SVC 2 -- one-class SVM 3 -- epsilon-SVR 4 -- nu-SVR |
-t 核函数 : set type of kernel function (default 2)
1 2 3 4 5 6 7 |
0 -- linear 1 -- polynomial 2 -- radial basis function: $exp(-\gamma*|u-v|^2)$ 3 -- sigmoid |
-g gamma : set gamma in kernel function (default 1/num_features)
-c cost : set the parameter C of C-SVC, epsilon-SVR, and nu-SVR (default 1)
-p epsilon : set the epsilon in loss function of epsilon-SVR (default 0.1)
Step 4 模型训练好可以直接保存下来,是个结构体的形式
save RegressModel.mat model
Step 5 如果有测试数据就可以进一步进行验证了
这里涉及libsvm的预测函数
[predict_y,accuracy,dec_value] = svmpredict(test_y,test_x,model)
其中,test_y如果没有可以用任意向量替代,此时输出accuracy是一个$3*1$向量,分别表示分类准确率(分类问题使用),MSE(越小越好),平方关系系数$r^2$(越接近1越好)。
例子
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 |
x=(-10:0.5:9.5)'; y=-x.^2; [x_scale,minimums,ranges] = svm_scale(x); % grid search for hyperparameters c = []; g = []; N_grid = 11; for i = 1:N_grid c = [c, 2^(-7+2*i)]; g = [g, 2^(-7+2*i)]; end MSE = 0; for i = 1:N_grid for j = 1:N_grid ops = ['-s 3 -t 2 -p 0.01 -c ',num2str(c(i)),' -g ',num2str(g(j))]; [train_data,train_target,valid_data,valid_target] = data_split(x_scale,y,0.7); model = svmtrain(train_target,train_data,ops); [py,mse,prob_estimates]=svmpredict(valid_target,valid_data,model); MSE(i,j) = mse(2); end end [i,j]=find(MSE==min(min(MSE))); ops = ['-s 3 -t 2 -p 0.01 -c ',num2str(c(i)),' -g ',num2str(g(j))]; % 根据网格搜索得到的最优参数进行全部数据建模 model = svmtrain(y,x_scale,ops); [py,mse,prob_estimates]=svmpredict(y,x_scale,model); % 画图 训练数据的拟合结果 figure; plot(x,y,'o'); hold on plot(x,py,'r*'); legend('原始数据','回归数据'); grid on; % 测试 testx = [-16:0.2:-8]'; testy = -testx.^2; [testx_scale,minimums,ranges] = svm_scale(testx,minimums,ranges); [ptesty,tmse,prob_estimates]=svmpredict(testy,testx_scale,model); figure; plot(testx,testy,'o'); hold on plot(testx,ptesty,'r*'); legend('原始数据','回归数据'); grid on; |