Exercise 001_08

Cahier des charges

1
# 001_08 — Simulation et extrapolation des données
2
3
## Objectifs
4
- Générer des données supplémentaires par extrapolation
5
- Prédire N(i+1) à N(i+k) avec différents modèles
6
- Comparer modèle théorique vs données observées
7
- Calculer des intervalles de confiance
8
9
## Structure des feuilles
10
11
### Feuille "do_observed"
12
Données observées d'origine :
13
- i, ttf(i), dN(i), N(i)
14
- 10 points (i=0 à i=9)
15
16
### Feuille "do_extrapolated"
17
Données extrapolées :
18
- Extension jusqu'à i=20
19
- Colonnes : i, ttf_extrap(i), N_extrap(i)
20
- Plusieurs méthodes d'extrapolation
21
22
### Feuille "do_models"
23
Comparaison de modèles :
24
- Colonnes : i, N_observed, N_linear, N_expo, N_weibull
25
- Modèle linéaire : N(i) = N(0) - k×i
26
- Modèle exponentiel : N(i) = N(0) × exp(-λ×t)
27
- Modèle de Weibull : N(i) = N(0) × exp(-(t/η)^β)
28
29
### Feuille "do_predictions"
30
Prédictions avec incertitude :
31
- Colonnes : i, ttf(i), N_pred(i), IC_inf, IC_sup
32
- IC (Intervalle de Confiance) à 95%
33
34
### Feuille "graph_comparison"
35
Graphe comparatif :
36
- Courbes multiples sur même graphe
37
- Données observées (scatter)
38
- Modèle linéaire (line)
39
- Modèle exponentiel (line)
40
- Zone d'incertitude (area chart)
41
42
## Méthodes d'extrapolation
43
44
### Extrapolation linéaire
45
```python
46
# Régression linéaire sur ttf(i)
47
slope = (ttf[-1] - ttf[0]) / len(ttf)
48
ttf_extrap = [ttf[-1] + slope * k for k in range(1, n_extra+1)]
49
```
50
51
### Modèle exponentiel
52
```python
53
# Décroissance exponentielle de N(i)
54
λ = -np.log(N[-1] / N[0]) / ttf[-1]
55
N_expo = N[0] * np.exp(-λ * ttf)
56
```
57
58
### Interpolation pandas
59
```python
60
# Utiliser pd.interpolate() pour combler les valeurs manquantes
61
df_extended = df.reindex(range(n_extended))
62
df_extended['N(i)'] = df_extended['N(i)'].interpolate(method='polynomial', order=2)
63
```
64
65
## Calcul d'intervalle de confiance
66
```python
67
# Écart-type des résidus
68
std_residuals = np.std(N_observed - N_predicted)
69
# IC à 95% (1.96 × σ)
70
IC_inf = N_pred - 1.96 * std_residuals
71
IC_sup = N_pred + 1.96 * std_residuals
72
```
73
74
## Concepts démontrés
75
- Régression et ajustement de modèles
76
- Comparaison de modèles théoriques
77
- Quantification de l'incertitude
78
- Visualisation multi-séries
79

Code Python

1
# TD_EDC_01_001_08.py
2
# Résumé : Simulation et extrapolation - modèles prédictifs et intervalles de confiance
3
# Génère 5 feuilles : observed, extrapolated, models, predictions, graph_comparison
4
from pathlib import Path
5
import subprocess
6
import pandas as pd
7
import numpy as np
8
import xlsxwriter
9
10
11
def build_paths() -> Path:
12
    """Calcule le chemin du fichier Excel de sortie."""
13
    script = Path(__file__).resolve()
14
    root = script.parent.parent
15
    stem = script.stem
16
    base_dir_name = script.parent.name
17
    xlsx_dir = root / f"{base_dir_name}_do"
18
    xlsx_dir.mkdir(parents=True, exist_ok=True)
19
    
20
    xlsx_path = (xlsx_dir / f"{stem}.xlsx").resolve()
21
    return xlsx_path
22
23
24
def delete_if_exists(file_path: Path) -> None:
25
    """Supprime le fichier s'il existe déjà."""
26
    if file_path.exists():
27
        file_path.unlink()
28
29
30
def prepare_observed_data(n: int = 9, ttf_values: list = None) -> pd.DataFrame:
31
    """Prépare les données observées."""
