Text Share Online

%% =========================================================
% SVR MPPT – Entraînement complet avec 4 noyaux
% Données : (T, E) → D_MPP
% Noyaux : Linéaire | Gaussien (RBF) | Quadratique | Cubique
% Auteurs : HMIDOUCH – IGROUANE – EL OGRI
%% =========================================================
clc; clear; close all;

%% ── 1. CHARGEMENT DES DONNÉES ──────────────────────────────
raw = readmatrix(‘intervalle_de_moncef_Après_nettoyage.xlsx’, …
‘Range’, ‘E3:G212’, … % colonnes T, E, D (ligne 3 → 212)
‘NumHeaderLines’, 0);

% Supprimer les lignes avec NaN
raw(any(isnan(raw), 2), 🙂 = [];

T_data = raw(:, 1); % Température [°C]
E_data = raw(:, 2); % Irradiance [W/m²]
D_data = raw(:, 3); % Duty Cycle [-]

X = [T_data, E_data]; % matrice d’entrées (209×2)
y = D_data; % vecteur de sortie (209×1)

fprintf(‘Données chargées : %d pointsn’, size(X,1));
fprintf(‘T : [%.0f – %.0f] °Cn’, min(T_data), max(T_data));
fprintf(‘E : [%.0f – %.0f] W/m²n’, min(E_data), max(E_data));
fprintf(‘D : [%.3f – %.3f]nn’, min(y), max(y));

%% ── 2. NORMALISATION MIN-MAX → [0, 1] ────────────────────
% CORRECTION CLÉE : sans cette étape, E (max 1000) domine
% complètement T (max 50) dans le calcul de distance RBF
% → le modèle prédit une constante ≈ 0.5 (R² ≈ 0.02)

X_min = min(X); X_max = max(X);
y_min = min(y); y_max = max(y);

X_norm = (X – X_min) ./ (X_max – X_min);
y_norm = (y – y_min) ./ (y_max – y_min);

%% ── 3. SPLIT TRAIN / TEST (80 % / 20 %) ─────────────────
rng(42);
n = size(X_norm, 1);
idx = randperm(n);
n_tr = round(0.8 * n);

X_tr = X_norm(idx(1:n_tr), :);
y_tr = y_norm(idx(1:n_tr));
X_te = X_norm(idx(n_tr+1:end), :);
y_te = y_norm(idx(n_tr+1:end));

% Conserver les valeurs originales pour les graphes
y_te_orig = y(idx(n_tr+1:end));
X_te_orig = X(idx(n_tr+1:end), :);

fprintf(‘Train : %d points | Test : %d pointsnn’, n_tr, n-n_tr);

%% ── 4. DÉFINITION DES 4 MODÈLES SVR ──────────────────────
% Paramètres adaptés après normalisation :
% C = 100 → pénalité élevée pour précision
% epsilon = 0.001 → bande insensible étroite (D normalisé ∈ [0,1])
% KernelScale = ‘auto’ pour linéaire/poly, optimisé pour RBF

kernels = {‘linear’, ‘gaussian’, ‘polynomial’, ‘polynomial’};
degrees = [NaN, NaN, 2, 3];
labels = {‘Linéaire’, ‘Gaussien (RBF)’, ‘Quadratique (d=2)’, ‘Cubique (d=3)’};
colors = {‘#185FA5’, ‘#1D9E75’, ‘#BA7517’, ‘#A32D2D’};

models = cell(4, 1);

for k = 1:4
fprintf(‘Entraînement : %s …n’, labels{k});
if strcmp(kernels{k}, ‘linear’)
mdl = fitrsvm(X_tr, y_tr, …
‘KernelFunction’, ‘linear’, …
‘BoxConstraint’, 100, …
‘Epsilon’, 0.001, …
‘Standardize’, false); % déjà normalisé

elseif strcmp(kernels{k}, ‘gaussian’)
mdl = fitrsvm(X_tr, y_tr, …
‘KernelFunction’, ‘rbf’, …
‘BoxConstraint’, 100, …
‘Epsilon’, 0.001, …
‘KernelScale’, ‘auto’, …
‘Standardize’, false);

else % polynomial
mdl = fitrsvm(X_tr, y_tr, …
‘KernelFunction’, ‘polynomial’, …
‘PolynomialOrder’, degrees(k), …
‘BoxConstraint’, 100, …
‘Epsilon’, 0.001, …
‘Standardize’, false);
end
models{k} = mdl;
end
fprintf(‘n’);

%% ── 5. ÉVALUATION DES MODÈLES ────────────────────────────
results = struct();

for k = 1:4
% Prédiction (espace normalisé → retour espace original)
y_pred_norm = predict(models{k}, X_te);
y_pred = y_pred_norm * (y_max – y_min) + y_min;

% Métriques
residuals = y_te_orig – y_pred;
SS_res = sum(residuals.^2);
SS_tot = sum((y_te_orig – mean(y_te_orig)).^2);

results(k).label = labels{k};
results(k).y_pred = y_pred;
results(k).R2 = 1 – SS_res / SS_tot;
results(k).RMSE = sqrt(mean(residuals.^2));
results(k).MAE = mean(abs(residuals));
results(k).MSE = mean(residuals.^2);
results(k).residuals= residuals;

fprintf(‘%-22s | R²=%.4f | RMSE=%.4f | MAE=%.4fn’, …
labels{k}, results(k).R2, results(k).RMSE, results(k).MAE);
end
fprintf(‘n’);

%% ── 6. FIGURE 1 : Prédiction vs Réalité (4 sous-graphes) ─
figure(‘Name’,’Prédiction vs Réalité’,’NumberTitle’,’off’, …
‘Position’, [50 50 1200 900]);

for k = 1:4
subplot(2, 2, k);
hold on; grid on; box on;

% Ligne de référence parfaite
d_range = [min(y_te_orig)-0.02, max(y_te_orig)+0.02];
plot(d_range, d_range, ‘k–‘, ‘LineWidth’, 1.5, …
‘DisplayName’,’Prédiction parfaite’);

% Points de prédiction
scatter(y_te_orig, results(k).y_pred, 40, colors{k}, …
‘filled’, ‘MarkerFaceAlpha’, 0.7, …
‘DisplayName’, sprintf(‘R²=%.4f’, results(k).R2));

xlabel(‘D réel’, ‘FontSize’, 11);
ylabel(‘D prédit’, ‘FontSize’, 11);
title(sprintf(‘Noyau %s’, labels{k}), ‘FontSize’, 12, ‘FontWeight’, ‘bold’);
legend(‘Location’,’northwest’, ‘FontSize’, 9);
xlim(d_range); ylim(d_range);

% Annotation métriques
txt = sprintf(‘R² = %.4fnRMSE = %.4fnMAE = %.4f’, …
results(k).R2, results(k).RMSE, results(k).MAE);
annotation_x = d_range(1) + 0.02*(d_range(2)-d_range(1));
annotation_y = d_range(2) – 0.05*(d_range(2)-d_range(1));
text(annotation_x, annotation_y, txt, …
‘FontSize’, 9, ‘VerticalAlignment’,’top’, …
‘BackgroundColor’,’white’, ‘EdgeColor’,’#cccccc’);
end
sgtitle(‘Prédiction vs Réalité — 4 noyaux SVR’, …
‘FontSize’, 14, ‘FontWeight’, ‘bold’);

%% ── 7. FIGURE 2 : Résidus (4 sous-graphes) ───────────────
figure(‘Name’,’Analyse des Résidus’,’NumberTitle’,’off’, …
‘Position’, [100 100 1200 900]);

for k = 1:4
subplot(2, 2, k);
hold on; grid on; box on;

% Ligne zéro
d_range = [min(y_te_orig)-0.02, max(y_te_orig)+0.02];
plot(d_range, [0 0], ‘k–‘, ‘LineWidth’, 1.2);

% Bande ±RMSE
fill([d_range(1) d_range(2) d_range(2) d_range(1)], …
[-results(k).RMSE -results(k).RMSE results(k).RMSE results(k).RMSE], …
colors{k}, ‘FaceAlpha’, 0.1, ‘EdgeColor’, ‘none’);

% Points résidus
scatter(y_te_orig, results(k).residuals, 35, colors{k}, …
‘filled’, ‘MarkerFaceAlpha’, 0.7);

xlabel(‘D réel’, ‘FontSize’, 11);
ylabel(‘Résidu (réel − prédit)’, ‘FontSize’, 11);
title(sprintf(‘Résidus — %s’, labels{k}), ‘FontSize’, 12, ‘FontWeight’, ‘bold’);
xlim(d_range);

% Annotation
txt = sprintf(‘RMSE = %.4fnMAE = %.4f’, results(k).RMSE, results(k).MAE);
text(d_range(1)+0.01, max(results(k).residuals)*0.85, txt, …
‘FontSize’, 9, ‘BackgroundColor’,’white’,’EdgeColor’,’#cccccc’);
end
sgtitle(‘Analyse des résidus — 4 noyaux SVR’, …
‘FontSize’, 14, ‘FontWeight’, ‘bold’);

%% ── 8. FIGURE 3 : Surface 3D prédite par chaque noyau ────
T_grid = linspace(0, 50, 40);
E_grid = linspace(100, 1000, 40);
[TT, EE] = meshgrid(T_grid, E_grid);
X_grid_orig = [TT(:), EE(:)];
X_grid_norm = (X_grid_orig – X_min) ./ (X_max – X_min);

figure(‘Name’,’Surfaces 3D prédites’,’NumberTitle’,’off’, …
‘Position’, [150 50 1300 950]);

for k = 1:4
D_grid_norm = predict(models{k}, X_grid_norm);
D_grid = reshape(D_grid_norm * (y_max – y_min) + y_min, size(TT));

subplot(2, 2, k);
surf(TT, EE, D_grid, ‘EdgeColor’,’none’, ‘FaceAlpha’, 0.85);
colormap(gca, parula);
colorbar;
hold on;

% Superposer les points mesurés
scatter3(T_data, E_data, D_data, 20, ‘k’, ‘filled’, ‘MarkerFaceAlpha’, 0.5);

xlabel(‘T [°C]’, ‘FontSize’, 10);
ylabel(‘E [W/m²]’, ‘FontSize’, 10);
zlabel(‘D_{MPP}’, ‘FontSize’, 10);
title(sprintf(‘Surface — %sn(R²=%.4f)’, labels{k}, results(k).R2), …
‘FontSize’, 11, ‘FontWeight’, ‘bold’);
view(45, 30);
grid on;
end
sgtitle(‘Surfaces D = f(T, E) prédites — 4 noyaux SVR’, …
‘FontSize’, 14, ‘FontWeight’, ‘bold’);

%% ── 9. FIGURE 4 : Comparaison finale des métriques ───────
figure(‘Name’,’Comparaison des noyaux’,’NumberTitle’,’off’, …
‘Position’, [200 100 1100 750]);

metric_names = {‘R²’, ‘RMSE’, ‘MAE’, ‘MSE’};
metric_vals = zeros(4, 4);
for k = 1:4
metric_vals(k,:) = [results(k).R2, results(k).RMSE, …
results(k).MAE, results(k).MSE];
end

short_labels = {‘Linéaire’,’Gaussien’,’Quad.’,’Cubique’};
bar_colors_rgb = [
0.094, 0.373, 0.647; % blue
0.114, 0.620, 0.459; % green
0.729, 0.459, 0.090; % amber
0.639, 0.176, 0.176]; % red

for m = 1:4
subplot(2, 2, m);
b = bar(metric_vals(:, m), ‘FaceColor’, ‘flat’);
for k = 1:4
b.CData(k,:) = bar_colors_rgb(k,:);
end
set(gca, ‘XTickLabel’, short_labels, ‘XTickLabelRotation’, 15, …
‘FontSize’, 10);
ylabel(metric_names{m}, ‘FontSize’, 11);
title(sprintf(‘Comparaison — %s’, metric_names{m}), …
‘FontSize’, 12, ‘FontWeight’, ‘bold’);
grid on; box on;

% Annoter les valeurs au-dessus de chaque barre
for k = 1:4
v = metric_vals(k, m);
text(k, v + 0.002 * max(metric_vals(:,m)), sprintf(‘%.4f’, v), …
‘HorizontalAlignment’,’center’, ‘FontSize’, 9, ‘FontWeight’,’bold’);
end
end
sgtitle(‘Tableau de bord — Comparaison des 4 noyaux’, …
‘FontSize’, 14, ‘FontWeight’, ‘bold’);

%% ── 10. TABLEAU RÉCAPITULATIF (console) ──────────────────
fprintf(‘n══════════════════════════════════════════════════════n’);
fprintf(‘ TABLEAU DE COMPARAISON FINAL DES 4 NOYAUXn’);
fprintf(‘══════════════════════════════════════════════════════n’);
fprintf(‘%-22s | %6s | %6s | %6s | %8sn’,’Noyau’,’R²’,’RMSE’,’MAE’,’MSE’);
fprintf(‘──────────────────────────────────────────────────────n’);
for k = 1:4
flag = ”;
if results(k).R2 == max([results.R2]), flag = ‘ ← MEILLEUR’; end
fprintf(‘%-22s | %6.4f | %6.4f | %6.4f | %8.6f%sn’, …
results(k).label, results(k).R2, results(k).RMSE, …
results(k).MAE, results(k).MSE, flag);
end
fprintf(‘══════════════════════════════════════════════════════nn’);

%% ── 11. FIGURE 5 : Comparaison R² + RMSE (radar-style) ───
figure(‘Name’,’R² vs RMSE’,’NumberTitle’,’off’, …
‘Position’,[250 150 700 450]);

subplot(1,2,1);
b = barh(metric_vals(:,1), ‘FaceColor’,’flat’);
for k=1:4, b.CData(k,:)=bar_colors_rgb(k,:); end
set(gca,’YTickLabel’,short_labels,’FontSize’,10);
xlabel(‘R²’,’FontSize’,11); title(‘R² par noyau’,’FontWeight’,’bold’);
xlim([0 1.05]); grid on;
for k=1:4
text(metric_vals(k,1)+0.01,k,sprintf(‘%.4f’,metric_vals(k,1)),’FontSize’,9,’FontWeight’,’bold’);
end

subplot(1,2,2);
b = barh(metric_vals(:,2),’FaceColor’,’flat’);
for k=1:4, b.CData(k,:)=bar_colors_rgb(k,:); end
set(gca,’YTickLabel’,short_labels,’FontSize’,10);
xlabel(‘RMSE’,’FontSize’,11); title(‘RMSE par noyau (↓ mieux)’,’FontWeight’,’bold’);
grid on;
for k=1:4
text(metric_vals(k,2)+0.001,k,sprintf(‘%.4f’,metric_vals(k,2)),’FontSize’,9,’FontWeight’,’bold’);
end
sgtitle(‘Synthèse : R² et RMSE des 4 noyaux SVR’,’FontSize’,13,’FontWeight’,’bold’);

fprintf(‘Terminé ! 5 figures générées.n’);

  • none/plain text
  • 1h
Share This: