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