Implementação de LSSVR Otimizada pelo Algoritmo do Lobo Cinzento em MATLAB

Classe principal para otimização de parâmetros

classdef OtimizadorLSSVR_GWO
    properties
        ParamRegularizacao;  
        ParamRBF;
        DadosTreino;
        RotulosTreino;
        DadosTeste;
        RotulosTeste;
        Modelo;
        HistoricoAptidao;
    end
    
    methods
        function obj = OtimizadorLSSVR_GWO(X_treino, y_treino, X_teste, y_teste)
            obj.DadosTreino = X_treino;
            obj.RotulosTreino = y_treino;
            obj.DadosTeste = X_teste;
            obj.RotulosTeste = y_teste;
            obj.HistoricoAptidao = [];
        end
        
        function [C_otimo, gamma_otimo] = treinar(obj, numLobos, iterMax)
            dim = 2;                    
            limInf = [0.1, 0.01];       
            limSup = [1000, 100];       
            
            lobos = inicializarLobos(numLobos, dim, limInf, limSup);
            posAlpha = zeros(1, dim);   
            aptAlpha = inf;             
            posBeta = zeros(1, dim);    
            aptBeta = inf;              
            posDelta = zeros(1, dim);   
            aptDelta = inf;             
            
            for it = 1:iterMax
                a = 2 - it * (2 / iterMax);
                
                for i = 1:numLobos
                    lobos(i, :) = verificarLimites(lobos(i, :), limInf, limSup);
                    aptidao = obj.calcularAptidao(lobos(i, 1), lobos(i, 2));
                    
                    if aptidao < aptAlpha
                        aptAlpha = aptidao;
                        posAlpha = lobos(i, :);
                    end
                    
                    if aptidao > aptAlpha && aptidao < aptBeta
                        aptBeta = aptidao;
                        posBeta = lobos(i, :);
                    end
                    
                    if aptidao > aptBeta && aptidao < aptDelta
                        aptDelta = aptidao;
                        posDelta = lobos(i, :);
                    end
                end
                
                for i = 1:numLobos
                    for j = 1:dim
                        r1 = rand();
                        r2 = rand();
                        A_alpha = 2*a*r1 - a;
                        C_alpha = 2*r2;
                        D_alpha = abs(C_alpha*posAlpha(j) - lobos(i, j));
                        X1 = posAlpha(j) - A_alpha*D_alpha;
                        
                        r1 = rand();
                        r2 = rand();
                        A_beta = 2*a*r1 - a;
                        C_beta = 2*r2;
                        D_beta = abs(C_beta*posBeta(j) - lobos(i, j));
                        X2 = posBeta(j) - A_beta*D_beta;
                        
                        r1 = rand();
                        r2 = rand();
                        A_delta = 2*a*r1 - a;
                        C_delta = 2*r2;
                        D_delta = abs(C_delta*posDelta(j) - lobos(i, j));
                        X3 = posDelta(j) - A_delta*D_delta;
                        
                        lobos(i, j) = (X1 + X2 + X3) / 3;
                    end
                end
                
                obj.HistoricoAptidao(it) = aptAlpha;
                
                if mod(it, 10) == 0
                    fprintf('Iteração %d: Melhor Aptidão = %.4f, C = %.4f, gamma = %.4f\n', ...
                        it, aptAlpha, posAlpha(1), posAlpha(2));
                end
            end
            
            C_otimo = posAlpha(1);
            gamma_otimo = posAlpha(2);
            obj.ParamRegularizacao = C_otimo;
            obj.ParamRBF = gamma_otimo;
            obj.Modelo = obj.construirLSSVR(C_otimo, gamma_otimo);
        end
        
        function aptidao = calcularAptidao(obj, C, gamma)
            modelo = obj.construirLSSVR(C, gamma);
            predicoes = obj.prever(modelo, obj.DadosTeste);
            eqm = mean((obj.RotulosTeste - predicoes).^2);
            aptidao = eqm;
        end
        
        function modelo = construirLSSVR(obj, C, gamma)
            sigma = 1/sqrt(2*gamma);
            n = size(obj.DadosTreino, 1);
            K = zeros(n, n);
            for i = 1:n
                for j = 1:n
                    diferenca = obj.DadosTreino(i, :) - obj.DadosTreino(j, :);
                    K(i, j) = exp(-norm(diferenca)^2/(2*sigma^2));
                end
            end
            
            Omega = [K + eye(n)/C, ones(n, 1); ones(1, n), 0];
            Y = [obj.RotulosTreino; 0];
            solucao = Omega \ Y;
            alfa = solucao(1:n);
            bias = solucao(n+1);
            
            modelo.alfa = alfa;
            modelo.bias = bias;
            modelo.DadosTreino = obj.DadosTreino;
            modelo.sigma = sigma;
        end
        
        function predicoes = prever(obj, modelo, X)
            n_treino = size(modelo.DadosTreino, 1);
            n_teste = size(X, 1);
            predicoes = zeros(n_teste, 1);
            
            for i = 1:n_teste
                soma = 0;
                for j = 1:n_treino
                    diff = X(i, :) - modelo.DadosTreino(j, :);
                    k = exp(-norm(diff)^2/(2*modelo.sigma^2));
                    soma = soma + modelo.alfa(j)*k;
                end
                predicoes(i) = soma + modelo.bias;
            end
        end
        
        function visualizarResultados(obj)
            figure;
            subplot(2, 2, 1);
            plot(obj.HistoricoAptidao, 'LineWidth', 2);
            title('Convergência da Otimização');
            xlabel('Iterações');
            ylabel('EQM');
            grid on;
            
            predicoes = obj.prever(obj.Modelo, obj.DadosTeste);
            subplot(2, 2, 2);
            plot(obj.RotulosTeste, 'b-o', 'LineWidth', 1.5);
            hold on;
            plot(predicoes, 'r-*', 'LineWidth', 1.5);
            title('Comparação de Valores Reais e Preditos');
            xlabel('Amostras');
            ylabel('Valor');
            legend('Reais', 'Preditos');
            grid on;
            
            subplot(2, 2, 3);
            erros = obj.RotulosTeste - predicoes;
            histogram(erros, 20);
            title('Distribuição de Erros');
            xlabel('Erro de Predição');
            ylabel('Frequência');
            grid on;
            
            subplot(2, 2, 4);
            r2 = 1 - sum((obj.RotulosTeste - predicoes).^2)/sum((obj.RotulosTeste - mean(obj.RotulosTeste)).^2);
            text(0.1, 0.8, sprintf('C ótimo: %.4f', obj.ParamRegularizacao), 'FontSize', 12);
            text(0.1, 0.6, sprintf('Gamma ótimo: %.4f', obj.ParamRBF), 'FontSize', 12);
            text(0.1, 0.4, sprintf('EQM: %.4f', mean(erros.^2)), 'FontSize', 12);
            text(0.1, 0.2, sprintf('R²: %.4f', r2), 'FontSize', 12);
            axis off;
            title('Métricas Finais');
        end
    end
