1. 加载数据
load fisheriris
X = meas; % 输入特征矩阵,包含花瓣长度、花瓣宽度、萼片长度、萼片宽度
Y = species; % 标签数据,包含三类鸢尾花品种
2. 分割数据集为训练集和测试集
% 使用随机数生成器确保每次运行的结果一致
rng(1); % 固定随机数种子
% 随机划分数据,30%作为测试集,70%作为训练集
cv = cvpartition(Y,'HoldOut',0.3);
XTrain = X(training(cv),:);
YTrain = Y(training(cv));
XTest = X(test(cv),:);
YTest = Y(test(cv));
3. 训练多分类支持向量机模型
% 使用fitcecoc处理多分类问题
SVMModel = fitcecoc(XTrain, YTrain, ...
'Learners', templateSVM('KernelFunction', 'linear'), ... % 使用线性核函数
'Coding', 'onevsall', ... % one-vs-all编码方式
'ClassNames', unique(YTrain)); % 指定类标签
4. 模型预测
% 对测试集进行预测,得到预测的标签和决策值
[label, score] = predict(SVMModel, XTest);
% 打印预测结果与实际标签对比
disp('预测标签与实际标签对比:');
table(YTest, label, 'VariableNames', {'实际标签', '预测标签'})
运行结果如下
实际标签 预测标签
______________ ______________
{'setosa' } {'setosa' }
{'setosa' } {'setosa' }
{'setosa' } {'setosa' }
{'setosa' } {'setosa' }
{'setosa' } {'setosa' }
{'setosa' } {'setosa' }
{'setosa' } {'setosa' }
{'setosa' } {'setosa' }
{'setosa' } {'setosa' }
{'setosa' } {'setosa' }
{'setosa' } {'setosa' }
{'setosa' } {'setosa' }
{'setosa' } {'setosa' }
{'setosa' } {'setosa' }
{'setosa' } {'setosa' }
{'versicolor'} {'versicolor'}
{'versicolor'} {'versicolor'}
{'versicolor'} {'versicolor'}
{'versicolor'} {'versicolor'}
{'versicolor'} {'virginica' }
{'versicolor'} {'versicolor'}
{'versicolor'} {'versicolor'}
{'versicolor'} {'virginica' }
{'versicolor'} {'versicolor'}
{'versicolor'} {'versicolor'}
{'versicolor'} {'virginica' }
{'versicolor'} {'versicolor'}
{'versicolor'} {'versicolor'}
{'versicolor'} {'versicolor'}
{'versicolor'} {'versicolor'}
{'virginica' } {'virginica' }
{'virginica' } {'versicolor'}
{'virginica' } {'virginica' }
{'virginica' } {'virginica' }
{'virginica' } {'virginica' }
{'virginica' } {'virginica' }
{'virginica' } {'virginica' }
{'virginica' } {'virginica' }
{'virginica' } {'virginica' }
{'virginica' } {'virginica' }
{'virginica' } {'virginica' }
{'virginica' } {'virginica' }
{'virginica' } {'virginica' }
{'virginica' } {'virginica' }
{'virginica' } {'virginica' }
5. 交叉验证与模型评估
% 使用5折交叉验证来评估模型的泛化性能
CVSVMModel = crossval(SVMModel, 'KFold', 5);
% 计算交叉验证的分类错误率
classLoss = kfoldLoss(CVSVMModel);
disp(['5折交叉验证的分类错误率:', num2str(classLoss)])
运行结果如下:
5折交叉验证的分类错误率:0.038095
6. 超参数调整(网络搜索)
% 定义正则化参数的搜索范围
boxConstraint = logspace(-2, 2, 5); % 正则化参数
% 使用超参数调优,找到最优参数组合
t = templateSVM('KernelFunction', 'linear');
[Mdl, HyperparameterOptimizationResults] = fitcecoc(XTrain, YTrain, ...
'Learners', t, ...
'OptimizeHyperparameters', {'BoxConstraint'}, ...
'HyperparameterOptimizationOptions', struct('AcquisitionFunctionName', ...
'expected-improvement-plus'));

7. 可视化
% 可视化调参前后的决策边界(前提条件:使用二维特征进行分类)
% 为了简化可视化,我们仅使用前两个特征进行训练
SVMModel2D = fitcecoc(XTrain(:, 1:2), YTrain, ...
'Learners', templateSVM('KernelFunction', 'linear'));
% 绘制决策边界
figure;
gscatter(XTrain(:,1), XTrain(:,2), YTrain);
hold on;
% 获取支持向量
sv = SVMModel2D.BinaryLearners{1}.SupportVectors;
% 检查支持向量的维度
if size(sv, 2) == 2
% 如果支持向量是二维的,则绘制
plot(sv(:,1),sv(:,2),'ko','MarkerSize',10); % 支持向量
else
% 如果支持向量是其他维度的,则打印警告信息
disp('支持向量的维度不为二维,无法绘制。');
end
title('线性核函数的支持向量机决策边界');
xlabel('萼片长度');
ylabel('萼片宽度');
legend('Location','Best');
hold off;
运行结果如下:

