Par Tahiana Hajanirina Andriambahoaka, Mohamed Amar et Lounis Hamroun · Février 2026
Projet réalisé dans le cadre du cours DATA705 — BDD NoSQL à Télécom Paris
Chaque jour, des milliers d’avions survolent la France. Avec les orages, les descentes brutales des avions, les vitesses anormalement faibles en altitude : comment repérer automatiquement en quelques secondes les vols à risque ?
C’est la question que nous nous sommes posée en lançant SkySafe. Un pipeline Big Data qui ingère en quasi temps-réel les positions GPS de tous les avions au-dessus de la France, les croise avec la météo locale, calcule un score de risque pour chaque vol, et utilise le Machine Learning pour détecter automatiquement les comportements suspects.
Toutes les informations nécessaires au suivi des vols sont regroupées dans un unique dashboard Kibana : chaque avion y apparaît avec ses principales données, un indicateur de vols normaux ou à risque, ainsi que la mise en évidence des anomalies détectées.
Dans cet article, découvrez la conception de ce système, les principaux obstacles rencontrés, et les solutions mises en place pour les surmonter.
Avant de plonger dans les détails, voici la vue d’ensemble. Notre pipeline suit le modèle Raw → Formatted → Enriched → Usage, orchestré par Airflow et alimenté en parallèle par deux sources de données :
API Vols (OpenSky) ──> Nettoyage / Formatage (Spark) ──┐
├─> Croisement + ML (Spark) ──> Elasticsearch
API Météo (Open-Meteo) ──> Nettoyage / Formatage (Spark) ──┘
Les principaux outils qui font tourner ce pipeline :
Pour construire notre système de surveillance, nous avions besoin de deux types d’informations : où sont les avions et quel temps fait-il là où ils volent.
L’API OpenSky Network nous fournit en temps réel la position de chaque avion grâce à son transpondeur ADS-B : identifiant ICAO, callsign, latitude, longitude, altitude, vitesse, cap, taux de montée/descente, pays d’origine…
Nous filtrons les vols sur une bounding box couvrant la France métropolitaine pour réduire le volume de données à traiter.
Pour un usage non commercial, nous avons droit à 10K requêtes quotidiennes gratuitement, ce qui est largement suffisant pour notre cas d’usage.
L’API Open-Meteo nous donne les conditions météorologiques actuelles pour 6 zones stratégiques couvrant la France métropolitaine : Paris CDG, Toulouse, Lyon, Marseille, Nantes et Lille.
Nous avons sélectionné ces 6 villes car elles constituent les grands noeuds du trafic aérien français : ce sont des zones à forte densité de vols, où les conditions météorologiques ont le plus d’impact sur la sécurité aérienne. Elles sont également géographiquement bien réparties sur l’ensemble du territoire, ce qui permet de couvrir des microclimats différents.
Pour chaque station, on récupère la température, le vent, les rafales, la pluie, la visibilité, la couverture nuageuse et le code météo (qui indique notamment la présence d’un orage).
Par défaut, les utilisateurs anonymes disposent de 400 crédits API par jour. En créant un compte et en effectuant des requêtes authentifiées, nous avons pu bénéficier de 4 000 appels par jour — largement suffisant pour interroger ces 6 stations toutes les minutes.
L’idée est que pour chaque avion en vol, on lui associe les conditions météo de la station la plus proche grâce à la formule de Haversine (distance sur la sphère terrestre), puis on en déduit un niveau de risque.
C’est ici que les choses sont devenues intéressantes.
Durant les premières phases de développement, tout fonctionnait parfaitement en local : l’API OpenSky répondait en quelques secondes. Mais dès que nous avons déployé notre pipeline sur un serveur cloud (une instance EC2 AWS), les requêtes ont commencé à échouer avec des erreurs 504 Timeout.
Après investigation, nous avons identifié le problème : OpenSky Network impose des limites de débit strictes et bloque activement les requêtes provenant des gros datacenters. Notre serveur se trouvait sur une plage d’adresses blacklistée. C’est d’ailleurs assumé publiquement dans la documentation officielle de leur API :
“Note that we may block AWS and other hyperscalers due to generalized abuse from these IPs.”
Il fallait donc trouver une solution alternative pour contourner ce blocage, sans pour autant rapatrier le code en local. C’est là que l’architecture Serverless est venue à la rescousse.
Nous avons contourné le problème en déployant une fonction serverless (Lambda) sur Scaleway Cloud. Cette Lambda agit comme un proxy intelligent :
Ce contournement a résolu le problème immédiatement — et nous a permis au passage de mettre en pratique l’architecture Serverless. Une pierre, deux coups.
Après avoir nettoyé les données et associé chaque vol à sa station météo la plus proche, Spark calcule un score de risque composite de 0 à 100 basé sur des règles aéronautiques officielles (FAA) :
| Condition météorologique | Points | Justification |
|---|---|---|
| Orage détecté | +40 | Dangers cumulés : turbulences extrêmes, givrage, cisaillements de vent. La FAA recommande de ne jamais approcher un orage sévère à moins de 20 nm. |
| Rafales > 80 km/h | +25 | Le Wind Shear déstabilise la portance et rend le contrôle difficile. |
| Précipitations > 5 mm | +20 | Visibilité réduite et aérodynamisme des ailes altéré. |
| Visibilité < 1 000 m | +20 | Passage obligatoire en conditions IFR (Instrument Flight Rules) — alerte majeure pour le contrôle aérien. |
| Altitude < 300 m en vol | +15 | Marge de récupération quasi nulle face aux cisaillements de basse couche (LLWS). |
| Couverture nuageuse > 80 % | +10 | Plafond bas masquant le développement de nuages d’orage. |
Sources officielles utilisées pour définir ces règles métier :
- Orages et turbulences : FAA Advisory Circular 00-24C - Aviation Weather
- Cisaillement de vent (Wind Shear) : National Weather Service (NWS) - Aviation Safety
- Règles de visibilité et météo en vol : FAA - Pilot’s Handbook of Aeronautical Knowledge (Chapitre 12)
Un avion traversant un orage avec rafales et mauvaise visibilité atteint facilement 80+ → HIGH RISK, affiché en rouge sur le dashboard. Un vol en croisière par temps clair obtient 0 → LOW.
Limite du score : il croise météo et position, mais ne dit rien sur le comportement de l’avion lui-même. C’est là qu’intervient le Machine Learning.
C’est la brique qui transforme notre pipeline de données en véritable système de surveillance intelligent — et celle dont nous sommes le plus fiers.
L’API OpenSky fournit la vitesse, l’altitude et le taux de montée/descente de chaque avion — mais elle ne dit rien sur sa phase de vol (décollage, croisière, atterrissage), ni sur d’éventuels comportements anormaux. Ce sont pourtant des informations essentielles pour un système de surveillance aérienne — et c’est précisément de là que vient le nom SkySafe : un ciel surveillé et plus sûr.
Nous avons donc entraîné un modèle de Machine Learning non supervisé directement dans Spark, capable d’inférer automatiquement ces informations à chaque exécution du pipeline — soit toutes les minutes.
Nous utilisons l’algorithme K-Means (disponible nativement dans Spark MLlib) pour regrouper les avions en 3 clusters à partir de trois caractéristiques : vitesse, altitude et taux de montée/descente. Pour visualiser : imaginez tous les avions disposés sur une table. Le K-Means va naturellement les regrouper en trois tas :
La labellisation est automatique : les clusters sont triés par altitude moyenne croissante. Le cluster le plus bas devient “Takeoff / Landing”, le plus haut “Cruise”, et le troisième “Climb / Descent”.
En amont du K-Means, un StandardScaler normalise les trois features. Cette étape est indispensable car sans normalisation, l’altitude (exprimée en milliers de mètres) dominerait entièrement le calcul des distances, reléguant la vitesse et le taux vertical à un rôle quasi nul.
Le K-Means génère toujours $k = 3$ clusters, quelle que soit la distribution réelle des données. En pratique, cela pose problème aux heures creuses (2h–5h du matin), quand le trafic se réduit quasi exclusivement à des long-courriers en croisière : l’algorithme segmente alors artificiellement une population homogène en trois sous-groupes non significatifs.
Pour pallier cette limite, nous basculons automatiquement sur une classification par règles aéronautiques lorsque les trois centroïdes sont trop proches (clusters non significatifs) :
Ce mécanisme assure une classification cohérente en toutes circonstances : K-Means en période normale, règles métier en période creuse — sans dégradation de la qualité des données.
Une fois les clusters constitués, chaque avion se voit associer un centroïde de référence qui est le point central de son groupe. Nous calculons la distance euclidienne entre chaque avion et ce centroïde : c’est l’anomaly_score. Plus cette distance est grande, plus le comportement de l’avion s’éloigne de la norme de son groupe.
Le seuil de détection est recalculé dynamiquement à chaque cycle selon la formule moyenne + 2 écarts-types sur l’ensemble des distances observées — ce qui correspond statistiquement aux 5 % de vols les plus atypiques.
Toutes ces données enrichies arrivent dans Elasticsearch, puis s’affichent sur un tableau de bord Kibana. Voici ce que nous obtenons :

