Analyse statistique d'un jeu de données capteur
1. Pourquoi la statistique pour l'IoT ?
Les capteurs IoT génèrent des milliers de mesures. La statistique permet de passer d'une série brute à une information utile : température moyenne d'un entrepôt, détection d'un capteur défaillant, pic de consommation anormal.
| Mesure | Définition | Exemple IoT |
|---|---|---|
| Moyenne (μ) | Somme des valeurs divisée par le nombre d'observations. μ = (∑xᵢ) / N | Température moyenne d'un entrepôt sur 24h |
| Médiane | Valeur centrale après tri — divise la série en deux parts égales | Résistante aux valeurs aberrantes (capteur en panne) |
| Mode | Valeur la plus fréquente dans la série | Plage de température la plus courante dans un entrepôt |
| Écart-type (σ) | Racine carrée de la variance. Mesure la dispersion autour de la moyenne | Plus σ est grand, plus les mesures sont instables |
| Variance (σ²) | Moyenne des carrés des écarts à la moyenne : σ² = ∑(xᵢ − μ)² / N | Utile pour quantifier la variabilité d'un processus |
| Règle 3σ | 99.7% des données dans [μ − 3σ, μ + 3σ]. Hors de cet intervalle = anomalie | Alerte si température > μ + 3σ (capteur défaillant ou incendie) |
2. Représentations graphiques
Un graphique vaut mille mesures. Trois représentations essentielles :
- Histogramme — répartition des fréquences par intervalle. Permet de visualiser la distribution (normale, asymétrique, bimodale).
- Série temporelle — valeur en fonction du temps. Indispensable pour voir l'évolution et les tendances.
- Boîte à moustaches — médiane, quartiles, valeurs extrêmes. Détection rapide des outliers.
3. Détection d'anomalies IoT
Un capteur IoT produit un flux continu de données. Une anomalie peut être :
- Globale — valeur hors de l'intervalle [μ − 3σ, μ + 3σ] (ex: 120°C dans un entrepôt à 25°C)
- Contextuelle — valeur anormale pour un contexte donné (ex: 30°C à 3h du matin)
- Collective — séquence de valeurs anormales (ex: plateau à 0°C = capteur mort)
a) À partir d'un fichier CSV contenant 100 mesures de température (capteur DHT22), calculez la moyenne, la médiane et l'échantillon-type à l'aide de Python (NumPy).
b) Identifiez les valeurs anormales avec la règle 3σ. Combien y en a-t-il ? Sont-elles cohérentes avec le contexte ?
c) Créez un histogramme (10 bins) et une boîte à moustaches. Interprétez la forme de la distribution.
d) BONUS — Programme Arduino qui calcule une moyenne glissante sur 10 échantillons et allume une LED rouge si la température dépasse μ + 2σ.
import numpy as np
import matplotlib.pyplot as plt
data = np.loadtxt("mesures_capteur.csv", delimiter=",", skiprows=1)
moyenne = np.mean(data)
mediane = np.median(data)
ecart_type = np.std(data, ddof=1)
print(f"Moyenne: {moyenne:.2f}°C")
print(f"Médiane: {mediane:.2f}°C")
print(f"Écart-type: {ecart_type:.2f}°C")
seuil_bas = moyenne - 3 * ecart_type
seuil_haut = moyenne + 3 * ecart_type
anomalies = data[(data < seuil_bas) | (data > seuil_haut)]
print(f"Anomalies détectées: {len(anomalies)}")
print(f"Intervalle 3σ: [{seuil_bas:.2f}, {seuil_haut:.2f}]")
plt.hist(data, bins=10, edgecolor="black", alpha=0.7)
plt.axvline(moyenne, color="r", linestyle="--", label=f"Moyenne={moyenne:.1f}")
plt.axvline(moyenne + 2*ecart_type, color="orange", linestyle=":", label="μ+2σ")
plt.axvline(moyenne - 2*ecart_type, color="orange", linestyle=":", label="μ-2σ")
plt.title("Histogramme des températures capteur")
plt.xlabel("Température (°C)"); plt.ylabel("Fréquence")
plt.legend(); plt.grid(True)
plt.show()
const int N = 10;
float buffer[N];
int index = 0;
float somme = 0;
float moyenne_glissante = 0;
const int LED_ROUGE = 7;
const int CAPTEUR_PIN = A0;
float mu = 25.0;
float sigma = 2.0;
void setup() {
Serial.begin(9600);
pinMode(LED_ROUGE, OUTPUT);
for (int i = 0; i < N; i++) buffer[i] = 0;
}
void loop() {
float valeur = analogRead(CAPTEUR_PIN) * (5.0 / 1023.0) * 100;
somme -= buffer[index];
buffer[index] = valeur;
somme += buffer[index];
index = (index + 1) % N;
moyenne_glissante = somme / N;
Serial.print("Valeur: "); Serial.print(valeur, 1);
Serial.print(" | Moy. glissante: "); Serial.println(moyenne_glissante, 1);
if (moyenne_glissante > mu + 2 * sigma) {
digitalWrite(LED_ROUGE, HIGH);
Serial.println("⚠ ALARME: Température anormale !");
} else {
digitalWrite(LED_ROUGE, LOW);
}
delay(1000);
}