% 绘制决策区域
d = 0.02;
[x1Grid,x2Grid] = meshgrid(min(XTrain(:,1)):d:max(XTrain(:,1)), min(XTrain(:,2)):d:max(XTrain(:,2)));
xGrid = [x1Grid(:),x2Grid(:)];
[~,scores1] = predict(SVMModel2D,xGrid);
figure;
contourf(x1Grid, x2Grid, reshape(scores1(:,2),size(x1Grid)), 'LineColor','none');
colormap jet;
colorbar;
hold on;
gscatter(XTrain(:,1), XTrain(:,2), YTrain, 'rb','.');
title('SVM 决策区域');
xlabel('萼片长度');
ylabel('萼片宽度');
hold off;

% 可视化混淆矩阵
figure;
confusionchart(YTest, label);
title('测试集的混淆矩阵');

完整代码如下:
% 清空工作区,关闭所有图形窗口,清空命令行
clear; clc; close all;
%% 1. 加载数据
% 这里使用MATLAB内置的Fisher's Iris数据集
load fisheriris
X = meas; % 输入特征矩阵,包含花瓣长度、花瓣宽度、萼片长度、萼片宽度
Y = species; % 标签数据,包含三类鸢尾花品种
%% 2. 分割数据集为训练集和测试集
% 使用随机数生成器确保每次运行的结果一致
rng(1); % 固定随机数种子
% 随机划分数据,30%作为测试集,70%作为训练集
cv = cvpartition(Y,'HoldOut',0.3);
XTrain = X(training(cv),:);
YTrain = Y(training(cv));
XTest = X(test(cv),:);
YTest = Y(test(cv));
%% 3. 训练多分类支持向量机模型
% 使用fitcecoc处理多分类问题
SVMModel = fitcecoc(XTrain, YTrain, ...
'Learners', templateSVM('KernelFunction', 'linear'), ... % 使用线性核函数
'Coding', 'onevsall', ... % one-vs-all编码方式
'ClassNames', unique(YTrain)); % 指定类标签
%% 4. 模型预测
% 对测试集进行预测,得到预测的标签和决策值
[label, score] = predict(SVMModel, XTest);
% 打印预测结果与实际标签对比
disp('预测标签与实际标签对比:');
table(YTest, label, 'VariableNames', {'实际标签', '预测标签'})
%% 5. 交叉验证与模型评估
% 使用5折交叉验证来评估模型的泛化性能
CVSVMModel = crossval(SVMModel, 'KFold', 5);
% 计算交叉验证的分类错误率
classLoss = kfoldLoss(CVSVMModel);
disp(['5折交叉验证的分类错误率:', num2str(classLoss)])
%% 6. 超参数调整(网格搜索)
% 定义正则化参数的搜索范围
boxConstraint = logspace(-2, 2, 5); % 正则化参数
% 使用超参数调优,找到最优参数组合
t = templateSVM('KernelFunction', 'linear');
[Mdl, HyperparameterOptimizationResults] = fitcecoc(XTrain, YTrain, ...
'Learners', t, ...
'OptimizeHyperparameters', {'BoxConstraint'}, ...
'HyperparameterOptimizationOptions', struct('AcquisitionFunctionName', ...
'expected-improvement-plus'));
%% 7. 可视化
% 可视化调参前后的决策边界(前提条件:使用二维特征进行分类)
% 为了简化可视化,我们仅使用前两个特征进行训练
SVMModel2D = fitcecoc(XTrain(:, 1:2), YTrain, ...
'Learners', templateSVM('KernelFunction', 'linear'));
% 绘制决策边界
figure;
gscatter(XTrain(:,1), XTrain(:,2), YTrain);
hold on;
% 获取支持向量
sv = SVMModel2D.BinaryLearners{1}.SupportVectors;
% 检查支持向量的维度
if size(sv, 2) == 2
% 如果支持向量是二维的,则绘制
plot(sv(:,1),sv(:,2),'ko','MarkerSize',10); % 支持向量
else
% 如果支持向量是其他维度的,则打印警告信息
disp('支持向量的维度不为二维,无法绘制。');
end
title('线性核函数的支持向量机决策边界');
xlabel('萼片长度');
ylabel('萼片宽度');
legend('Location','Best');
hold off;
% 绘制决策区域
d = 0.02;
[x1Grid,x2Grid] = meshgrid(min(XTrain(:,1)):d:max(XTrain(:,1)), min(XTrain(:,2)):d:max(XTrain(:,2)));
xGrid = [x1Grid(:),x2Grid(:)];
[~,scores1] = predict(SVMModel2D,xGrid);
figure;
contourf(x1Grid, x2Grid, reshape(scores1(:,2),size(x1Grid)), 'LineColor','none');
colormap jet;
colorbar;
hold on;
gscatter(XTrain(:,1), XTrain(:,2), YTrain, 'rb','.');
title('SVM 决策区域');
xlabel('萼片长度');
ylabel('萼片宽度');
hold off;
% 可视化混淆矩阵
figure;
confusionchart(YTest, label);
title('测试集的混淆矩阵');
596

被折叠的 条评论
为什么被折叠?