32
    i_values = list(range(n + 1))
33
    dN_values = [0] + [1] * n
34
    N_values = [n - i for i in range(n + 1)]
35
    
36
    df = pd.DataFrame({
37
        'i': i_values,
38
        'ttf(i)': ttf_values if ttf_values else [0] * (n + 1),
39
        'dN(i)': dN_values,
40
        'N(i)': N_values
41
    })
42
    
43
    return df
44
45
46
def extrapolate_data(df: pd.DataFrame, n_extra: int = 10) -> pd.DataFrame:
47
    """Extrapole les données linéairement."""
48
    ttf = df['ttf(i)'].values
49
    
50
    # Régression linéaire simple
51
    slope = (ttf[-1] - ttf[0]) / (len(ttf) - 1)
52
    
53
    # Extrapoler ttf
54
    i_extrap = list(range(len(df), len(df) + n_extra + 1))
55
    ttf_extrap = [ttf[-1] + slope * k for k in range(1, n_extra + 2)]
56
    
57
    # Extrapoler N (décroissance linéaire)
58
    N_extrap = [max(0, df['N(i)'].iloc[-1] - k) for k in range(1, n_extra + 2)]
59
    
60
    df_extrap = pd.DataFrame({
61
        'i': i_extrap,
62
        'ttf_extrap(i)': ttf_extrap,
63
        'N_extrap(i)': N_extrap
64
    })
65
    
66
    return df_extrap
67
68
69
def calculate_models(df: pd.DataFrame) -> pd.DataFrame:
70
    """Calcule différents modèles prédictifs."""
71
    ttf = df['ttf(i)'].values
72
    N_obs = df['N(i)'].values
73
    N_0 = N_obs[0]
74
    
75
    # Modèle linéaire : N(i) = N(0) - k*i
76
    k_linear = (N_obs[0] - N_obs[-1]) / len(N_obs)
77
    N_linear = [max(0, N_0 - k_linear * i) for i in range(len(ttf))]
78
    
79
    # Modèle exponentiel : N(t) = N(0) * exp(-λ*t)
80
    if ttf[-1] > 0 and N_obs[-1] > 0:
81
        lambda_exp = -np.log(N_obs[-1] / N_0) / ttf[-1]
82
        N_expo = [N_0 * np.exp(-lambda_exp * t) for t in ttf]
83
    else:
84
        N_expo = N_obs.tolist()
85
    
86
    # Modèle de Weibull simplifié : N(t) = N(0) * exp(-(t/η)^β)
87
    # Approximation avec β = 2, η calibré
88
    if ttf[-1] > 0:
89
        eta = ttf[-1] / np.sqrt(-np.log(N_obs[-1] / N_0)) if N_obs[-1] > 0 else ttf[-1]
90
        beta = 2
91
        N_weibull = [N_0 * np.exp(-((t / eta) ** beta)) if t > 0 else N_0 for t in ttf]
92
    else:
93
        N_weibull = N_obs.tolist()
94
    
95
    df_models = pd.DataFrame({
96
        'i': df['i'],
97
        'ttf(i)': ttf,
98
        'N_observed': N_obs,
99
        'N_linear': N_linear,
100
        'N_expo': N_expo,
101
        'N_weibull': N_weibull
102
    })
103
    
104
    return df_models
105
106
107
def calculate_predictions_with_ci(df: pd.DataFrame) -> pd.DataFrame:
108
    """Calcule les prédictions avec intervalles de confiance."""
109
    # Utiliser le modèle exponentiel comme prédiction
110
    ttf = df['ttf(i)'].values
111
    N_obs = df['N(i)'].values
112
    N_0 = N_obs[0]
113
    
114
    if ttf[-1] > 0 and N_obs[-1] > 0:
115
        lambda_exp = -np.log(N_obs[-1] / N_0) / ttf[-1]
116
        N_pred = [N_0 * np.exp(-lambda_exp * t) for t in ttf]
117
    else:
118
        N_pred = N_obs.tolist()
119
    
120
    # Calculer l'écart-type des résidus
121
    residuals = N_obs - np.array(N_pred)
122
    std_residuals = np.std(residuals)
123
    
