多分类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