基于粒子群算法(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

参数调优建议:

  1. PSO参数

    • 种群规模:20-50
    • 迭代次数:30-100
    • 学习因子:c1=1.5, c2=1.7
    • 惯性权重:0.4-0.9
  2. SVM参数范围

    • C: [0.01, 10000]
    • γ: [0.001, 1000]

4. 优势分析

  1. 全局搜索能力:PSO能够避免陷入局部最优
  2. 收敛速度快:相比网格搜索,计算效率更高
  3. 自适应调整:惯性权重衰减提高后期搜索精度
  4. 适用性广:适用于各种类型的SVM核函数

这种方法特别适合处理高维数据和大规模数据集,能够有效找到SVM的最优参数组合。

posted @ 2025-12-18 09:17  晃悠人生  阅读(3)  评论(0)    收藏  举报