Pregunta

Estoy intentando aplicar un uso básico del paquete scikitlearn KMeans Clustering, para crear diferentes clusters que podría usar para identificar una determinada actividad.Por ejemplo, en mi conjunto de datos a continuación, tengo diferentes eventos de uso (0,...,11) y cada evento tiene la potencia utilizada y la duración.

Basado en el Wattage, Duration, y timeOfDay, Me gustaría agruparlos en diferentes grupos para ver si puedo crear grupos y clasificar manualmente las actividades individuales de cada grupo.

Estaba teniendo problemas con el paquete KMeans porque creo que mis valores debían estar en forma de números enteros.Y luego, ¿cómo trazaría los grupos en un diagrama de dispersión?Sé que necesito colocar los puntos de datos originales en el gráfico y luego tal vez pueda separarlos por color del grupo.

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

Editar:Aquí está el resultado de una de mis ejecuciones de K-Means Clustering.¿Cómo interpreto las medias que son cero?¿Qué significa esto en términos del grupo y las matemáticas?

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  
¿Fue útil?

Solución

Para la agrupación, sus datos deben ser números enteros.Además, dado que k-means utiliza una distancia euclidiana, tener una columna categórica no es una buena idea.Por lo tanto, también debes codificar la columna. timeOfDay en tres variables ficticias.Por último, no olvides estandarizar tus datos.Puede que esto no sea importante en su caso, pero en general, corre el riesgo de que el algoritmo se oriente en la dirección con los valores más grandes, que no es lo que desea.

Así que descargué sus datos, los puse en .csv e hice un ejemplo muy simple.Puede ver que estoy usando un marco de datos diferente para la agrupación en sí y luego, una vez que recupero las etiquetas del grupo, las agrego a la anterior.

Tenga en cuenta que omito la marca de tiempo variable; dado que el valor es único para cada registro, solo confundirá el 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()

Esto puede decirnos cuáles son las diferencias entre los grupos.Muestra los valores medios del atributo por cada grupo.Parece que el grupo 0 son personas nocturnas con alto consumo, mientras que el 1 son personas matutinas con bajo consumo.

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

También pediste visualización.Esto es complicado, porque todo lo que está por encima de dos dimensiones es difícil de leer.Entonces puse un diagrama de dispersión. Duration contra Wattage y coloreé los puntos según el grupo.

Puedes ver que parece bastante razonable, excepto el punto azul que hay allí.

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

enter image description here

Licenciado bajo: CC-BY-SA con atribución
scroll top