[PYTHON] Détection d'anomalies des données ECG par profil matriciel

L'exploration de données de séries chronologiques semble être une révolution par Matrix Profile. Cependant, il semble qu'il y ait encore peu de documents japonais, j'espère donc les ajouter. Cet article fournit une vue d'ensemble de MatrixProfile et un exemple d'implémentation en Python.

Qu'est-ce que le profil matriciel

C'est une combinaison similaire de séries chronologiques partielles.

Prenons une paire de données de séries chronologiques (A, B) (il peut s'agir d'une paire de la même série chronologique). Chaque série chronologique est décomposée en séries chronologiques partielles de longueur m. Pour toutes les séries chronologiques partielles dans A, l'indice de la série chronologique partielle dans B la plus proche et sa distance (similarité) sont appelés MatrixProfile. Si A et B sont la même série chronologique, la paire avec la série temporelle partielle sera optimale, de sorte que la zone autour de la série temporelle partielle sera ignorée.

無題.jpg Exemple de données sismiques et de profil matriciel [Yeh et. Al, ICDM2016]

Il faut énormément de temps pour calculer correctement, mais il est possible de le résoudre dans un temps réaliste en concevant un algorithme utilisant la FFT ou autre. C'est une révolution, non?

Pour plus de détails, voir https://www.cs.ucr.edu/~eamonn/MatrixProfile.html On dit que c'est une technologie du laboratoire du Dr Keogh de l'UCR, qui est célèbre pour SAX et Shapelet. Il semble que les titres des articles soient sérialisés sous la forme de Matrix Profile 〇〇:, et à partir de novembre 2019, il a été publié dans Matrix Profile XIX:.

Bibliothèque pour MatrixProfile "matrixprofile-ts"

Il existe déjà une bibliothèque Python ultra-simple MatrixProfile uniquement appelée matrixprofile-ts.

pip install matrixprofile-ts

Il est également disponible sur ici. Il semble qu'il y en ait aussi des R et C ++. Cette fois, nous essaierons de détecter des anomalies dans les données ECG en utilisant cette matrice profile-ts.

Problème de réglage

Cette fois, en utilisant une série de données ECG comprenant des parties de forme d'onde anormales, le problème est de calculer le degré d'anomalie à chaque point sans enseignant et d'identifier la partie anormale. Ci-dessous, nous allons passer à la mise en œuvre.

Lire les données ECG

Cette fois, nous utiliserons les données ECG appelées qtdbsel102. https://www.cs.ucr.edu/~eamonn/discords/qtdbsel102.txt Ce sont également les données utilisées dans l'article du professeur Keogh. La longueur des données étant très longue, nous utiliserons les 5000 premiers points. En passant, le profil de matrice est normalisé dans le processus de calcul, aucun prétraitement n'est donc nécessaire.

from matrixprofile import *
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

#Lire les données
ECG = pd.read_csv('qtdbsel102.txt', header=None, delimiter='\t')    
X = ECG.values[:5000,2]

#Visualisation ECG
plt.style.use('seaborn')
plt.figure(figsize=(16, 8))
plt.xlim(0, 5000)
plt.plot(X)
plt.axvspan(4200, 4400, facecolor='r', alpha=0.1)

ecg_data.png Des formes d'onde anormales apparaissent autour de 4200 à 4400 points. C'est évident en un coup d'œil.

Calcul du profil matriciel

C'est facile à mettre en œuvre grâce à l'excellente bibliothèque. L'hyper paramètre correspond uniquement à la longueur de la série chronologique partielle. Cette fois, réglez-le sur 200. En ce qui concerne la méthode de calcul, j'utiliserai ** SCRIMP ++ **, qui est la méthode la plus rapide et la plus récente, bien que la précision soit légèrement inférieure.

#Calcul de matriceProfile
window_size = 200
MP = matrixProfile.scrimp_plus_plus(X,window_size)

Détection d'anomalies

Dans les données avec une périodicité telle que l'ECG, une série chronologique partielle normale doit avoir une forme d'onde très similaire à elle-même dans d'autres parties. Inversement, s'il n'y a pas de forme d'onde similaire à elle-même, c'est-à-dire que la partie où la valeur de distance de Matrix Profile devient grande est considérée comme anormale. C'est la méthode dite du voisinage.

À propos, la colonne de distance et la colonne d'indice de référence sont stockées dans le MP calculé précédemment. Vérifions la colonne de distance et visualisons-la.

#Visualisation du profil de la matrice
plt.figure(figsize=(16, 8))

plt.subplot(2,1,1)
plt.xlim(0, 5000)
plt.title('ECG')
plt.plot(X)
x = np.arange(4200,4400)
plt.axvspan(4200, 4400, facecolor='r', alpha=0.1)

plt.subplot(2,1,2)
plt.xlim(0, 5000)
plt.title('MatrixProfile')
plt.plot(MP[0])
plt.axvspan(4200, 4400, facecolor='r', alpha=0.1)

ecg_and_mp.png Vous pouvez confirmer que l'anomalie a été détectée avec succès. De plus, vérifions la forme d'onde de la partie où la valeur de MatrixProfile est le maximum, c'est-à-dire la forme d'onde de la partie la plus anormale.

#Forme d'onde maximale de MatrixProfile et sa forme d'onde la plus proche
max_point_index = np.argmax(MP[0])
nearest_neighbor_index = MP[1][max_point_index]
plt.tight_layout()
fig, ax = plt.subplots(1, 3, figsize=(22, 6))


ax[0].plot(X[max_point_index:max_point_index+window_size], linewidth=5, color = "r")
ax[0].title.set_text("mp_peak(anormaly_wave)")

ax[1].plot(X[nearest_neighbor_index:nearest_neighbor_index+window_size], linewidth=5, color = "b")
ax[1].title.set_text("nearest_neighbor")

from sklearn.preprocessing import StandardScaler
S = StandardScaler()

ax[2].title.set_text("comparison")
ax[2].plot(S.fit_transform(X[max_point_index:max_point_index+window_size].reshape(-1,1)).flatten(), linewidth=5, color = "r")
ax[2].plot(S.fit_transform(X[nearest_neighbor_index:nearest_neighbor_index+window_size].reshape(-1,1)).flatten(), linewidth=5, color = "b")

図1.png La forme d'onde la plus à gauche est la plus grande forme d'onde MatrixProfile, le milieu est la forme d'onde la plus proche et la plus à droite est la comparaison normalisée en z de chaque forme d'onde. Eh bien, je ne suis pas un expert en ECG, donc je ne peux pas comprendre la signification de la forme d'onde, mais la forme d'onde anormale a plusieurs pics, petites bosses et déphasés en premier lieu. Vous pouvez voir la différence. C'est interprétable et agréable.

Forces du profil matriciel

"N'est-il pas possible de détecter des anomalies avec d'autres méthodes? L'apprentissage en profondeur est très bien." Beaucoup de gens peuvent le penser.

Cependant, l'attrait de Matrix Profile est sa simplicité. Bien qu'il existe une nouveauté étonnante dans le processus de calcul de MatrixProfile, ce qui est finalement produit est juste une correspondance entre des formes d'onde partielles. En d'autres termes, même si une anomalie est détectée, une personne peut facilement vérifier sa validité. En termes de fiabilité et de maniabilité, il n'y a rien de tel.

De plus, cette détection de forme d'onde anormale n'est qu'une des fonctions de Matrix Profile. Il semble qu'il existe de nombreuses applications, dont la découverte de Motif et Shapelet. C'est une révolution, non?

Résumé

Introduction de MatrixProfile et essai d'une bibliothèque appelée matrixprofile-ts: grinning:

Recommended Posts

Détection d'anomalies des données ECG par profil matriciel
Détection d'anomalies des données de séries chronologiques par LSTM (Keras)
Détection d'anomalies à l'aide de MNIST par Autoencoder (PyTorch)
Apprentissage profond appris par la mise en œuvre ~ Détection d'anomalies (apprentissage sans enseignant) ~
[Détection d'anomalies] Détecter la distorsion de l'image par apprentissage à distance
Matrice considérée par fonction
Fractionner les données par seuil
Données de formation par CNN
Corrélation par prétraitement des données
Détection d'anomalies Introduction 2 Détection des valeurs aberrantes
Détection d'anomalies en supposant une distribution normale multivariée par la méthode T ^ 2 d'hôtel
J'ai essayé d'implémenter la détection d'anomalies par apprentissage de structure clairsemée
Détection d'anomalies par encodeur automatique à l'aide de keras [Exemple d'implémentation pour les débutants]