124
    # Intervalle de confiance à 95% (1.96 * σ)
125
    IC_inf = [max(0, pred - 1.96 * std_residuals) for pred in N_pred]
126
    IC_sup = [pred + 1.96 * std_residuals for pred in N_pred]
127
    
128
    df_predictions = pd.DataFrame({
129
        'i': df['i'],
130
        'ttf(i)': ttf,
131
        'N_pred(i)': N_pred,
132
        'IC_inf': IC_inf,
133
        'IC_sup': IC_sup
134
    })
135
    
136
    return df_predictions
137
138
139
def write_to_excel(xlsx_path: Path, df_obs: pd.DataFrame, df_extrap: pd.DataFrame,
140
                   df_models: pd.DataFrame, df_pred: pd.DataFrame) -> None:
141
    """Écrit toutes les données dans Excel avec graphe comparatif."""
142
    workbook = xlsxwriter.Workbook(str(xlsx_path))
143
    
144
    # Feuille 1 : Données observées
145
    ws_obs = workbook.add_worksheet("do_observed")
146
    for col_num, col_name in enumerate(df_obs.columns):
147
        ws_obs.write(0, col_num, col_name)
148
    for row_num, row_data in enumerate(df_obs.values, start=1):
149
        for col_num, value in enumerate(row_data):
150
            ws_obs.write(row_num, col_num, value)
151
    print(f"✓ Feuille 'do_observed' créée ({len(df_obs)} lignes)")
152
    
153
    # Feuille 2 : Données extrapolées
154
    ws_extrap = workbook.add_worksheet("do_extrapolated")
155
    for col_num, col_name in enumerate(df_extrap.columns):
156
        ws_extrap.write(0, col_num, col_name)
157
    for row_num, row_data in enumerate(df_extrap.values, start=1):
158
        for col_num, value in enumerate(row_data):
159
            ws_extrap.write(row_num, col_num, value)
160
    print(f"✓ Feuille 'do_extrapolated' créée ({len(df_extrap)} lignes)")
161
    
162
    # Feuille 3 : Modèles comparatifs
163
    ws_models = workbook.add_worksheet("do_models")
164
    for col_num, col_name in enumerate(df_models.columns):
165
        ws_models.write(0, col_num, col_name)
166
    for row_num, row_data in enumerate(df_models.values, start=1):
167
        for col_num, value in enumerate(row_data):
168
            ws_models.write(row_num, col_num, value)
169
    print(f"✓ Feuille 'do_models' créée ({len(df_models)} lignes)")
170
    
171
    # Feuille 4 : Prédictions avec IC
172
    ws_pred = workbook.add_worksheet("do_predictions")
173
    for col_num, col_name in enumerate(df_pred.columns):
174
        ws_pred.write(0, col_num, col_name)
175
    for row_num, row_data in enumerate(df_pred.values, start=1):
176
        for col_num, value in enumerate(row_data):
177
            ws_pred.write(row_num, col_num, value)
178
    print(f"✓ Feuille 'do_predictions' créée ({len(df_pred)} lignes)")
179
    
180
    # Feuille 5 : Graphe comparatif des modèles
181
    n_rows = len(df_models)
182
    
183
    chart = workbook.add_chart({'type': 'line'})
184
    
185
    # Série 1 : Données observées (scatter)
186
    chart.add_series({
187
        'name': 'Observé',
188
        'categories': ['do_models', 1, 1, n_rows, 1],  # ttf(i)
189
        'values': ['do_models', 1, 2, n_rows, 2],      # N_observed
190
        'line': {'width': 2.5},
191
        'marker': {'type': 'circle', 'size': 8}
192
    })
193
    
194
    # Série 2 : Modèle linéaire
195
    chart.add_series({
196
        'name': 'Linéaire',
197
        'categories': ['do_models', 1, 1, n_rows, 1],
198
        'values': ['do_models', 1, 3, n_rows, 3],      # N_linear
199
        'line': {'dash_type': 'dash'}
200
    })
201
    
202
    # Série 3 : Modèle exponentiel
203
    chart.add_series({
204
        'name': 'Exponentiel',
205
        'categories': ['do_models', 1, 1, n_rows, 1],
206
        'values': ['do_models', 1, 4, n_rows, 4],      # N_expo
207
        'line': {'dash_type': 'dash_dot'}
208
    })
