# 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
R² = 0.90

# RÉGRESSION AVEC OUTLIER
Prix = 80000 + 1000×Surface
R² = 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)
