Python k-mean,质心放置在集群之外

Posted

技术标签:

【中文标题】Python k-mean,质心放置在集群之外【英文标题】:Python k-mean, centroids are placed outside of the clusters 【发布时间】:2018-10-11 23:07:56 【问题描述】:

我正在尝试使用 k-means 算法对混合数据进行聚类:chemical_1chemical_2 - 数字、season - 分类。 将season 列转换为假人,以便在 K-means 算法中使用它。

我用plt.scatter(centers[:,0], centers[:,1], marker="x", color='r') 添加了集群中心,但它把它们放在了错误的位置,在集群之外。 我应该如何处理kmeans.cluster_centers_ 才能正确绘制它们?

#Make a copy of DF
df_transformed = df

#Transform the 'season' to dummies
df_transformed = pd.get_dummies(df_transformed, columns=['season'])

#Standardize
columns = ['chemical_1', 'chemical_2', 'season_winter', 'season_spring', 'season_autumn', 'season_summer']
df_tr_std = stats.zscore(df_transformed[columns])

#Cluster the data
kmeans = KMeans(n_clusters=4).fit(df_tr_std)
labels = kmeans.labels_
centers = np.array(kmeans.cluster_centers_)

#Glue back to original data
df_transformed['clusters'] = labels

#Add the column into our list
columns.extend(['clusters'])

#Analyzing the clusters
print(df_transformed[columns].groupby(['clusters']).mean())

          chemical_1  chemical_2  season_winter  season_spring  season_autumn  \
clusters                                                                        
0           7.951500   10.600500              0              0              1   
1           8.119180    8.818852              1              0              0   
2           8.024423    8.009615              0              1              0   
3           7.939432    9.414773              0              0              0   

          season_summer  
clusters                 
0                     0  
1                     0  
2                     0  
3                     1

#Scatter plot of chemical_1 and chemical_2
sns.lmplot('chemical_1', 'chemical_2', 
           data=df_transformed,
           size = 10,
           fit_reg=False, 
           hue="clusters",  
           scatter_kws="marker": "D", 
                        "s": 100
          )
plt.scatter(centers[:,0], centers[:,1], marker="x", color='r')

plt.title('Clusters chemical_1 vs chemical_2')
plt.xlabel('chemical_1')
plt.ylabel('chemical_2')
plt.show

UPD:我尝试使用 PCA 进行转换。这是正确的方法吗?另外,我只能用 matplotlib 绘制数据。在这里使用 seaborn 的正确方法是什么?

pca = PCA(n_components=2, whiten=True).fit(df_tr_std)

#Cluster the data
kmeans = KMeans(n_clusters=4)
kmeans.fit(df_tr_std)
labels = kmeans.labels_
centers = pca.transform(kmeans.cluster_centers_)

plt.scatter(df_tr_std[:,0], df_tr_std[:,1])
plt.scatter(centers[:,0], centers[:,1], marker="x", color='r')

现在散点图如下所示:

【问题讨论】:

#Make a copy of DF 下面的行与复制正好相反。您应该明确使用copy 此外,您似乎拥有多维数据,但您只绘制了前两列。这是完全不正确的。在绘制它们之前,您需要先在 2D 空间中找到它们的投影。 @cᴏʟᴅsᴘᴇᴇᴅ 我可能必须在执行df_tr_std = stats.zscore(df_transformed[columns]) 之后转换回来,以便在正确的坐标中绘制质心。但我被困在这一步 那么,让我确定我已经理解了……您已经使用了“季节”标签并将其与您的功能混为一谈?你为什么要这么做? 另外,您的数据来自哪里? 【参考方案1】:

如果您对 z 分数进行聚类,则生成的中心也将是 z 分数。

Kmeans 显然无法将它们映射回您的旧坐标系 - 您必须自己执行此操作。

由于 z 分数变换是一个简单的线性变换,因此可以直接重新创建此函数逆变换。

【讨论】:

我已经阅读了关于 z 分数的 scipy 文档,并研究了如何将 z 分数映射回旧坐标系。但仍然没有找到相关的解决方案,现在只是坚持这个问题。我在 python 和统计方面还没有太多经验,此时需要帮助。您能否在代码中展示一个如何在我的情况下执行转换的示例? 变换只是 (x-mu)/sigma。逆很简单。 我觉得我不够聪明,抱歉。这对我来说不是微不足道的。我不知道我应该在哪里应用什么转换。在研究了这个问题后,我想出了以下解决方案并相应地更新了我的帖子:centers = pca.transform(kmeans.cluster_centers_)。但不确定是否正确。 不,PCA 不是 zscore 的倒数。 你真的需要做数学。 x_zscore=(x-mu)/sigma 的倒数显然是 x=x_zscore*sigma+mu...是的,非常非常基础的微积分...

以上是关于Python k-mean,质心放置在集群之外的主要内容,如果未能解决你的问题,请参考以下文章

scikit k-means:查找属于特定质心生成集群的数据点

Mahout Java API 用于查找使用 k-means 生成的集群的质心

K-Means:将集群分配给新的数据点

如何在k-means中记录每次迭代的质心?

在 python / pyspark 中获取 k-means 质心和异常值

在python中使用k-means聚类提取质心?