209
    
210
    # Série 4 : Modèle Weibull
211
    chart.add_series({
212
        'name': 'Weibull',
213
        'categories': ['do_models', 1, 1, n_rows, 1],
214
        'values': ['do_models', 1, 5, n_rows, 5],      # N_weibull
215
        'line': {'dash_type': 'long_dash'}
216
    })
217
    
218
    chart.set_title({'name': 'Comparaison des modèles prédictifs'})
219
    chart.set_x_axis({'name': 'ttf(i)'})
220
    chart.set_y_axis({'name': 'N(i)'})
221
    chart.set_style(10)
222
    
223
    ws_chart = workbook.add_worksheet("graph_comparison")
224
    ws_chart.insert_chart('A1', chart, {'x_scale': 2.5, 'y_scale': 2})
225
    print("✓ Graphe comparatif créé")
226
    
227
    workbook.close()
228
229
230
def open_in_excel(xlsx_path: Path) -> None:
231
    """Ouvre le classeur généré dans Excel."""
232
    subprocess.Popen(["start", "excel", str(xlsx_path)], shell=True)
233
234
235
def main() -> None:
236
    """Pipeline : simulation et extrapolation."""
237
    xlsx_path = build_paths()
238
    
239
    ttf_i = [0, 250, 400, 550, 700, 850, 1000, 1150, 1300, 1450]
240
    
241
    print("Préparation des données observées...")
242
    df_obs = prepare_observed_data(n=9, ttf_values=ttf_i)
243
    
244
    print("Extrapolation des données...")
245
    df_extrap = extrapolate_data(df_obs, n_extra=10)
246
    
247
    print("Calcul des modèles prédictifs...")
248
    df_models = calculate_models(df_obs)
249
    print("\nModèles calculés :")
250
    print(df_models.head())
251
    
252
    print("\nCalcul des prédictions avec intervalles de confiance...")
253
    df_pred = calculate_predictions_with_ci(df_obs)
254
    
255
    print("\nÉcriture dans Excel...")
256
    delete_if_exists(xlsx_path)
257
    write_to_excel(xlsx_path, df_obs, df_extrap, df_models, df_pred)
258
    
259
    print(f"\nFichier créé : {xlsx_path}")
260
    print("5 feuilles générées + 1 graphe comparatif")
261
    open_in_excel(xlsx_path)
262
263
264
if __name__ == "__main__":
265
    main()
266

Documentation

1
# 001_08.py — Simulation et extrapolation
2
3
Ce script Python effectue des simulations et extrapolations de données avec modèles prédictifs et intervalles de confiance.
4
5
## Objectifs pédagogiques
6
- Comprendre la différence entre données observées et extrapolées
7
- Implémenter des modèles prédictifs (régression, tendances)
8
- Calculer des intervalles de confiance
9
- Visualiser les prédictions avec graphiques comparatifs
10
11
## Fonctionnement
12
1. **Données observées**
13
   - Chargement ou génération de données réelles
14
   - Analyse statistique de base
15
16
2. **Extrapolation**
17
   - Application de modèles mathématiques (linéaire, exponentiel)
18
   - Projection sur périodes futures
19
   - Calcul des marges d'erreur
20
21
3. **Modèles et prédictions**
22
   - Comparaison de plusieurs modèles
23
   - Évaluation de la qualité des prédictions
24
   - Intervalles de confiance à 95%
25
26
4. **Export multi-feuilles**
27
   - Feuille `observed` : données réelles
28
   - Feuille `extrapolated` : données projetées
29
   - Feuille `models` : paramètres des modèles
30
   - Feuille `predictions` : prédictions comparées
31
   - Feuille `graph_comparison` : visualisation
32
33
## Points techniques
34
- Utilisation de `numpy` pour calculs matriciels
35
- Régression linéaire et polynomiale
36
- Calculs d'écarts-types et intervalles de confiance
37
- Graphiques avec séries multiples
38
39
## Utilisation
40
Ce script sert de modèle pour effectuer des analyses prédictives et générer des projections avec indicateurs de fiabilité.
41
42
---
43
*Fichier généré automatiquement par GitHub Copilot (GPT-4.1) — 11/12/2025*
44