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  
È stato utile?

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')

 entrare descrizione dell'immagine qui

Autorizzato sotto: CC-BY-SA insieme a attribuzione
scroll top