Code source de BsplineQuantRegpy.examples.example_temperature

#!/usr/bin/env python
# -*- coding: utf-8 -*-

"""
Script d'analyse des données de température avec différentes contraintes et quantiles.
Peut être exécuté indépendamment ou appelé depuis la GUI.
"""

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import os
import sys

# Ajouter le chemin du projet si exécuté indépendamment
#if __name__ == "__main__":
#    PROJECT_ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
#    SRC_PATH = os.path.join(PROJECT_ROOT, 'src')
#    if SRC_PATH not in sys.path:
#        sys.path.insert(0, SRC_PATH)

from BsplineQuantRegpy import quantile_spline




def load_temperature_data(data_path=None):
    """Charge les données de température."""
    if data_path is None:
        possible_paths = [
            os.path.join(os.path.dirname(__file__), 'temp.xls'),
            os.path.join(os.path.dirname(__file__), '..', 'data', 'temp.xls'),
            'temp.xls',
        ]
        for p in possible_paths:
            if os.path.exists(p):
                data_path = p
                break
    
    if data_path is None or not os.path.exists(data_path):
        raise FileNotFoundError(f"Fichier temp.xls non trouvé")
    
    temp = (pd.read_excel(data_path)).values
    
    return temp


[docs] def run_temperature_analysis(degree=3, tau = [0.1, 0.25, 0.5, 0.75, 0.9], solver='CLARABEL'): """ Lance une analyse complète des données de température avec différentes contraintes pour plusieurs quantiles. Parameters ---------- degree : int Degré de la spline (1, 2, 3, 4) tau : list of floats Les quantiles à évaluer. solver : str Solveur à utiliser """ print("=" * 70) print("ANALYSE DES TEMPÉRATURES - RÉGRESSION QUANTILE CONTRAINTE") print("=" * 70) print(f"Degré: {degree}, Solveur: {solver}") print("Quantiles: 0.1, 0.25, 0.5, 0.75, 0.9") print("=" * 70) # Charger les données try: temp_val = load_temperature_data() except FileNotFoundError as e: print(f"❌ Erreur: {e}") return year = temp_val[:, 0] ytab = temp_val[:, 1] # Normalisation xtab = (year - year[0]) / (year[-1] - year[0]) # Nœuds spécifiques pour l'étude des tendances year_knots = np.array([1880, 1889, 1900, 1910, 1930, 1940, 1965, 1992]) knots = (year_knots - 1880) / (1992 - 1880) def yr(x): return 1880 + x * (1992 - 1880) # Quantiles à afficher defaut quantiles = tau colors = ['blue', 'cyan', 'green', 'orange', 'red'] # Créer la figure fig, axes = plt.subplots(2, 3, figsize=(18, 10)) x_eval = np.linspace(0, 1, 500) # Vérifier que les modules sont disponibles if quantile_spline is None: print("❌ Module quantile_spline non disponible") return # ============================================ # 1. Sans contraintes # ============================================ ax = axes[0, 0] ax.scatter(yr(xtab), ytab, alpha=0.3, s=10, color='gray', label='Données') ax.set_title('1. Sans contraintes') ax.set_xlabel('Année') ax.set_ylabel('Δ Température (°C)') for tau, color in zip(quantiles, colors): try: res = quantile_spline(xtab, ytab, knots, tau, degree=degree, monot=0, cv=0, der3=0, solver=solver) if res is not None: ax.plot(yr(x_eval), res(x_eval), color=color, linewidth=1.5, label=f'τ={tau}') except Exception as e: print(f"Erreur sans contrainte τ={tau}: {e}") ax.plot(yr(knots), np.ones_like(knots)*max(ytab)*0.9, 'k|', markersize=6, label='Nœuds') ax.legend(fontsize='small', ncol=2) ax.grid(True, alpha=0.3) # ============================================ # 2. Contrainte croissante partout # ============================================ ax = axes[0, 1] ax.scatter(yr(xtab), ytab, alpha=0.3, s=10, color='gray', label='Données') ax.set_title('2. Contrainte croissante') ax.set_xlabel('Année') ax.set_ylabel('Δ Température (°C)') for tau, color in zip(quantiles, colors): try: res = quantile_spline(xtab, ytab, knots, tau, degree=degree, monot=1, cv=0, der3=0, solver=solver) if res is not None: ax.plot(yr(x_eval), res(x_eval), color=color, linewidth=1.5, label=f'τ={tau}') except Exception as e: print(f"Erreur croissante τ={tau}: {e}") ax.plot(yr(knots), np.ones_like(knots)*max(ytab)*0.9, 'k|', markersize=6, label='Nœuds') ax.legend(fontsize='small', ncol=2) ax.grid(True, alpha=0.3) # ============================================ # 3. Contrainte décroissante (contre-nature) # ============================================ ax = axes[0, 2] ax.scatter(yr(xtab), ytab, alpha=0.3, s=10, color='gray', label='Données') ax.set_title('3. Contrainte décroissante') ax.set_xlabel('Année') ax.set_ylabel('Δ Température (°C)') for tau, color in zip(quantiles, colors): try: res = quantile_spline(xtab, ytab, knots, tau, degree=degree, monot=-1, cv=0, der3=0, solver=solver) if res is not None: ax.plot(yr(x_eval), res(x_eval), color=color, linewidth=1.5, label=f'τ={tau}') except Exception as e: print(f"Erreur décroissante τ={tau}: {e}") ax.plot(yr(knots), np.ones_like(knots)*max(ytab)*0.9, 'k|', markersize=6, label='Nœuds') ax.legend(fontsize='small', ncol=2) ax.grid(True, alpha=0.3) # ============================================ # 4. Contrainte croissante + convexe # ============================================ ax = axes[1, 0] ax.scatter(yr(xtab), ytab, alpha=0.3, s=10, color='gray', label='Données') ax.set_title('4. Croissante + Convexe') ax.set_xlabel('Année') ax.set_ylabel('Δ Température (°C)') for tau, color in zip(quantiles, colors): try: res = quantile_spline(xtab, ytab, knots, tau, degree=degree, monot=1, cv=1, der3=0, solver=solver) if res is not None: ax.plot(yr(x_eval), res(x_eval), color=color, linewidth=1.5, label=f'τ={tau}') except Exception as e: print(f"Erreur croissante+convexe τ={tau}: {e}") ax.plot(yr(knots), np.ones_like(knots)*max(ytab)*0.9, 'k|', markersize=6, label='Nœuds') ax.legend(fontsize='small', ncol=2) ax.grid(True, alpha=0.3) # ============================================ # 5. Contrainte partielle (décroissante sur 1940-1965) # ============================================ ax = axes[1, 1] ax.scatter(yr(xtab), ytab, alpha=0.3, s=10, color='gray', label='Données') ax.set_title('5. Contrainte partielle croissante \n sauf 1940-1965: décroissante)') ax.set_xlabel('Année') ax.set_ylabel('Δ Température (°C)') # Contrainte: décroissante sur l'intervalle 1940-1965 monot_partiel = [1, 1, 1, 1, 1, -1, 1] # Colorier la zone 1940-1965 (une fois) ax.axvspan(1940, 1965, alpha=0.15, color='yellow', label='Zone décroissante') for tau, color in zip(quantiles, colors): try: res = quantile_spline(xtab, ytab, knots, tau, degree=degree, monot=monot_partiel, cv=0, der3=0, solver=solver) if res is not None: ax.plot(yr(x_eval), res(x_eval), color=color, linewidth=1.5, label=f'τ={tau}') except Exception as e: print(f"Erreur partielle τ={tau}: {e}") ax.plot(yr(knots), np.ones_like(knots)*max(ytab)*0.9, 'k|', markersize=6, label='Nœuds') ax.legend(fontsize='small', ncol=2) ax.grid(True, alpha=0.3) # ============================================ # 6. Comparaison des contraintes (τ=0.5) # ============================================ ax = axes[1, 2] ax.scatter(yr(xtab), ytab, alpha=0.3, s=10, color='gray', label='Données') ax.set_title('6. Comparaison des contraintes (τ=0.5)') ax.set_xlabel('Année') ax.set_ylabel('Δ Température (°C)') tau_mid = 0.5 configs = [ (0, 0, 'blue', 'Sans contrainte'), (1, 0, 'green', 'Croissante'), (-1, 0, 'red', 'Décroissante'), (1, 1, 'magenta', 'C+Convexe'), (monot_partiel, 0, 'cyan', 'Partielle'), ] for monot, cv_val, color, label in configs: try: res = quantile_spline(xtab, ytab, knots, tau_mid, degree=degree, monot=monot, cv=cv_val, der3=0, solver=solver) if res is not None: ax.plot(yr(x_eval), res(x_eval), color=color, linewidth=2, label=label) except Exception as e: print(f"Erreur pour {label}: {e}") ax.plot(yr(knots), np.ones_like(knots)*max(ytab)*0.9, 'k|', markersize=6, label='Nœuds') ax.legend(fontsize='small') ax.grid(True, alpha=0.3) # Titre général fig.suptitle(f'Analyse des températures - Régression quantile (degré {degree})', fontsize=14, fontweight='bold') plt.tight_layout() plt.show() print("\n" + "=" * 70) print("ANALYSE TERMINÉE") print("=" * 70)
def main(): """Fonction principale pour exécution indépendante.""" import argparse parser = argparse.ArgumentParser(description='Analyse des températures avec splines contraintes') parser.add_argument('--degree', type=int, default=3, choices=[1, 2, 3, 4], help='Degré de la spline (1, 2, 3, 4)') parser.add_argument('--solver', type=str, default='CLARABEL', help='Solveur à utiliser') parser.add_argument('--tau ', type=str, default=[0.1,0.3,0.5,0.7,0.9], help='quantiles à afficher') args = parser.parse_args() run_temperature_analysis(degree=args.degree, solver=args.solver) if __name__ == "__main__": main()