matlab实现多分类svm

多分类SVM

相关资料

libsvm开源库
libsvm matlab安装
matlab独自实现多分类svm-csdn
matlab独自实现多分类svm-git-hub

设计思路

SVM也叫支持向量机,其是一个二类分类器,但是对于多分类,SVM也可以实现。主要方法就是训练多个二类分类器。常见的有以下两种方式:

  • 一对一(one-vs-one)
    给定m个类,对m个类中的每两个类都训练一个分类器,总共的二类分类器个数为 m(m-1)/2 .比如有三个类,1,2,3,那么需要有三个分类器,分别是针对:1和2类,1和3类,2和3类。对于一个需要分类的数据x,它需要经过所有分类器的预测,最后使用投票的方式来决定x最终的类属性。
  • 一对多(one-vs-rest)
    给定m个类,需要训练m个二类分类器。其中的分类器 i 是将 i 类数据设置为类1(正类),其它所有m-1个i类以外的类共同设置为类2(负类),这样,针对每一个类都需要训练一个二类分类器,最后,我们一共有 m 个分类器。对于一个需要分类的数据 x,通常选择置信度最大的类别标记为分类结果。

由于类别较多,本实验采用一对多方式预测

代码

function y_predict = my_MultiSvm(X_train, y_train, X_test)
% multi svm
% one vs all 模型
% Input:
% X_train: n*m矩阵 n为训练集样本数 m为特征数
% y_train: n*1向量 为训练集label,支持任意多种类
% X_test: n*m矩阵 n为测试集样本数 m为特征数
% Output:
% y_predict: n*1向量 测试集的预测结果
% 
% Copyright(c) lihaoyang 2020
%

    y_labels = unique(y_train);
    n_class = size(y_labels, 1);
    models = cell(n_class, 1);
    % 训练n个模型
    for i = 1:n_class
        class_i_place = find(y_train == y_labels(i));
        svm_train_x = X_train(class_i_place,:);
        sample_num = numel(class_i_place);
        class_others = find(y_train ~= y_labels(i));
        randp = randperm(numel(class_others));
        svm_train_minus = randp(1:sample_num)';
        svm_train_x = [svm_train_x; X_train(svm_train_minus,:)];
        svm_train_y = [ones(sample_num, 1); -1*ones(sample_num, 1)];
        disp(['生成模型:', num2str(i)])
        models{i} = fitcsvm(svm_train_x, svm_train_y);
    end
    test_num = size(X_test, 1);
    y_predict = zeros(test_num, 1);
    % 对每条数据,n个模型分别进行预测,选择label为1且概率最大的一个作为预测类别
    for i = 1:test_num
        if mod(i, 100) == 0
            disp(['预测个数:', num2str(i)])
        end
        bagging = zeros(n_class, 1);
        for j = 1:n_class
            model = models{j};
            [label, rat] = predict(model, X_test(i,:));
            bagging(j) = bagging(j) + rat(2);
        end
        [maxn, maxp] = max(bagging);
        y_predict(i) = y_labels(maxp);
    end
end

猜你喜欢

转载自blog.csdn.net/Metralix/article/details/105608859