end

function lobos = inicializarLobos(numLobos, dim, limInf, limSup)
    lobos = zeros(numLobos, dim);
    for i = 1:dim
        lobos(:, i) = limInf(i) + (limSup(i) - limInf(i)) * rand(numLobos, 1);
    end
end

function x = verificarLimites(x, limInf, limSup)
    for i = 1:length(x)
        if x(i) < limInf(i)
            x(i) = limInf(i);
        elseif x(i) > limSup(i)
            x(i) = limSup(i);
        end
    end
end

Exemplo de aplicação

% Configuração de dados
amostras = 300;
caracteristicas = 4;
X = rand(amostras, caracteristicas) * 8;
y = 2*sin(X(:,1)) + 0.7*cos(3*X(:,2)) + 0.4*X(:,3).^2 + randn(amostras, 1)*0.2;

% Divisão de dados
indices = randperm(amostras);
treinoIdx = indices(1:240);
testeIdx = indices(241:end);
X_treino = X(treinoIdx, :);
y_treino = y(treinoIdx);
X_teste = X(testeIdx, :);
y_teste = y(testeIdx);

% Criação e treinamento
otimizador = OtimizadorLSSVR_GWO(X_treino, y_treino, X_teste, y_teste);
[C_otimo, gamma_otimo] = otimizador.treinar(25, 80);

% Visualização
otimizador.visualizarResultados();

Recomendações técnicas

  • Parâmetros do GWO: Utilize 20-50 partículas e 50-300 iterações
  • Espaço de busca: Para problemas complexos, defina C ∈ [1, 2000] e gamma ∈ [0.05, 150]
  • Pré-processamento: Normalize os dados para melhor convergência
  • Kernels alternativos: Implemente funções lineares ou polinomiais

Extensões avançadas

% Exemplo de kernel composto
function modelo = kernelCombinado(obj, C, gamma1, gamma2, peso)
    n = size(obj.DadosTreino, 1);
    K1 = zeros(n, n);
    K2 = zeros(n, n);
    
    for i = 1:n
        for j = 1:n
            diff = obj.DadosTreino(i, :) - obj.DadosTreino(j, :);
            K1(i, j) = exp(-norm(diff)^2/(2*gamma1));
            K2(i, j) = (obj.DadosTreino(i, :) * obj.DadosTreino(j, :)')^3;
        end
    end
    K = peso * K1 + (1-peso) * K2;
    % Restante da implementação...
end

% Exemplo de paralelização
function aptidoes = avaliacaoParalela(obj, lobos)
    numLobos = size(lobos, 1);
    aptidoes = zeros(numLobos, 1);
    parfor i = 1:numLobos
        modelo = obj.construirLSSVR(lobos(i,1), lobos(i,2));
        pred = obj.prever(modelo, obj.DadosTeste);
        aptidoes(i) = mean((obj.RotulosTeste - pred).^2);
    end
end

Tags: LSSVR GWO MATLAB Otimização regressão

Publicado em 6-2 19:30 por Thomas