Confus sur la façon d'appliquer KMeans sur mon jeu de données avec un caractéristiques extraites
-
16-10-2019 - |
Question
Je suis en train d'appliquer une utilisation de base du paquet scikit-learn KMeans Clustering, pour créer différents groupes que je pourrais utiliser pour identifier une certaine activité. Par exemple, dans mon jeu de données ci-dessous, je différents événements d'utilisation (0, ..., 11), et chaque événement a la puissance utilisée et la durée.
D'après les Wattage
, Duration
et timeOfDay
, je voudrais regrouper ces derniers dans différents groupes pour voir si je peux créer des clusters et la main classer les activités individuelles de chaque groupe.
J'avais des problèmes avec le paquet KMeans parce que je pense que mes valeurs nécessaires pour être en forme entière. Et puis, comment pourrais-je tracer les grappes sur un diagramme de dispersion? Je sais que je dois mettre les points de données originales sur le terrain, et je peux peut-être les séparer par la couleur du 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
Edit: Voici la sortie d'une de mes courses de K-means. Comment interpréter les moyens qui sont nuls? Qu'est-ce que cela signifie en termes de cluster et les mathématiques?
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
La solution
Pour les clusters, vos données doivent être bien entiers. De plus, étant donné que k-means est en utilisant la distance euclidienne, ayant la colonne catégorique n'est pas une bonne idée. Par conséquent, vous devez également encoder la colonne timeOfDay
en trois variables muettes. Enfin, ne pas oublier de normaliser vos données. Cela pourrait être pas important dans votre cas, mais en général, vous risquez que l'algorithme sera tiré dans la direction avec les plus grandes valeurs, ce qui est pas ce que vous voulez.
Je téléchargé vos données, mises en .csv et fait un exemple très simple. Vous pouvez voir que j'utilise différents dataframe pour le regroupement lui-même, puis une fois que je récupère les étiquettes de cluster, je les ajoute à la précédente.
Notez que l'horodatage Je laisse de côté variable - puisque la valeur est unique pour chaque enregistrement, il ne confondez pas l'algorithme.
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()
Cela peut nous dire quelles sont les différences entre les groupes. Il montre des valeurs moyennes de l'attribut par chaque groupe. On dirait groupe 0 sont des gens du soir avec une forte consommation, tandis que 1 sont des gens du matin avec une faible consommation.
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
Vous avez demandé la visualisation aussi bien. Ceci est difficile, car tout ce qui précède deux dimensions est difficile à lire. Donc, je l'ai mis sur Duration
la diffusion de complot contre Wattage
de couleur et les points en fonction de cluster.
Vous pouvez voir qu'il semble tout à fait raisonnable, sauf celui point bleu 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')