Dieses Mal verwenden wir das UCR Time Series Classification Archive der University of California, Riverside.
EKG fördert bekanntermaßen die Erkennung von Herzerkrankungen
Der zu verwendende Inhalt von ** ECGFiveDays_TRAIN.tsv ** lautet wie folgt.
DataFrame
df = pd.read_table("ECGFiveDays_TRAIN.tsv",header=None)
df.head(10)
Klicken Sie hier für eine Datenübersicht
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("Gesamtzahl der Zeitreihendaten: ",len(data_train))
print("Anzahl der Klassen: ", len(np.unique(data_train[:,0])))
print("Zeitreihenlänge: ",len(data_train[0,1:]))
----------------------
#Gesamtzahl der Zeitreihendaten: 23
#Anzahl der Klassen: 2
#Zeitreihenlänge: 136
Insgesamt sind 23 Zeitreihendaten mit 136 Schnappschüssen enthalten. Es fehlen keine Werte.
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()
Da diese Etiketten von EKG-Experten angebracht werden, sind sowohl Klasse 1.0 als auch Klasse 2.0 für die Augen eines Amateurs kaum zu unterscheiden. Als Ergänzung enthält dieses Elektrokardiogramm laut Readme.md, das mit ECGFiveDays_TRAIN.tsv heruntergeladen wird, EKG-Daten eines 67-jährigen Mannes, die 1990 gemessen wurden.
Normalisieren Sie alle Zeitreihendaten so, dass sie einen Durchschnitt von 0 und eine Standardabweichung von 1 haben, um sie in die K-Form zu bringen. Hier werde ich das EKG von Plot0, Klasse 1.0, normalisieren, grafisch darstellen und vergleichen.
Normalisierung
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)
Ich werde kurz mit 3 Punkten zusammenfassen.
Führen Sie 2 Cluster, 100 maximale Iterationen und 100 Trainings aus.
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]
Für insgesamt 23 Zeitreihen konnten wir ein Vorhersageetikett anbringen, auf welche der beiden Klassen klassifiziert werden würde. Informationen zu Hyperparametern in Bezug auf K-Shape finden Sie unter der folgenden URL. https://tslearn.readthedocs.io/en/stable/gen_modules/clustering/tslearn.clustering.KShape.html
Der ** angepasste Landindex ** wird als Bewertungsskala für die Zeitreihenclusterung verwendet. Kurz gesagt, diese Metrik misst, "wie gut die Clusterzuordnungen zwischen vorhergesagtem Clustering und echtem Clustering übereinstimmen".
Hier wird der angepasste_Rand_score von Scikit-learn verwendet. https://scikit-learn.org/stable/modules/generated/sklearn.metrics.adjusted_rand_score.html
Auswertung(Für Trainingsdaten)
from sklearn.metrics import adjusted_rand_score
ars = adjusted_rand_score(data_train[:,0],y_pred)
print("Angepasster Landindex: ",ars)
---
#Angepasster Landindex: 0.668041237113402
Als nächstes finden Sie die Ars für die Testdaten.
Auswertung(Für Testdaten)
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("Angepasster Landindex: ",ars)
---
#Angepasster Landindex: 0.06420517898316379
Ich habe eine sehr niedrige Punktzahl.
Punktzahl nahe 0=Punktzahl bei zufälliger Zuordnung
Aufgrund der Logik kann niemals gesagt werden, dass es sich um ein gutes Modell handelt. Der Grund, warum die Punktzahl für die Testdaten niedrig ist, wird angenommen, dass die Anzahl der Daten überwiegend gering ist. Erhöhen Sie also die Anzahl der Daten und versuchen Sie es gleich.
Im Folgenden werden ** ECG5000_TRAIN.tsv ** und ** ECG500_TEST.tsv ** verwendet, die im UCR-Archiv enthalten sind.
EKG5000-Datensatz
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("Gesamtzahl der Zeitreihendaten: ",len(data_train_))
print("Anzahl der Klassen: ", len(np.unique(data_train_[:,0])))
print("Zeitreihenlänge: ",len(data_train_[0,1:]))
---
#Gesamtzahl der Zeitreihendaten: 4000
#Anzahl der Klassen: 5
#Zeitreihenlänge: 140
Klicken Sie hier, um die Anzahl der zum Cluster gehörenden Daten anzuzeigen
Clusterdetails
print("Klasse 1.Anzahl der zu 0 gehörenden Daten",len(data_train_[data_train_[:,0]==1.0]))
print("Klasse 1.Anzahl der zu 0 gehörenden Daten",len(data_train_[data_train_[:,0]==2.0]))
print("Klasse 1.Anzahl der zu 0 gehörenden Daten",len(data_train_[data_train_[:,0]==3.0]))
print("Klasse 1.Anzahl der zu 0 gehörenden Daten",len(data_train_[data_train_[:,0]==4.0]))
print("Klasse 1.Anzahl der zu 0 gehörenden Daten",len(data_train_[data_train_[:,0]==5.0]))
---
#Klasse 1.Anzahl der Daten zu 0 2342
#Klasse 1.Anzahl der Daten zu 0 1415
#Klasse 1.Anzahl der Daten zu 0 74
#Klasse 1.Anzahl der zu 0 153 gehörenden Daten
#Klasse 1.Anzahl der Daten zu 0 16
In einem Diagramm sieht es so aus
Visualisierung jedes Clusters
%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()
Wir werden wie bisher trainieren und bewerten
Ausbildung/Auswertung(Für Testdaten)
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("Angepasster Landindex: ",ars_)
---
#Angepasster Landindex: 0.4984050982000773
Der Bewertungslandindex betrug bei Anwendung auf die Testdaten etwa 0,498 </ font>. Im Vergleich zur vorherigen Datenanwendung ist es ein Unterschied im Wolkenschlamm. Durch Erhöhen der Größe des Trainingssatzes von 23 auf 4000 wurde ein viel genaueres Modell erstellt.
Schauen wir uns zum Schluss die Testdaten an
Visualisierung der Klassifizierungsergebnisse
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()
Hier ist eine Visualisierung der Klassifizierungsergebnisse der Testdaten (rote Linie ist Centroid)
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})}}
tslearn ist ein Python-Paket für die Zeitreihenanalyse mit maschinellem Lernen. Neben K-Shape sind verschiedene Algorithmen zur Zeitreihenanalyse enthalten.
Recommended Posts