基于粒子群算法(PSO)优化支持向量机(SVM)参数实现方案
基于粒子群算法(PSO)优化支持向量机(SVM)参数实现方案,结合PSO算法和LibSVM库。
基于粒子群算法(PSO)优化支持向量机(SVM)参数是一个有效的机器学习优化方法。
1. 基本原理
PSO优化SVM参数流程:
数据准备 → PSO初始化 → 粒子位置(C,γ) → SVM训练 → 计算适应度 → 更新粒子 → 收敛判断 → 最优参数
2. 完整MATLAB实现
主程序:PSO_SVM.m
function [bestc, bestg, bestacc] = PSO_SVM(train_data, train_label, test_data, test_label)
% 基于粒子群算法的SVM参数优化
% 输入:训练数据、测试数据
% 输出:最优参数C、gamma,最佳准确率
%% 参数设置
pso_options = struct(...
'c1', 1.5, ... % 个体学习因子
'c2', 1.7, ... % 社会学习因子
'maxgen', 50, ... % 最大迭代次数
'sizepop', 20, ... % 种群规模
'k', 0.6, ... % 收缩因子
'w', 0.9, ... % 惯性权重
'wdamp', 0.99, ... % 惯性权重衰减系数
'vmax', 1, ... % 最大速度
'popcmax', 1000, ... % C最大值
'popcmin', 0.1, ... % C最小值
'popgmax', 100, ... % gamma最大值
'popgmin', 0.01 ... % gamma最小值
);
%% 粒子群初始化
% 种群初始化
for i = 1:pso_options.sizepop
% 随机初始化位置
pop(i,1) = (pso_options.popcmax - pso_options.popcmin) * rand() + pso_options.popcmin;
pop(i,2) = (pso_options.popgmax - pso_options.popgmin) * rand() + pso_options.popgmin;
% 随机初始化速度
V(i,1) = pso_options.vmax * randn();
V(i,2) = pso_options.vmax * randn();
% 计算初始适应度
fitness(i) = fitness_function([pop(i,1), pop(i,2)], train_data, train_label);
end
% 个体最佳和全局最佳
individual_best_fitness = fitness;
individual_best_position = pop;
[global_best_fitness, best_index] = max(fitness);
global_best_position = pop(best_index, :);
%% 粒子群迭代
for gen = 1:pso_options.maxgen
for i = 1:pso_options.sizepop
% 更新速度
V(i,1) = pso_options.w * V(i,1) + ...
pso_options.c1 * rand() * (individual_best_position(i,1) - pop(i,1)) + ...
pso_options.c2 * rand() * (global_best_position(1) - pop(i,1));
V(i,2) = pso_options.w * V(i,2) + ...
pso_options.c1 * rand() * (individual_best_position(i,2) - pop(i,2)) + ...
pso_options.c2 * rand() * (global_best_position(2) - pop(i,2));
% 速度边界检查
V(i,1) = min(max(V(i,1), -pso_options.vmax), pso_options.vmax);
V(i,2) = min(max(V(i,2), -pso_options.vmax), pso_options.vmax);
% 更新位置
pop(i,1) = pop(i,1) + V(i,1);
pop(i,2) = pop(i,2) + V(i,2);
% 位置边界检查
pop(i,1) = min(max(pop(i,1), pso_options.popcmin), pso_options.popcmax);
pop(i,2) = min(max(pop(i,2), pso_options.popgmin), pso_options.popgmax);
% 计算新适应度
fitness(i) = fitness_function([pop(i,1), pop(i,2)], train_data, train_label);
% 更新个体最优
if fitness(i) > individual_best_fitness(i)
individual_best_fitness(i) = fitness(i);
individual_best_position(i,:) = pop(i,:);
% 更新全局最优
if fitness(i) > global_best_fitness
global_best_fitness = fitness(i);
global_best_position = pop(i,:);
end
end
end
% 惯性权重衰减
pso_options.w = pso_options.w * pso_options.wdamp;
% 显示迭代信息
if mod(gen, 10) == 0
fprintf('迭代次数: %d, 最佳适应度: %.4f, C: %.4f, gamma: %.4f\n', ...
gen, global_best_fitness, global_best_position(1), global_best_position(2));
end
% 记录收敛过程
convergence(gen) = global_best_fitness;
end
%% 输出最终结果
bestc = global_best_position(1);
bestg = global_best_position(2);
bestacc = global_best_fitness;
% 使用最优参数在测试集上评估
final_model = svmtrain(train_label, train_data, sprintf('-c %.4f -g %.4f -q', bestc, bestg));
[predict_label, accuracy, ~] = svmpredict(test_label, test_data, final_model, '-q');
fprintf('\n=== 最终结果 ===\n');
fprintf('最优参数: C=%.4f, gamma=%.4f\n', bestc, bestg);
fprintf('验证集准确率: %.2f%%\n', bestacc * 100);
fprintf('测试集准确率: %.2f%%\n', accuracy(1));
% 绘制收敛曲线
figure;
plot(1:pso_options.maxgen, convergence, 'b-', 'LineWidth', 2);
xlabel('迭代次数');
ylabel('最佳适应度');
title('PSO-SVM收敛曲线');
grid on;
end
适应度函数:fitness_function.m
function accuracy = fitness_function(parameters, train_data, train_label)
% 适应度函数:使用交叉验证计算SVM分类准确率
% 输入:参数[C, gamma]、训练数据和标签
% 输出:交叉验证准确率
c = parameters(1);
g = parameters(2);
% 5折交叉验证
k = 5;
indices = crossvalind('Kfold', train_label, k);
cv_acc = zeros(k, 1);
for i = 1:k
test_idx = (indices == i);
train_idx = ~test_idx;
% 训练SVM模型
model = svmtrain(train_label(train_idx), train_data(train_idx, :), ...
sprintf('-c %f -g %f -q', c, g));
% 预测
[predict_label, acc, ~] = svmpredict(train_label(test_idx), ...
train_data(test_idx, :), model, '-q');
cv_acc(i) = acc(1) / 100; % 转换为0-1之间的值
end
% 平均准确率作为适应度值
accuracy = mean(cv_acc);
end
数据预处理函数:data_preprocessing.m
function [train_scaled, test_scaled] = data_preprocessing(train_data, test_data)
% 数据预处理:归一化到[0,1]范围
% 合并数据进行归一化
all_data = [train_data; test_data];
% 最小-最大归一化
min_vals = min(all_data, [], 1);
max_vals = max(all_data, [], 1);
% 避免除零
range_vals = max_vals - min_vals;
range_vals(range_vals == 0) = 1;
% 归一化
all_scaled = (all_data - min_vals) ./ range_vals;
% 分割回训练集和测试集
train_scaled = all_scaled(1:size(train_data,1), :);
test_scaled = all_scaled(size(train_data,1)+1:end, :);
end
主调用脚本:main_script.m
%% 基于PSO优化的SVM分类
clear; clc; close all;
%% 1. 加载数据(示例使用UCI数据集或自定义数据)
% 这里以随机生成数据为例,实际使用时请替换为您的数据
fprintf('加载数据...\n');
load('your_dataset.mat'); % 请替换为您的数据文件
% 如果没有数据文件,使用示例数据
if ~exist('train_data', 'var')
% 生成示例数据
rng(1); % 设置随机种子保证可重复性
[train_data, train_label, test_data, test_label] = generate_sample_data();
end
fprintf('数据维度: 训练集 %dx%d, 测试集 %dx%d\n', ...
size(train_data), size(test_data));
%% 2. 数据预处理
fprintf('数据预处理...\n');
[train_scaled, test_scaled] = data_preprocessing(train_data, test_data);
%% 3. PSO优化SVM参数
fprintf('开始PSO优化SVM参数...\n');
tic;
[bestc, bestg, bestacc] = PSO_SVM(train_scaled, train_label, test_scaled, test_label);
time_elapsed = toc;
fprintf('优化完成! 耗时: %.2f 秒\n', time_elapsed);
%% 4. 与传统网格搜索对比
fprintf('\n=== 与网格搜索对比 ===\n');
grid_search_result = grid_search_svm(train_scaled, train_label, test_scaled, test_label);
%% 5. 结果可视化
plot_comparison_results(bestc, bestg, bestacc, grid_search_result);
辅助函数
function [train_data, train_label, test_data, test_label] = generate_sample_data()
% 生成示例分类数据
n_samples = 1000;
n_features = 10;
% 生成两个类别的数据
class1_data = randn(n_samples/2, n_features) + 1;
class2_data = randn(n_samples/2, n_features) - 1;
train_data = [class1_data(1:400,:); class2_data(1:400,:)];
train_label = [ones(400,1); -ones(400,1)];
test_data = [class1_data(401:500,:); class2_data(401:500,:)];
test_label = [ones(100,1); -ones(100,1)];
end
function grid_result = grid_search_svm(train_data, train_label, test_data, test_label)
% 网格搜索作为对比
c_values = [0.1, 1, 10, 100, 1000];
g_values = [0.001, 0.01, 0.1, 1, 10];
best_acc = 0;
best_c = 1;
best_g = 0.1;
fprintf('网格搜索进度: ');
for i = 1:length(c_values)
for j = 1:length(g_values)
model = svmtrain(train_label, train_data, ...
sprintf('-c %f -g %f -q', c_values(i), g_values(j)));
[~, acc, ~] = svmpredict(test_label, test_data, model, '-q');
if acc(1) > best_acc
best_acc = acc(1);
best_c = c_values(i);
best_g = g_values(j);
end
end
fprintf('%.0f%% ', i/length(c_values)*100);
end
fprintf('\n');
grid_result = struct('bestc', best_c, 'bestg', best_g, 'bestacc', best_acc);
fprintf('网格搜索结果: C=%.4f, gamma=%.4f, 准确率=%.2f%%\n', ...
best_c, best_g, best_acc);
end
function plot_comparison_results(pso_c, pso_g, pso_acc, grid_result)
% 绘制对比结果
methods = {'PSO优化', '网格搜索'};
accuracy = [pso_acc*100, grid_result.bestacc];
c_values = [pso_c, grid_result.bestc];
g_values = [pso_g, grid_result.bestg];
figure('Position', [100, 100, 1200, 400]);
% 准确率对比
subplot(1,3,1);
bar(accuracy, 'FaceColor', [0.2, 0.6, 0.8]);
set(gca, 'XTickLabel', methods);
ylabel('准确率 (%)');
title('方法准确率对比');
grid on;
% 添加数值标签
for i = 1:length(accuracy)
text(i, accuracy(i)+1, sprintf('%.2f%%', accuracy(i)), ...
'HorizontalAlignment', 'center');
end
% 参数C对比
subplot(1,3,2);
semilogy(1:2, c_values, 'ro-', 'LineWidth', 2, 'MarkerSize', 8);
set(gca, 'XTick', 1:2, 'XTickLabel', methods);
ylabel('参数 C (log scale)');
title('参数C对比');
grid on;
% 参数gamma对比
subplot(1,3,3);
semilogy(1:2, g_values, 'bs-', 'LineWidth', 2, 'MarkerSize', 8);
set(gca, 'XTick', 1:2, 'XTickLabel', methods);
ylabel('参数 γ (log scale)');
title('参数gamma对比');
grid on;
sgtitle('PSO优化 vs 网格搜索 结果对比');
end
参考代码 基于粒子群算法和LibSVM库的支持向量机优化 www.3dddown.com/cna/82115.html
3. 使用说明
环境要求:
- MATLAB R2016b或更高版本
- LibSVM MATLAB接口
- 统计和机器学习工具箱
安装LibSVM:
% 下载LibSVM并编译
if ~exist('svmpredict', 'file')
% 下载LibSVM
urlwrite('https://www.csie.ntu.edu.tw/~cjlin/libsvm/libsvm-3.32.zip', 'libsvm.zip');
unzip('libsvm.zip');
cd libsvm-3.32/matlab;
make;
addpath(pwd);
cd ../..;
end
参数调优建议:
-
PSO参数:
- 种群规模:20-50
- 迭代次数:30-100
- 学习因子:c1=1.5, c2=1.7
- 惯性权重:0.4-0.9
-
SVM参数范围:
- C: [0.01, 10000]
- γ: [0.001, 1000]
4. 优势分析
- 全局搜索能力:PSO能够避免陷入局部最优
- 收敛速度快:相比网格搜索,计算效率更高
- 自适应调整:惯性权重衰减提高后期搜索精度
- 适用性广:适用于各种类型的SVM核函数
这种方法特别适合处理高维数据和大规模数据集,能够有效找到SVM的最优参数组合。
浙公网安备 33010602011771号