Initial commit: Data Analysis application with FastAPI backend and Next.js frontend

This commit is contained in:
2026-01-11 21:54:33 +01:00
commit 7bdafb4fbf
549 changed files with 96211 additions and 0 deletions

View File

@@ -0,0 +1,916 @@
# Guide Complet des Outliers (Valeurs Aberrantes)
🔍 **Identifier, comprendre et gérer les outliers** pour garantir la qualité de vos analyses statistiques.
---
## Table des Matières
1. [Qu'est-ce qu'un Outlier ?](#quest-ce-quun-outlier)
2. [Types d'Outliers](#types-doutliers)
3. [Méthodes de Détection](#méthodes-de-détection)
4. [Indicateurs Visuels](#indicateurs-visuels)
5. [Processus de Gestion](#processus-de-gestion)
6. [Impact sur les Analyses](#impact-sur-les-analyses)
7. [Bonnes Pratiques](#bonnes-pratiques)
8. [Exemples Concrets](#exemples-concrets)
---
## Qu'est-ce qu'un Outlier ?
### Définition
Un **outlier** (valeur aberrante) est une observation qui s'écarte **significativement** du reste des données.
### Caractéristiques
```
Données normales :
┌─┐
┌─┤ ├─┐ ← Distribution normale
│ │ │ │
└─┤ ├─┘
└─┘
Avec outliers :
┌─┐
┌─┤ ├─┐
│ │ │ │ ● ← Outlier élevé
└─┤ ├─┘ ●
└─┘ ● ← Outlier faible
```
### Pourquoi les Outliers Sont-Ils Importants ?
⚠️ **Ils peuvent fausser vos résultats** :
```python
# Moyenne SANS outlier
[10, 12, 11, 13, 12] Moyenne = 11.6
# Moyenne AVEC outlier
[10, 12, 11, 13, 12, 100] Moyenne = 26.3
# Impact : La moyenne est plus que doublée !
# Solution : Utiliser la médiane (robuste aux outliers)
```
---
## Types d'Outliers
L'application détecte **2 types** d'outliers :
### 1. Outliers Univariés 🔴
**Définition** : Valeur extrême dans **une seule variable**.
**Détection** : Méthode **IQR** (Interquartile Range)
**Exemple** :
```python
# Surface des appartements (m²)
[45, 50, 55, 60, 65, 70, 75, 500] # 500 est outlier
# Calcul :
Q1 = 52.5
Q3 = 71.25
IQR = Q3 - Q1 = 18.75
# Limite supérieure
Upper = Q3 + 1.5×IQR = 71.25 + 1.5×18.75 = 99.375
# 500 > 99.375 → OUTLIER 🔴
```
**Indicateur visuel** : **Cercle rouge** sur la valeur dans la table
---
### 2. Outliers Multivariés 🟣
**Définition** : Combinaison **inhabituelle** de plusieurs variables.
**Détection** : Algorithme **Isolation Forest**
**Exemple** :
```python
# Client : Âge=18, Revenu=100000€, Historique=0
# Individuellement :
# - Âge 18 : Normal
# - Revenu 100000€ : Normal
# - Historique 0 : Normal
# Mais COMBINÉ :
# → Jeune avec très haut revenu et aucun historique
# → SUSPECT ! (fraude potentielle, erreur de saisie, etc.)
# → OUTLIER MULTIVARIÉ 🟣
```
**Indicateur visuel** : **Cercle violet** sur la ligne dans la table
---
## Méthodes de Détection
### Méthode 1 : IQR (Interquartile Range)
#### Principe
L'IQR mesure la **dispersion centrale** des données (50% central).
```
┌────┬──────┬──────┬──────┬────┐
Min Q1 Médiane Q3 Max
└─────┬─────┘
IQR
```
#### Formules
```python
Q1 = 25ème percentile
Q3 = 75ème percentile
IQR = Q3 - Q1
Limite inférieure = Q1 - 1.5 × IQR
Limite supérieure = Q3 + 1.5 × IQR
# Outlier si :
valeur < Limite inférieure
OU
valeur > Limite supérieure
```
#### Exemple Pas à Pas
```python
# Données : Prix immobiliers
Prix = [150k, 180k, 200k, 220k, 250k, 280k, 300k, 1500k]
# Étape 1 : Trier
[150, 180, 200, 220, 250, 280, 300, 1500]
# Étape 2 : Calculer Q1 et Q3
Q1 = 190 (moyenne de 180 et 200)
Q3 = 290 (moyenne de 280 et 300)
# Étape 3 : Calculer IQR
IQR = 290 - 190 = 100
# Étape 4 : Calculer les limites
Limite_inf = 190 - 1.5×100 = 40
Limite_sup = 290 + 1.5×100 = 440
# Étape 5 : Identifier les outliers
150k > 40 Normal
180k > 40 Normal
...
300k < 440 Normal
1500k > 440 OUTLIER 🔴
```
#### Avantages et Limites
**Avantages** :
- Simple à comprendre
- Robuste aux outliers (utilise des rangs)
- Fonctionne avec des données non normales
**Limites** :
- Ne détecte que les extrêmes univariés
- Peut manquer des outliers multivariés
- Seuil 1.5 arbitraire (peut être ajusté)
---
### Méthode 2 : Isolation Forest
#### Principe
L'algorithme **isole** les observations en créant des partitions aléatoires. Les outliers sont **plus faciles à isoler** (moins de partitions nécessaires).
```
Forêt aléatoire d'arbres de décision :
- Chaque arbre partitionne les données
- Les outliers ont des chemins plus courts
- Score d'anomalie basé sur la longueur moyenne des chemins
```
#### Algorithme
```python
from sklearn.ensemble import IsolationForest
# 1. Entraîner le modèle
model = IsolationForest(
contamination='auto', # Détection automatique du seuil
random_state=42
)
# 2. Prédire
predictions = model.fit_predict(data_multivariée)
# Résultats :
# 1 → Normal
# -1 → Outlier 🟣
```
#### Exemple Visuel
```
Espace 2D (Âge, Revenu) :
Revenu
│ •
│ • •
│ • •
│ • ● • ← ● = Outlier multivarié
│ • • • (combinaison rare)
│• •
└──────────────→ Âge
```
#### Avantages et Limites
**Avantages** :
- Détecte les outliers **multivariés**
- Ne nécessite pas de distribution normale
- Fonctionne avec des données de haute dimension
**Limites** :
- Plus complexe à interpréter
- Résultats non déterministes (aléatoire)
- Peut varier selon le paramètre `contamination`
---
### Comparaison des Méthodes
| Critère | IQR | Isolation Forest |
|---------|-----|------------------|
| **Type** | Univarié | Multivarié |
| **Détection** | Valeurs extrêmes | Combinaisons rares |
| **Complexité** | Simple | Complexe |
| **Interprétabilité** | Élevée | Faible |
| **Robustesse** | Moyenne | Élevée |
| **Utilisation** | Première analyse | Analyse approfondie |
---
## Indicateurs Visuels
### Dans l'Application
#### 🔴 Cercle Rouge (Outlier Univarié)
**Affichage** : Sur la **cellule** spécifique
**Exemple** :
```
┌─────────────┬─────────────┬─────────────┐
│ Surface │ Prix │ Chambres │
├─────────────┼─────────────┼─────────────┤
│ 60 │ 250000 │ 3 │
│ 75 │ 300000 │ 4 │
│ 500 🔴 │ 350000 │ 5 │ ← Outlier sur Surface
│ 55 │ 280000 │ 3 │
└─────────────┴─────────────┴─────────────┘
```
**Information au survol** :
```
Column 'Surface' value 500 is outside IQR bounds [32.5, 115.5]
```
---
#### 🟣 Cercle Violet (Outlier Multivarié)
**Affichage** : Sur toute la **ligne**
**Exemple** :
```
┌─────────────┬─────────────┬─────────────┐
│ Âge │ Revenu │ Historique │
├─────────────┼─────────────┼─────────────┤
│ 35 │ 3000 │ 12 │
│ 42 │ 4500 │ 8 │
│ 18 🟣 │ 100000 │ 0 🟣 │ ← Outlier multivarié
│ 28 │ 2500 │ 5 │
└─────────────┴─────────────┴─────────────┘
```
**Information au survol** :
```
Multivariate anomaly detected by Isolation Forest
```
---
#### 🔴🟣 Les Deux (Outlier Univarié + Multivarié)
**Exemple** :
```
┌─────────────┬─────────────┬─────────────┐
│ Surface │ Prix │ Chambres │
├─────────────┼─────────────┼─────────────┤
│ 500 🔴🟣 │ 5000000 🔴 │ 10 🟣 │
└─────────────┴─────────────┴─────────────┘
```
**Interprétation** :
- 🔴 Surface et Prix sont des valeurs extrêmes
- 🟣 La combinaison Surface+Prix+Chambres est anormale
---
## Processus de Gestion
### Workflow Recommandé
```
1. Détection automatique
├─ IQR (univarié)
└─ Isolation Forest (multivarié)
2. Investigation manuelle
├─ Survoler les indicateurs colorés
├─ Lire les raisons détaillées
└─ Vérifier la source de données
3. Décision
├─ Conserver (valeurs légitimes)
├─ Corriger (erreurs de saisie)
└─ Exclure (vraies anomalies)
4. Ré-analyse
├─ Réexécuter la détection
├─ Vérifier l'impact sur les résultats
└─ Documenter les décisions
```
---
### Étape 1 : Identification
**Dans l'application** :
1. Importez vos données
2. Les outliers sont automatiquement détectés
3. Repérez les cercles 🔴 et 🟣
**Règle de priorité** :
```
🔴 Univarié → Vérifier en premier (simple)
🟣 Multivarié → Vérifier ensuite (complexe)
```
---
### Étape 2 : Investigation
#### Questions à se poser
**1. Est-ce une erreur de saisie ?**
```python
# Exemple : Âge = 250
# → Probablement une erreur (tapez 25 au lieu de 250)
# → Vérifier la source de données
# → Corriger si possible
```
**2. Est-ce une valeur légitime ?**
```python
# Exemple : Revenu = 1000000€ pour un CEO
# → Valeur extrême mais réelle
# → CONSERVER (pas d'erreur)
# → Vérifier l'impact sur l'analyse
```
**3. Est-ce un événement rare ?**
```python
# Exemple : Pic de ventes le Black Friday
# → Valeur extrême mais explicable
# → CONSERVER ou créer une variable "Black Friday"
# → Modéliser séparément si nécessaire
```
**4. Est-ce une mesure défaillante ?**
```python
# Exemple : Température = -50°C en été
# → Erreur de capteur
# → EXCLURE ou CORRIGER
```
---
### Étape 3 : Action
#### Option 1 : Corriger
**Quand** : Erreur de saisie identifiée
**Exemple** :
```python
# Avant (erreur)
Prix = 15000000 # 15 millions pour un 60 m² ??
# Après (correction)
Prix = 150000 # 150k€ → réaliste
# Action : Modifier la valeur dans le fichier source
```
---
#### Option 2 : Conserver
**Quand** : Valeur légitime mais extrême
**Stratégies** :
**A. Transformation**
```python
# Appliquer une transformation log
prix_log = log(Prix)
# Avantages :
# - Réduit l'impact des extrêmes
# - Normalise la distribution
```
**B. Modèle robuste**
```python
# Utiliser des méthodes robustes aux outliers
# - Spearman au lieu de Pearson
# - Médiane au lieu de moyenne
# - Isolation Forest pour la détection
```
**C. Analyse séparée**
```python
# Créer deux modèles
# - Modèle 1 : Données normales
# - Modèle 2 : Outliers (cas particuliers)
```
---
#### Option 3 : Exclure
**Quand** :
- Erreur non corrigeable
- Valeur influente et non représentative
- Mesure défaillante
**Dans l'application** :
1. Cliquez sur l'outlier (🔴 ou 🟣)
2. La ligne est marquée pour exclusion
3. Les prochaines analyses ignoreront cette ligne
4. Les exclusions sont mémorisées
**⚠️ Précautions** :
- Documentez la raison de l'exclusion
- Vérifiez l'impact sur la taille de l'échantillon
- Assurez-vous que l'exclusion est justifiée
---
### Étape 4 : Vérification
#### Avant vs Après
```python
# AVANT (avec outliers)
Moyenne = 26.3
Écart-type = 38.5
Corrélation = 0.45
# APRÈS (sans outliers)
Moyenne = 11.6
Écart-type = 1.1
Corrélation = 0.92
# Impact : L'analyse est plus représentative
```
#### Checklist de validation
- [ ] Les exclusions sont **justifiées** et documentées
- [ ] L'échantillon reste **suffisamment grand** (n > 30)
- [ ] Les résultats sont **plus cohérents**
- [ ] Pas de **sur-correction** (exclure trop de données)
- [ ] Les décisions sont **reproductibles**
---
## Impact sur les Analyses
### 1. Moyenne vs Médiane
```python
# Données avec outlier
[10, 12, 11, 13, 12, 100]
Moyenne = 26.3 📊 Biaisée par l'outlier
Médiane = 12 📊 Robuste
# Règle : Utiliser la médiane en présence d'outliers
```
---
### 2. Corrélation Pearson vs Spearman
```python
# Avec outlier (Pearson)
r_pearson = 0.60 📊 Faible (outlier distord la relation)
# Avec outlier (Spearman)
r_spearman = 0.90 📊 Fort (robuste aux outliers)
# Sans outlier (Pearson)
r_pearson = 0.92 📊 Fort (relation réelle)
# Règle : Utiliser Spearman si outliers présents
```
---
### 3. Régression
#### Impact sur les Coefficients
```python
# RÉGRESSION SANS OUTLIER
Prix = 50000 + 2500×Surface
= 0.90
# RÉGRESSION AVEC OUTLIER
Prix = 80000 + 1000×Surface
= 0.60
# Impact :
# - Intercept : 50000 → 80000 (biaisé)
# - Surface : 2500 → 1000 (sous-estimé)
# - R² : 0.90 → 0.60 (moins précis)
```
#### Influence (Leverage)
Certains outliers ont un **impact disproportionné** :
```python
# Outlier avec fort leverage
Point : (Surface=1000, Prix=1000000)
# Si exclu :
# Coefficient Surface : 2500 → 2800 (+12%)
# L'outlier "tire" la droite vers lui
```
---
### 4. Tests Statistiques
```python
# Test t (comparaison de moyennes)
# SANS outlier
Groupe A : [10, 12, 11, 13, 12]
Groupe B : [15, 17, 16, 18, 17]
p-value = 0.0001 Différence significative
# AVEC outlier dans Groupe A
Groupe A : [10, 12, 11, 13, 12, 100] # outlier ajouté
Groupe B : [15, 17, 16, 18, 17]
p-value = 0.15 Différence non significative
# Impact : L'outlier masque la différence réelle
```
---
## Bonnes Pratiques
### 1. Toujours Visualiser
```python
# Box plot pour détecter visuellement
import matplotlib.pyplot as plt
plt.boxplot(data['Prix'])
plt.show()
# Box plot avec outliers marqués
# ┌─┐
# │ │ ● ← Outlier
# ├─┤
# │ │
# └─┘
```
---
### 2. Ne Pas Exclure Automatiquement
```python
MAUVAIS
if is_outlier(valeur):
exclure(valeur) # Automatique
BON
if is_outlier(valeur):
investiguer(valeur) # Manuel
si erreur:
corriger_ou_exclure()
sinon:
conserver()
```
---
### 3. Documenter les Décisions
```python
# Journal des exclusions
exclusions = {
'ligne_42': {
'raison': 'Erreur de saisie (âge=250)',
'action': 'Corrigé en 25',
'date': '2025-01-11'
},
'ligne_87': {
'raison': 'Capteur défaillant (température=-50)',
'action': 'Exclu',
'date': '2025-01-11'
}
}
```
---
### 4. Comparer Avec/Sans
```python
# Analyse 1 : Tous les données
model1 = regression(data_complete)
r2_1 = 0.75
# Analyse 2 : Sans outliers
model2 = regression(data_sans_outliers)
r2_2 = 0.92
# Conclusion : Les outliers impactent significativement
# → Exclusion justifiée si R² améliore et taille échantillon OK
```
---
### 5. Utiliser des Méthodes Robustes
```python
# Méthodes robustes aux outliers
Moyenne Médiane
Écart-type Écart interquartile (IQR)
Pearson Spearman
OLS Régression robuste (Huber, RANSAC)
```
---
## Exemples Concrets
### Exemple 1 : Immobilier
**Données** : Prix, Surface, Chambres
```
┌───────┬─────────┬──────────┬──────────┐
│ ID │ Surface │ Prix │ Chambres │
├───────┼─────────┼──────────┼──────────┤
│ 1 │ 60 │ 250000 │ 3 │
│ 2 │ 75 │ 300000 │ 4 │
│ 3 │ 500 🔴 │ 350000 │ 5 │ ← Outlier univarié
│ 4 │ 55 │ 280000 │ 3 │
│ 5 │ 80 │ 320000 │ 4 │
│ 6 │ 70 │ 15000000 🔴│ 3 │ ← Outlier univarié
│ 7 │ 65 │ 290000 │ 3 │
└───────┴─────────┴──────────┴──────────┘
```
**Analyse** :
- **Ligne 3** : Surface = 500 m² → Outlier (trop grand pour l'échantillon)
- **Ligne 6** : Prix = 15M€ → Outlier (prix extrême)
**Action** :
```
Investigation :
- Ligne 3 : Vérifié → Château luxueux (légitime)
- Ligne 6 : Vérifié → Erreur de saisie (15M au lieu de 150k)
Décision :
- Ligne 3 : CONSERVER (valeur réelle)
- Ligne 6 : CORRIGER (150k€)
```
---
### Exemple 2 : E-commerce
**Données** : Âge, Revenu, Montant_Achat
```
┌───────┬──────┬─────────┬──────────────┐
│ ID │ Âge │ Revenu │ Montant_Achat │
├───────┼──────┼─────────┼──────────────┤
│ 1 │ 35 │ 3000 │ 150 │
│ 2 │ 42 │ 4500 │ 200 │
│ 3 │ 28 │ 2500 │ 100 │
│ 4 │ 18 🟣│ 100000 🟣│ 0 🟣 │ ← Outlier multivarié
│ 5 │ 55 │ 5000 │ 250 │
└───────┴──────┴─────────┴──────────────┘
```
**Analyse** :
- **Ligne 4** :
- Âge = 18 (normal)
- Revenu = 100k€ (normal)
- Montant = 0 (normal)
- **MAIS** : Jeune avec très haut revenu et aucun achat → SUSPECT
**Investigation** :
```
Cas 1 : Erreur de saisie (revenu=10000€)
Cas 2 : Compte frauduleux
Cas 3 : Héritage récent (légitime)
Cas 4 : Erreur de catégorisation (professionnel vs personnel)
```
**Action** :
```
Si erreur → Corriger
Si fraude → Exclure et signaler
Si légitime → Créer une variable "Profil_Riche_Jeune"
```
---
### Exemple 3 : Santé
**Données** : IMC, Tension, Cholestérol
```
┌───────┬──────┬─────────┬────────────┐
│ ID │ IMC │ Tension │ Cholestérol│
├───────┼──────┼─────────┼────────────┤
│ 1 │ 22 │ 120 │ 180 │
│ 2 │ 25 │ 130 │ 200 │
│ 3 │ 60 🔴│ 180 🔴 │ 350 🔴 │ ← Outlier univarié
│ 4 │ 23 │ 125 │ 190 │
│ 5 │ 28 │ 140 │ 220 │
└───────┴──────┴─────────┴────────────┘
```
**Analyse** :
- **Ligne 3** : IMC=60 (obésité morbide), Tension=180 (hypertension sévère), Cholestérol=350 (très élevé)
**Investigation** :
```
Cas 1 : Patient réel (pathologie sévère)
Cas 2 : Erreur de mesure (unités ?)
Cas 3 : Données agrégées par erreur
```
**Action** :
```
Si patient réel :
→ CONSERVER et analyser séparément (cas sévères)
Si erreur :
→ CORRIGER ou EXCLURE
```
---
## 🎯 Checklist de Gestion des Outliers
### Détection
- [ ] Identifier les outliers univariés (🔴 cercles rouges)
- [ ] Identifier les outliers multivariés (🟣 cercles violets)
- [ ] Compter le nombre d'outliers
- [ ] Vérifier la proportion (< 5% des données)
### Investigation
- [ ] Vérifier la source de données
- [ ] Rechercher des erreurs de saisie
- [ ] Consulter un expert du domaine
- [ ] Explorer les causes possibles
### Action
- [ ] Corriger les erreurs identifiées
- [ ] Conserver les valeurs légitimes
- [ ] Exclure les vraies anomalies
- [ ] Documenter toutes les décisions
### Validation
- [ ] Comparer les résultats avec/sans
- [ ] Vérifier la taille de l'échantillon final
- [ ] S'assurer que la distribution est cohérente
- [ ] Valider avec des graphiques
---
## 📊 Fonctionnalités de l'Application
### Détection Automatique
L'application détecte automatiquement les outliers à l'importation :
```python
# Méthode 1 : IQR (univarié)
uni_outliers = detect_univariate_outliers(
data,
columns=numeric_columns
)
# Méthode 2 : Isolation Forest (multivarié)
multi_outliers = detect_multivariate_outliers(
data,
columns=numeric_columns
)
# Fusion structurée
result = merge_outliers_structured(uni_outliers, multi_outliers)
```
---
### Interface Utilisateur
#### Indicateurs Visuels
- 🔴 **Cercle rouge** : Outlier univarié (sur la cellule)
- 🟣 **Cercle violet** : Outlier multivarié (sur la ligne)
- 🔴🟣 **Les deux** : Les deux types d'outliers
#### Information au Survol
```javascript
// Exemple de tooltip
{
"index": 42,
"reasons": [
"Column 'Surface' value 500 is outside IQR bounds [32.5, 115.5]",
"Multivariate anomaly detected by Isolation Forest"
]
}
```
---
### Exclusion et Mémorisation
```python
# Marquer une ligne pour exclusion
excluded_indices = [42, 87, 156]
# Ré-analyser sans ces lignes
new_analysis = analyze_with_exclusions(
data,
excluded_indices=excluded_indices
)
# Les exclusions sont mémorisées dans la session
```
---
## 🚀 Conclusion
Les outliers sont à la fois un **défi** et une **opportunité** :
⚠️ **Défi** :
- Peuvent fausser vos analyses
- Nécessitent une investigation minutieuse
- Exiger des décisions subjectives
**Opportunité** :
- Peuvent révéler des phénomènes intéressants
- Signalent des erreurs dans les données
- Permettent d'améliorer la qualité des analyses
**Points clés** :
1. **Toujours investiguer** avant d'exclure
2. **Documenter** vos décisions
3. **Comparer** avec/sans outliers
4. **Utiliser** des méthodes robustes
5. **Visualiser** pour comprendre
---
**Version** : 1.0
**Projet** : Application d'Analyse de Données
🔗 **Voir aussi** : [Guide Corrélation](CORRELATION_GUIDE.md) | [Guide Régression](REGRESSION_GUIDE.md)