Confuso su come applicare K-Means sul mio un insieme di dati con caratteristiche estratte
-
16-10-2019 - |
Domanda
Sto cercando di applicare un utilizzo di base del pacchetto di scikit-learn K-Means clustering, per creare diversi cluster che potrei utilizzare per identificare una certa attività. Ad esempio, nel mio set di dati di seguito, ho diversi eventi di utilizzo (0, ..., 11), e ogni evento ha la potenza utilizzata e la durata.
In base alla Wattage
, Duration
e timeOfDay
, vorrei raggruppare questi in gruppi diversi per vedere se riesco a creare cluster e mano-classificare le singole attività di ogni cluster.
I aveva problemi con il pacchetto K-Means perché penso che i miei valori necessari per essere in forma intero. E poi, come potrei tracciare i cluster su un grafico a dispersione? So che ho bisogno di mettere le datapoints originali sulla trama, e poi magari mi può separarli per colore dal cluster?
km = KMeans(n_clusters = 5)
myFit = km.fit(activity_dataset)
Wattage time_stamp timeOfDay Duration (s)
0 100 2015-02-24 10:00:00 Morning 30
1 120 2015-02-24 11:00:00 Morning 27
2 104 2015-02-24 12:00:00 Morning 25
3 105 2015-02-24 13:00:00 Afternoon 15
4 109 2015-02-24 14:00:00 Afternoon 35
5 120 2015-02-24 15:00:00 Afternoon 49
6 450 2015-02-24 16:00:00 Afternoon 120
7 200 2015-02-24 17:00:00 Evening 145
8 300 2015-02-24 18:00:00 Evening 65
9 190 2015-02-24 19:00:00 Evening 35
10 100 2015-02-24 20:00:00 Evening 45
11 110 2015-02-24 21:00:00 Evening 100
Modifica Ecco l'uscita da una delle mie corse di K-Means Clustering. Come si interpretano i mezzi che sono a zero? Che cosa significa questo in termini di cluster e la matematica?
print (waterUsage[clmns].groupby(['clusters']).mean())
water_volume duration timeOfDay_Afternoon timeOfDay_Evening \
clusters
0 0.119370 8.689516 0.000000 0.000000
1 0.164174 11.114241 0.474178 0.525822
timeOfDay_Morning outdoorTemp
clusters
0 1.0 20.821613
1 0.0 25.636901
Soluzione
Per il clustering, i dati devono essere davvero interi. Inoltre, poiché k-means sta usando distanza euclidea, avendo colonna categorica non è una buona idea. Pertanto si dovrebbe anche codificare il timeOfDay
colonna in tre variabili dummy. Infine, non dimenticate di uniformare i dati. Questo potrebbe essere non è importante nel tuo caso, ma in generale, si rischia che l'algoritmo sarà tirato in direzione con i valori più grandi, che non è quello che si desidera.
Così ho scaricato i dati, messi in .csv e ha fatto un esempio molto semplice. Si può vedere che sto usando dataframe diverso per il raggruppamento stesso e poi una volta a recuperare le etichette a grappolo, li aggiungo a quella precedente.
Si noti che tralascio il timestamp variabili - in quanto il valore è univoco per ogni record, sarà solo confondere l'algoritmo.
import pandas as pd
from scipy import stats
from sklearn.cluster import KMeans
import matplotlib.pyplot as plt
import seaborn as sns
df = pd.read_csv('C:/.../Dataset.csv',sep=';')
#Make a copy of DF
df_tr = df
#Transsform the timeOfDay to dummies
df_tr = pd.get_dummies(df_tr, columns=['timeOfDay'])
#Standardize
clmns = ['Wattage', 'Duration','timeOfDay_Afternoon', 'timeOfDay_Evening',
'timeOfDay_Morning']
df_tr_std = stats.zscore(df_tr[clmns])
#Cluster the data
kmeans = KMeans(n_clusters=2, random_state=0).fit(df_tr_std)
labels = kmeans.labels_
#Glue back to originaal data
df_tr['clusters'] = labels
#Add the column into our list
clmns.extend(['clusters'])
#Lets analyze the clusters
print df_tr[clmns].groupby(['clusters']).mean()
Questo può dirci quali sono le differenze tra i cluster. Essa mostra valori medi dell'attributo per ogni cluster. Looks come gruppo 0 sono persone serali con elevato consumo, mentre 1 sono persone di mattina con piccoli consumi.
clusters Wattage Duration timeOfDay_Afternoon timeOfDay_Evening timeOfDay_Morning
0 225.000000 85.000000 0.166667 0.833333 0.0
1 109.666667 30.166667 0.500000 0.000000 0.5
ha chiesto per la visualizzazione pure. Questo è difficile, perché tutto sopra due dimensioni è difficile da leggere. Così ho messo su Duration
diagramma a dispersione contro Wattage
e colorato i punti sulla base di cluster.
Si può vedere che sembra abbastanza ragionevole, ad eccezione di quello punto blu lì.
#Scatter plot of Wattage and Duration
sns.lmplot('Wattage', 'Duration',
data=df_tr,
fit_reg=False,
hue="clusters",
scatter_kws={"marker": "D",
"s": 100})
plt.title('Clusters Wattage vs Duration')
plt.xlabel('Wattage')
plt.ylabel('Duration')