​​​​​​​​​​​​​​LIBSVM (四) SVM 的参数优化(交叉验证)

LIBSVM (四) SVM 的参数优化(交叉验证) 

转自 https://www.cnblogs.com/blogwww/p/9498607.html

  CV是用来验证分类器性能的一种统计分析方法,其基本思想是在某种意义下将原始数据进行分组,一部分作为测试集,另一部分作为验证集;先用训练集对分类器进行训练,再利用验证集来测试训练得到的模型,以得到的分类准确率作为评价分类器的性能指标。常见的 CV 方法如下:

1.1 交叉验证(Cross Validation,CV)

  伪代码:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

Start

    bestAccuracy = 0;

    bestc = 0;

    bestg = 0;

    % 其中n1,n2都是预先给定的数

    for c = 2^(-n1):2(n1)

        for g = 2^(-n2):2^(n2)

                将训练集平均分成 N 部分,设为

train(1),train(2),···,train(N)

                分别让每一个部分作为测试及进行预测(剩下的N-1部分作为训练集对训练集进行训练),取得最后

                得到的所有分类准确率的平均数,设为 cv.

                if(cv > bestAccuracy)

                    bestAccuracy = cv;bestc = c;bestg = g;

                end

            end

end

Over

   采用CV的方法,在没有测试标签的情况下可以找到一定意义下的最佳参数c和g。这里所说的“一定意义下”指的是此时最佳参数c和g是使得训练集在CV思想下能够达到最高分类准确率的参数,但不能保证会使得测试集也达到最高的分类准确率。用此方法对wine数据进行分类预测,MATLAB 实现代码如下:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

%% 交叉验证

bestcv = 0;

bestc = 0;

bestg = 0;

for log2c = -5:5

    for log2g = -5:5

        cmd =['-v 3 -c ',num2str(2^log2c), ' -g ',num2str(2^log2g)];

        cv = svmtrain(train_wine_labels,train_wine,cmd);

        if(cv > bestcv)

        bestcv = cv;

        bestc = 2^log2c;

        bestg = 2^log2g;

        end

    end

end

 

fprintf('(best c = %g,g = %g,rate = %g)\n',bestc,bestg,bestcv);

cmd = ['-c ',num2str(bestc),' -g ',num2str(bestg)];

model = svmtrain(train_wine_labels,train_wine,cmd);

[predict_label,accuracy,dec_value]=svmpredict(test_wine_labels,test_wine,model);

 (best c = 2,g = 0.5,rate = 98.8764)

Accuracy = 98.8764% (88/89) (classification)

1.2  K-CV 算法(K - fold Cross Validation )

   将原始数据分成K组(一般是均分),将每个子集数据分别做一次验证集,其余的 K-1 组子集数据作为训练集,这样会得到 K 个模型,用这 K 个模型最终的验证集的分类准确率的平均值作为此 K-CV 下分类器的性能指标。K>=2,一般实际操作是取K=3,只有在原始数据集合数据量小的时候才会尝试取 2。K - CV 可以有效地避免过学习以及欠学习状态的发生,最后得到的结果也比较具有说服性。

  这节主要涉及到函数 SVMcgForClass 的理解,以及使用技巧

1.2.1 SVMcgForClass

   伪代码:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

Start

    bestAccuracy = 0;

    bestc = 0;

    bestg = 0;

    % 将 c 和 g 划分网格进行搜索

    for c = 2^(-n1):2(n1)

        for g = 2^(-n2):2^(n2)

               %利用 K-CV 方法

将train平均分成 K 组,

记train(1),train(2),···,train(K)

相应的标签也要分离出来,

记为 train_label(1),train_label(2),···,train_label(k),

            for  run = 1:k  %让train(run),作为验证集,其他作为训练集,记录此时acc(run)

            end

            cv = (acc(1)+acc(2)+```+acc(K))/k;

            if(cv > bestAccuracy)

                bestAccuracy = cv;bestc = c;bestg = g;

            end

        end

end

Over

函数接口及输入参数解析

1

2

3

4

5

6

7

8

9

10

11

[bestacc,bestc,bestg]=SVMcgForClass(train_label,train,cmin,cmax,gmin,gmax,v,cstep,gstep,accstep)

train_label :训练集标签

train:训练集

cmin:惩罚参数c的变化范围(以2为底的幂指数后),即c_min=2……(cmin),默认值为-5;

cmax:惩罚参数c的变化范围(以2为底的幂指数后),即c_max=2……(cmax),默认值为5;

gmin:参数g的变化范围最小值(以2为底的幂指数后),即g_min=2……(gmin),默认值为-5;

gmax:参数g的变化范围最大值(以2为底的幂指数后),即g_max=2……(gmax),默认值为5;

v:CV的参数,即给测试集分几部分进行CV。默认值为3.

cstep:参数c步进的大小(取以2为底的幂指数后),默认值为1.

gstep:参数g步进的大小(取以2为底的幂指数后),默认值为1.

accstep:最后显示准确率图时的步进大小

 以上参数只有train_label和train是必须输入的,其他的可不输入采用默认值。

1.2.2 代码实现

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

% about the parameters of SVMcg

if nargin < 10

    accstep = 4.5;

end

if nargin < 8

    cstep = 0.8;

    gstep = 0.8;

end

if nargin < 7

    v = 5;

end

if nargin < 5

    gmax = 8;

    gmin = -8;

end

if nargin < 3

    cmax = 8;

    cmin = -8;

end

% X:c Y:g cg:CVaccuracy

[X,Y] = meshgrid(cmin:cstep:cmax,gmin:gstep:gmax);

[m,n] = size(X);

cg = zeros(m,n);

 

eps = 10^(-4);

 

% record acc with different c & g,and find the bestacc with the smallest c

bestc = 1;

bestg = 0.1;

bestacc = 0;

basenum = 2;

for i = 1:m

    for j = 1:n

        cmd = ['-v ',num2str(v),' -c ',num2str( basenum^X(i,j) ),' -g ',num2str( basenum^Y(i,j) )];

        cg(i,j) = svmtrain(train_label, train, cmd);

         

        if cg(i,j) <= 55

            continue;

        end

         

        if cg(i,j) > bestacc

            bestacc = cg(i,j);

            bestc = basenum^X(i,j);

            bestg = basenum^Y(i,j);

        end       

         

        if abs( cg(i,j)-bestacc )<=eps && bestc > basenum^X(i,j)

            bestacc = cg(i,j);

            bestc = basenum^X(i,j);

            bestg = basenum^Y(i,j);

        end       

         

    end

end

% to draw the acc with different c & g

figure;

[C,h] = contour(X,Y,cg,70:accstep:100);

clabel(C,h,'Color','r');

xlabel('log2c','FontSize',12);

ylabel('log2g','FontSize',12);

firstline = 'SVC参数选择结果图(等高线图)[GridSearchMethod]';

secondline = ['Best c=',num2str(bestc),' g=',num2str(bestg), ...

    ' CVAccuracy=',num2str(bestacc),'%'];

title({firstline;secondline},'Fontsize',12);

grid on;

 

figure;

meshc(X,Y,cg);

% mesh(X,Y,cg);

% surf(X,Y,cg);

axis([cmin,cmax,gmin,gmax,30,100]);

xlabel('log2c','FontSize',12);

ylabel('log2g','FontSize',12);

zlabel('Accuracy(%)','FontSize',12);

firstline = 'SVC参数选择结果图(3D视图)[GridSearchMethod]';

secondline = ['Best c=',num2str(bestc),' g=',num2str(bestg), ...

    ' CVAccuracy=',num2str(bestacc),'%'];

title({firstline;secondline},'Fontsize',12);

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值