Le dashboard est importé automatiquement au premier lancement grâce à un second DAG Airflow qui attend que les premières données soient indexées dans Elasticsearch, puis injecte la configuration Kibana via l’API Saved Objects (pas d’intervention manuelle).
Voici les choix techniques concrets qui rendent le pipeline robuste en production :
docker-compose up lance les 6 services (PostgreSQL, Airflow webserver, Airflow scheduler, Elasticsearch, Kibana, init container). Aucune installation manuelle..env local, exclu du dépôt Git via .gitignore. Le code source peut être rendu public sans risque.s3://bucket/<layer>/<group>/<dataEntity>/date=YYYY-MM-DD/hour=HH/. Spark lit directement la dernière partition sans scanner l’ensemble du bucket.Ce projet nous a confrontés à la réalité du Big Data bien au-delà des tutoriels :
Le projet est entièrement open source et disponible sur GitHub — SkySafe-DataLake.
Le dépôt contient toutes les instructions nécessaires pour le lancer dans votre propre environnement. Vous y trouverez le détail des prérequis, la configuration des variables d’environnement et les étapes de démarrage pas à pas.
Merci de nous avoir lus jusqu’ici !
Si ce projet vous a intéressé ou si vous avez des questions, n’hésitez pas à nous laisser une petite étoile sur le repo GitHub ⭐ ou à nous contacter.
Bon vol ! ✈️
Projet SkySafe — DATA705 BDD NoSQL — Télécom Paris — Février 2026