对如何在提取特征的数据集上应用 KMeans 感到困惑

数据挖掘 Python 聚类 k-均值 无监督学习
2021-09-29 06:11:36

我正在尝试应用 scikitlearn KMeans Clustering 包的基本用法,以创建可用于识别特定活动的不同集群。例如,在下面的数据集中,我有不同的使用事件(0、...、11),每个事件都有使用的瓦数和持续时间。

基于WattageDurationtimeOfDay,我想将它们分成不同的组,看看我是否可以创建集群并手动分类每个集群的各个活动。

我在使用 KMeans 包时遇到了问题,因为我认为我的值需要采用整数形式。然后,我将如何在散点图上绘制集群?我知道我需要将原始数据点放在图上,然后也许我可以通过颜色将它们与集群分开?

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

编辑: 这是我运行的一次 K-Means 聚类的输出。我如何解释为零的均值?这在集群和数学方面意味着什么?

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  
1个回答

对于聚类,您的数据必须确实是整数。此外,由于 k-means 使用的是欧几里德距离,因此使用分类列并不是一个好主意。因此,您还应该将该列编码timeOfDay为三个虚拟变量。最后,不要忘记标准化您的数据。在您的情况下,这可能并不重要,但总的来说,您可能会冒着算法被拉到具有最大值的方向的风险,这不是您想要的。

所以我下载了你的数据,放入 .csv 并做了一个非常简单的例子。您可以看到我为集群本身使用了不同的数据框,然后在检索集群标签后,我将它们添加到前一个标签中。

请注意,我省略了变量时间戳 - 因为每个记录的值都是唯一的,它只会混淆算法。

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

这可以告诉我们集群之间有什么区别。它显示每个集群的属性平均值。看起来集群 0 是晚上消费量高的人,而集群 1 是早上消费量少的人。

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

你也要求可视化。这很棘手,因为二维以上的所有内容都难以阅读。所以我把散点图放在了散点图上DurationWattage并根据集群给点上色。

您可以看到它看起来很合理,除了那里的一个蓝点。

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

在此处输入图像描述