
Une boîte à outils pratique pour la détection des anomalies de séries chronologiques, à l’aide de Python
Les aspects fascinants des séries chronologiques sont complexité intrinsèque d’un type de données apparemment simple.
En fin de compte, dans les séries chronologiques, vous avez un axe x qui représente généralement le temps
Cependant, c’est dans l’évolution de la quantité d’intérêt (axe y) au fil du temps (axe x) que se cache la complexité. Cette évolution présente-t-elle un s’orienter? Est-ce qu’il en a points de données qui dévient clairement du signal attendu ? Est-ce écurie ou imprévisible ? Est-ce la valeur moyenne de la quantité plus grand que ce à quoi nous nous attendrions ? Tout cela peut être défini d’une manière ou d’une autre comme anomalies.
Cet article est une collection de plusieurs techniques de détection d’anomalies. L’objectif est que, étant donné un ensemble de données composé de plusieurs séries temporelles, nous puissions détecter lequel la série chronologique est anormale et pourquoi.
Voici les 4 anomalies de séries chronologiques que nous allons détecter :
- Nous allons détecter toute tendance dans notre série chronologique (anomalie de tendance)
- Nous allons évaluer la volatilité de la série chronologique (anomalie de volatilité).
- Nous allons détecter les anomalies ponctuelles dans la série chronologique (anomalie ponctuelle).
- Nous allons détecter les anomalies au sein de notre banque de signaux, pour comprendre quel signal se comporte différemment de notre ensemble de signaux (anomalie au niveau de l’ensemble de données).

Nous allons décrire théoriquement chaque méthode de détection d’anomalies de cette collection, et nous allons montrer l’implémentation Python. L’intégralité du code que j’ai utilisé pour ce billet de blog est inclus dans le PieroPaialungaAI/timeseriesanomalie Dossier GitHub
0. L’ensemble de données
Afin de construire le collecteur d’anomalies, nous devons disposer d’un ensemble de données dans lequel nous savons exactement quelle anomalie nous recherchons, afin de savoir si notre détecteur d’anomalies fonctionne ou non. Pour ce faire, j’ai créé un données.py scénario. Le script contient un objet DataGenerator qui :
- Lit la configuration de notre jeu de données à partir d’un fichier config.json*.
- Crée un ensemble de données d’anomalies
- Vous donne la possibilité de facilement magasin les données et parcelle eux.
Voici l’extrait de code :

On voit donc qu’on a :
- Un partage axe du tempsde 0 à 100
- Séries chronologiques multiples qui forment une série temporelle ensemble de données
- Chaque série chronologique présente un ou plusieurs anomalies.
Les anomalies sont, comme prévu :
- Le comportement de tendanceoù les séries temporelles ont un comportement de degré linéaire ou polynomial
- La volatilitéoù la série chronologique est plus volatile et changeante que la normale
- Le changement de niveauoù la série chronologique a une moyenne supérieure à la normale
- Une anomalie ponctuelleoù la série chronologique présente un point anormal.
Maintenant, notre objectif sera d’avoir un boîte à outils qui peut identifier chacune de ces anomalies pour l’ensemble de l’ensemble de données.
*Le fichier config.json vous permet de modifier tous les paramètres de notre jeu de données, tels que le nombre de séries temporelles, l’axe des séries temporelles et le type d’anomalies. Voici à quoi cela ressemble :
1. Identification des anomalies de tendance
1.1 Théorie
Lorsque nous disons « une anomalie de tendance », nous recherchons une comportement structurel: la série évolue vers le haut ou vers le bas au fil du temps, ou elle se courbe de manière cohérente. Cela est important dans les données réelles, car la dérive signifie souvent une dégradation du capteur, un changement de comportement des utilisateurs, des problèmes de modèle/de pipeline de données ou un autre phénomène sous-jacent à étudier dans votre ensemble de données.
Nous considérons deux types de tendances :
- Régression linéaire: nous ajustons la série temporelle avec une tendance linéaire
- Régression polynomiale: nous ajustons la série temporelle avec un polynôme de bas degré.
En pratique, nous mesurons l’erreur du modèle de régression linéaire. S’il est trop grand, nous appliquons celui de la régression polynomiale. Nous considérons qu’une tendance est « significative » lorsque la valeur p est inférieure à un seuil défini (généralement p < 0,05).
1.2 Code
L’objet AnomalyDetector dans anomalie_detector.py exécutera le code décrit ci-dessus en utilisant les fonctions suivantes :
- Le détecteurqui chargera les données que nous avons générées dans DataGenerator.
- détecter_trend_anomaly et détecter_all_trends détecter la tendance (éventuelle) pour une seule série temporelle et pour l’ensemble des données, respectivement
- get_series_with_trend renvoie les indices qui ont une tendance significative.
Nous pouvons utiliser plot_trend_anomalies pour afficher la série chronologique et voir comment nous allons :

