基于MATLAB的PSO算法优化SVM模型参数实践
一、算法框架与实现思路
1. 核心优化目标
- 参数空间:支持向量机关键参数包括正则化系数
C与径向基核函数参数gamma - 评价标准:采用交叉验证精度作为分类任务的优化目标,回归任务则使用均方误差
2. 粒子群优化流程
graph TD A[初始化种群] --> B{计算适应度} B --> C[更新个体最优解] C --> D[全局最优更新] D --> E{终止条件?} E -->|达成| F[获取最佳参数组合] E -->|未达成| B
二、完整实现方案
1. 数据预处理模块
% 加载基准数据集
load fisheriris
features = meas';
labels = grp2idx(species);
% 特征标准化处理
[stdFeatures, ~] = mapminmax(features', 0, 1);
stdFeatures = stdFeatures';
% 划分训练/测试集
cv = cvpartition(labels,'HoldOut',0.3);
trainData = stdFeatures(cv.training,:);
trainLabels = labels(cv.training);
testData = stdFeatures(cv.test,:);
testLabels = labels(cv.test);
2. 参数配置参数
% 优化器配置
optimizerConfig = struct(...
'maxIterations', 150, % 最大迭代次数
'populationSize', 40, % 种群规模
'inertiaWeight', 0.8, % 惯性权重
'cognitiveCoeff', 1.2, % 认知因子
'socialCoeff', 1.4, % 社会因子
'velocityRange', [0.2, -0.2], % 速度边界
'mutationProb1', 0.05, % 参数变异概率1
'mutationProb2', 0.05); % 参数变异概率2
% 参数搜索范围
paramLimits = [0.01, 100; % C的取值区间
0.001, 10]; % gamma的取值区间
3. 适应度评估函数
function fitness = svmEvaluator(params, trainData, trainLabels)
% 参数转换
C_val = 10^params(1);
gamma_val = 10^params(2);
% 构建SVM命令
cmd = sprintf('-v 5 -c %.6f -g %.6f', C_val, gamma_val);
% 执行交叉验证
accuracy = svmtrain(trainLabels, trainData, cmd);
fitness = -accuracy; % 转换为最小化问题
end
4. 优化算法执行
% 初始化种群
popSize = optimizerConfig.populationSize;
paramDim = 2;
positions = rand(popSize, paramDim) .* (paramLimits(:,2)' - paramLimits(:,1)') + paramLimits(:,1)';
velocities = rand(popSize, paramDim) .* (optimizerConfig.velocityRange(1) - optimizerConfig.velocityRange(2)) + optimizerConfig.velocityRange(2);
% 初始化最优值
personalBest = positions;
personalFitness = inf(popSize, 1);
globalBest = personalBest(1,:);
globalFitness = personalFitness(1);
% 迭代优化过程
for iter = 1:optimizerConfig.maxIterations
for i = 1:popSize
% 计算适应度
currentFit = svmEvaluator(positions(i,:), trainData, trainLabels);
% 更新个体最优
if currentFit < personalFitness(i)
personalBest(i,:) = positions(i,:);
personalFitness(i) = currentFit;
end
% 更新全局最优
if currentFit < globalFitness
globalBest = positions(i,:);
globalFitness = currentFit;
end
end
% 速度更新
r1 = rand(popSize, paramDim);
r2 = rand(popSize, paramDim);
velocities = optimizerConfig.inertiaWeight * velocities ...
+ optimizerConfig.cognitiveCoeff * r1 .* (personalBest - positions) ...
+ optimizerConfig.socialCoeff * r2 .* (globalBest - positions);
% 速度限制
velocities = max(min(velocities, optimizerConfig.velocityRange(1)), optimizerConfig.velocityRange(2));
% 位置更新
positions = positions + velocities;
% 参数边界约束
positions(:,1) = max(min(positions(:,1), paramLimits(1,2)), paramLimits(1,1));
positions(:,2) = max(min(positions(:,2), paramLimits(2,2)), paramLimits(2,1));
% 自适应变异操作
if rand < optimizerConfig.mutationProb1
positions(:,1) = 10^randn(popSize,1);
end
if rand < optimizerConfig.mutationProb2
positions(:,2) = 10^randn(popSize,1);
end
% 迭代信息展示
fprintf('Iter %d: Best Fitness=%.4f (C=%.4f, gamma=%.4f)\n',...
iter, -globalFitness, 10^globalBest(1), 10^globalBest(2));
end
5. 模型训练与性能评估
% 获取最优参数
optimal_C = 10^globalBest(1);
optimal_gamma = 10^globalBest(2);
cmd = sprintf('-c %.6f -g %.6f', optimal_C, optimal_gamma);
trainedModel = svmtrain(trainLabels, trainData, cmd);
% 测试集预测
[results, accuracy, ~] = svmpredict(testLabels, testData, trainedModel);
% 输出评估结果
fprintf('测试集准确率: %.2f%%\n', accuracy(1)*100);
三、优化策略增强
1. 动态参数调整机制
- 惯性权重自适应:
w = optimizerConfig.inertiaWeight * (1 - iter/optimizerConfig.maxIterations);
- 学习因子动态调整:
c1 = optimizerConfig.cognitiveCoeff * (1 - iter/optimizerConfig.maxIterations);
c2 = optimizerConfig.socialCoeff * (1 + iter/optimizerConfig.maxIterations);
2. 多目标优化扩展
% 同时优化精度与模型复杂度
fitness = -accuracy + 0.1*(sum(W.^2)); % W为支持向量权重
3. 并行计算优化
% 使用并行计算加速适应度评估
parfor i = 1:popSize
% 并行计算适应度值
end
四、可视化分析
1. 收敛曲线分析
figure;
plot(1:optimizerConfig.maxIterations, -globalFitness*ones(1,optimizerConfig.maxIterations), 'r--');
hold on;
plot(1:optimizerConfig.maxIterations, mean(personalFitness,1), 'b-.');
legend('全局最优','平均适应度');
xlabel('迭代次数'); ylabel('适应度值');
title('PSO收敛趋势');
2. 参数分布热力图
figure;
histogram2(personalBest(:,1), personalBest(:,2), 'DisplayStyle','tile');
xlabel('log10(C)'); ylabel('log10(gamma)');
title('最优参数分布');
colorbar;