--ECG est connu pour favoriser la détection des maladies cardiaques
DataFrame
df = pd.read_table("ECGFiveDays_TRAIN.tsv",header=None)
df.head(10)
Cliquez ici pour le résumé des données
Summary
import numpy as np
import matplotlib.pyplot as plt
from tslearn.utils import to_time_series_dataset
data_train = np.loadtxt("ECGFiveDays_TRAIN.tsv")
X_train = to_time_series_dataset(data_train[:,1:])
print("Nombre total de données de séries chronologiques: ",len(data_train))
print("Nombre de cours: ", len(np.unique(data_train[:,0])))
print("Durée de la série chronologique: ",len(data_train[0,1:]))
----------------------
#Nombre total de données de séries chronologiques: 23
#Nombre de cours: 2
#Durée de la série chronologique: 136
Un total de 23 données chronologiques avec 136 clichés sont inclus. Il n'y a aucune valeur manquante.
Vizualize
%matplotlib inline
import numpy as np
import matplotlib.pyplot as plt
for i in range(0,3):
if data_train[i,0]==2.0:
plt.figure(figsize=(18, 8))
print("Plot",i,"Class",data_train[i,0])
plt.plot(data_train[i],c='r')
plt.show()
Étant donné que ces étiquettes sont fixées par des experts en ECG, les classes 1.0 et 2.0 sont presque impossibles à distinguer aux yeux d'un amateur. Aussi, en complément, selon Readme.md, qui est téléchargé avec ECGFiveDays_TRAIN.tsv, cet électrocardiogramme est des données ECG d'un homme de 67 ans mesurées en 1990.
Normaliser les données de chaque série temporelle afin qu'elles aient une moyenne de 0 et un écart type de 1 afin de les amener en forme de K. Ici, je vais normaliser l'ECG de Plot0, class1.0, le représenter graphiquement et le comparer.
Normalisation
from tslearn.preprocessing import TimeSeriesScalerMeanVariance
from tslearn.utils import to_time_series_dataset
X_train = to_time_series_dataset(data_train[:,1:])
X_train = TimeSeriesScalerMeanVariance(mu=0.,std=1.).fit_transform(X_train)
plt.figure(figsize=(18, 8))
plt.plot(X_train[1],c='magenta',alpha=0.8,label="normalized")
plt.plot(data_train[1],c='blue',alpha=0.8,label="original")
plt.legend(fontsize=17)
Je vais résumer brièvement avec 3 points.
--Une méthode de clustering basée sur la forme pour les données chronologiques
Exécutez avec 2 clusters, 100 itérations maximum et 100 formations.
Train
from tslearn.clustering import KShape
ks = KShape(n_clusters=2,max_iter=100,n_init=100,verbose=0)
ks.fit(X_train)
y_pred = ks.fit_predict(X_train)
print(y_pred)
---
#[0 1 0 0 1 0 0 1 0 1 1 1 1 0 0 0 1 0 1 1 1 0 1]
Pour un total de 23 séries chronologiques, nous avons pu mettre une étiquette de prédiction sur laquelle des deux classes serait classée. Pour les hyper paramètres liés à K-Shape, reportez-vous à l'URL suivante. https://tslearn.readthedocs.io/en/stable/gen_modules/clustering/tslearn.clustering.KShape.html
L '** indice foncier ajusté ** est utilisé comme échelle d'évaluation pour le regroupement des séries chronologiques. En un mot, cette métrique mesure «dans quelle mesure les attributions de cluster correspondent entre le clustering prévu et le clustering réel».
Ici, le score ajusté de Scikit-learn est utilisé. https://scikit-learn.org/stable/modules/generated/sklearn.metrics.adjusted_rand_score.html
Évaluation(Pour les données d'entraînement)
from sklearn.metrics import adjusted_rand_score
ars = adjusted_rand_score(data_train[:,0],y_pred)
print("Indice foncier ajusté: ",ars)
---
#Indice foncier ajusté: 0.668041237113402
Ensuite, recherchez les ars des données de test.
Évaluation(Pour les données de test)
import numpy as np
import matplotlib.pyplot as plt
from tslearn.utils import to_time_series_dataset
data_test = np.loadtxt("ECGFiveDays_TEST.tsv")
X_test = to_time_series_dataset(data_test[:,1:])
pred_test = ks.predict(X_test)
ars = adjusted_rand_score(data_test[:,0],pred_test)
print("Indice foncier ajusté: ",ars)
---
#Indice foncier ajusté: 0.06420517898316379
J'ai un score très bas.
Score proche de 0=Score lorsque attribué au hasard
En raison de la logique, on ne peut jamais dire que c'est un bon modèle. On pense que la raison pour laquelle le score des données de test est faible est que le nombre de données est extrêmement faible. Augmentez donc le nombre de données et essayez la même chose.
Ce qui suit utilise ** ECG5000_TRAIN.tsv ** et ** ECG500_TEST.tsv ** empaquetés dans l'archive UCR.
Jeu de données ECG5000
import numpy as np
import matplotlib.pyplot as plt
from tslearn.utils import to_time_series_dataset
from sklearn.model_selection import train_test_split
data_test_ = np.loadtxt("ECG5000_TEST.tsv")
data_train_ = np.loadtxt("ECG5000_TRAIN.tsv")
data_joined = np.concatenate((data_train_,data_test_),axis=0)
data_train_,data_test_ =train_test_split(data_joined,test_size=0.2,random_state=2000)
X_train_ = to_time_series_dataset(data_train_[:,1:])
X_test_ = to_time_series_dataset(data_test_[:,1:])
print("Nombre total de données de séries chronologiques: ",len(data_train_))
print("Nombre de cours: ", len(np.unique(data_train_[:,0])))
print("Durée de la série chronologique: ",len(data_train_[0,1:]))
---
#Nombre total de données de séries chronologiques: 4000
#Nombre de cours: 5
#Durée de la série chronologique: 140
Cliquez ici pour le nombre de données appartenant au cluster
Détails du cluster
print("Classe 1.Nombre de données appartenant à 0",len(data_train_[data_train_[:,0]==1.0]))
print("Classe 1.Nombre de données appartenant à 0",len(data_train_[data_train_[:,0]==2.0]))
print("Classe 1.Nombre de données appartenant à 0",len(data_train_[data_train_[:,0]==3.0]))
print("Classe 1.Nombre de données appartenant à 0",len(data_train_[data_train_[:,0]==4.0]))
print("Classe 1.Nombre de données appartenant à 0",len(data_train_[data_train_[:,0]==5.0]))
---
#Classe 1.Nombre de données appartenant à 0 2342
#Classe 1.Nombre de données appartenant à 0 1415
#Classe 1.Nombre de données appartenant à 0 74
#Classe 1.Nombre de données appartenant à 0153
#Classe 1.Nombre de données appartenant à 0 16
Cela ressemble à ceci dans un graphique
Visualisation de chaque cluster
%matplotlib inline
import matplotlib.pyplot as plt
for j in np.unique(data_train_[:,0]):
plt.figure(figsize=(28,2))
dataPlot = data_train_[data_train_[:,0]==j]
cnt = len(dataPlot)
dataPlot = dataPlot[:,1:].mean(axis=0)
print(" Class ",j," Count ",cnt)
plt.plot(dataPlot,c='b')
plt.show()
Nous nous formerons et évaluerons comme avant
Entraînement/Évaluation(Pour les données de test)
from tslearn.preprocessing import TimeSeriesScalerMeanVariance
from tslearn.utils import to_time_series_dataset
from tslearn.clustering import KShape
from sklearn.metrics import adjusted_rand_score
X_train_ = to_time_series_dataset(data_train_[:,1:])
X_train_ = TimeSeriesScalerMeanVariance(mu=0.,std=1.).fit_transform(X_train_)
X_test_ = to_time_series_dataset(data_test_[:,1:])
X_test_ = TimeSeriesScalerMeanVariance(mu=0.,std=1.).fit_transform(X_test_)
ks = KShape(n_clusters=5,max_iter=100,n_init=100,verbose=1,random_state=2000)
ks.fit(X_train_)
preds_test = ks.predict(X_test_)
ars_ = adjusted_rand_score(data_test_[:,0],preds_test)
print("Indice foncier ajusté: ",ars_)
---
#Indice foncier ajusté: 0.4984050982000773
L'indice de terrain d'évaluation appliqué aux données de test était d'environ 0,498 </ font>. Par rapport à l'application de données précédente, c'est une différence dans la boue des nuages. En augmentant la taille de l'ensemble d'entraînement de 23 à 4000, un modèle beaucoup plus précis a été créé.
Enfin, regardons les données de test
Visualisation des résultats de classification
for yi in range(5):
plt.figure(figsize=(20,35))
plt.subplot(5, 1, 1 + yi)
for xx in X_test_[preds_test == yi]:
plt.plot(xx.ravel(), alpha=0.1,c='blue')
cnt = len(X_test_[preds_test == yi])
plt.plot(ks.cluster_centers_[yi].ravel(), "red")
print(" Class ",yi," Count ",cnt)
plt.title("Cluster %d" % (yi + 1) )
plt.tight_layout()
plt.show()
Voici une visualisation des résultats de classification des données de test (la ligne rouge est le centre de gravité)
SBD(\vec{x},\vec{y})=1-\underset{w}{max}\frac{CC_w(\vec{x},\vec{y})}{\sqrt{R_0(\vec{x},\vec{x})}\sqrt{R_0(\vec{y},\vec{y})}}
--Introduire la similarité et la corrélation mutuelle $ CC_w $ qui correspondent bien aux données de séries chronologiques
tslearn est un package Python pour l'analyse de séries chronologiques à l'aide de l'apprentissage automatique. En plus de K-Shape, divers algorithmes d'analyse de séries chronologiques sont inclus.
Recommended Posts