Bien! Nous sommes donc en mesure de récupérer les séries temporelles « tendance » dans notre ensemble de données sans aucun bug. Passons à autre chose !
2. Identification des anomalies de volatilité
2.1 Théorie
Maintenant que nous avons une tendance mondiale, nous pouvons nous concentrer sur volatilité. Ce que j’entends par volatilité, c’est, en clair, à quel point nos séries chronologiques sont-elles partout ? En termes plus précis, comment la variance de la série chronologique se compare-t-elle à la moyenne de notre ensemble de données ?
Voici comment nous allons tester cette anomalie :
- Nous allons supprimer la tendance à partir de l’ensemble de données de la série temporelle.
- Nous allons trouver le statistiques de la variance.
- Nous allons trouver le valeurs aberrantes de ces statistiques
Assez simple, non ? Passons au code !
2.2 Codes
De la même manière que ce que nous avons fait pour les tendances, nous avons :
- détecter_volatilité_anomaliequi vérifie si une série chronologique donnée présente ou non une anomalie de volatilité.
- détecter_all_volatilitieset get_series_with_high_volatilityqui vérifient l’ensemble des ensembles de données de séries chronologiques pour détecter les anomalies de volatilité et renvoient les indices anormaux, respectivement.
Voici comment nous affichons les résultats :

3. Anomalie ponctuelle
3.1 Théorie
Ok, ignorons maintenant toutes les autres séries chronologiques de l’ensemble de données et concentrons-nous sur chaque série chronologique à la fois. Pour notre série chronologique qui nous intéresse, nous voulons voir si nous avons un point qui est clairement anormal. Il existe de nombreuses façons de procéder ; nous pouvons exploiter les Transformers, 1D CNN, LSTM, Encoder-Decoder, etc. Par souci de simplicité, utilisons un algorithme très simple :
- Nous allons adopter un fenêtre roulante approche, où une fenêtre de taille fixe se déplacera de gauche à droite
- Pour chaque point, on calcule le signifier et écart type de sa fenêtre environnante (à l’exclusion du point lui-même)
- Nous calculons de combien d’écarts types le point se trouve éloigné de son voisinage local en utilisant le Score Z
Nous définissons un point comme anormal lorsqu’il dépasse une valeur fixe du score Z. Nous allons utiliser le score Z = 3, ce qui signifie 3 fois les écarts types.
3.2 Codes
De la même manière que ce que nous avons fait pour les tendances et la volatilité, nous avons :
- détecter_point_anomaliequi vérifie si une série chronologique donnée présente des anomalies ponctuelles à l’aide de la méthode du score Z à fenêtre glissante.
- détecter_all_point_anomalies et get_series_with_point_anomaliesqui vérifient l’ensemble des données de la série chronologique pour détecter les anomalies ponctuelles et renvoient respectivement les indices des séries contenant au moins un point anormal.
Et voici comment cela fonctionne :

4. Anomalie au niveau de l’ensemble de données
4.1 Théorie
Cette partie est volontairement simple. Nous voici pas à la recherche de moments étranges dans le temps, nous recherchons signaux étranges à la banque. Ce à quoi nous voulons répondre est :
Existe-t-il des séries chronologiques dont l’ampleur globale est nettement plus grande (ou plus petite) que ce à quoi nous nous attendons compte tenu du reste de l’ensemble de données ?
Pour ce faire, nous compressons chaque série temporelle en un seul nombre « de référence » (un niveau typique), puis nous comparons ces références dans l’ensemble de la banque. La comparaison se fera en termes de médian et Note Z.
4.2 Codes
Voici comment nous traitons l’anomalie au niveau de l’ensemble de données :
- détecter_dataset_level_anomalies()recherche l’anomalie au niveau de l’ensemble de données sur l’ensemble de l’ensemble de données.
- get_dataset_level_anomalies()trouve les indices qui présentent une anomalie au niveau de l’ensemble de données.
- plot_dataset_level_anomalies()affiche un échantillon de séries chronologiques présentant des anomalies.
Voici le code pour le faire :

5. Tous ensemble !
Ok, il est temps de tout mettre en place. Nous utiliserons détecteur.detect_all_anomalies() et nous évaluerons les anomalies pour l’ensemble de données en fonction de tendance, volatilité, point unique et au niveau de l’ensemble de données anomalies. Le script pour faire cela est très simple :
Le df vous donnera l’anomalie pour chaque série chronologique. Voici à quoi cela ressemble :
Si nous utilisons la fonction suivante, nous pouvons le voir en action :

Assez impressionnant, non ? Nous l’avons fait. 🙂
6. Conclusions
Merci de passer du temps avec nous, cela signifie beaucoup. ❤️ Voici ce que nous avons réalisé ensemble :
- Création d’une petite boîte à outils de détection d’anomalies pour un banque de séries chronologiques.
- Détecté anomalies de tendance en utilisant la régression linéaire et la régression polynomiale lorsque l’ajustement linéaire n’est pas suffisant.
- Détecté anomalies de volatilité en déduisant d’abord la tendance, puis en comparant la variance à travers l’ensemble de données.
- Détecté anomalies ponctuelles avec une fenêtre roulante Z-score (simple, rapide et étonnamment efficace).
- Détecté anomalies au niveau de l’ensemble de données en compressant chaque série en une ligne de base (médiane) et en signalant les signaux qui vivent sur une échelle de magnitude différente.
- Rassemblez le tout dans un seul pipeline qui renvoie un tableau récapitulatif propre, nous pouvons inspecter ou tracer.
Dans de nombreux projets réels, une boîte à outils comme celle que nous avons construite ici vous mène très loin, car :
- Cela vous donne explicable signaux (tendance, volatilité, changement de ligne de base, valeurs aberrantes locales).
- Cela vous donne une forte ligne de base avant de passer à des modèles plus lourds.
- Cela évolue bien lorsque vous avez de nombreux signauxc’est là que la détection des anomalies devient généralement douloureuse.
Gardez à l’esprit que la base de référence est volontairement simple et qu’elle utilise des statistiques très simples. Cependant, la modularité du code vous permet d’ajouter facilement de la complexité en ajoutant simplement la fonctionnalité dans le anomalie_detector_utils.py et anomalie_detector.py.
7. Avant de partir !
Merci encore pour votre temps. Cela signifie beaucoup ❤️
Je m’appelle Piero Paialunga et je suis ce type ici :

Je suis originaire d’Italie, je suis titulaire d’un doctorat. de la Université de Cincinnatiet travaille comme Data Scientist chez The Trade Desk à New York. J’écris sur IA, apprentissage automatique et rôle évolutif des data scientists à la fois ici sur TDS et sur LinkedIn. Si l’article vous a plu et souhaitez en savoir plus sur le machine learning et suivre mes études, vous pouvez :
A. Suivez-moi sur Linkedinoù je publie toutes mes histoires
B. Suivez-moi sur GitHuboù vous pouvez voir tout mon code
C. Pour toute question, vous pouvez m’envoyer un email à piero.paialunga@hotmail



