【问题标题】:KMeans clustering won't work on a dataframe with more than 4 columnsKMeans 聚类不适用于超过 4 列的数据框
【发布时间】:2021-03-15 22:30:20
【问题描述】:

我在这里问了一个类似的问题:How to apply KMeans to get the centroid using dataframe with multiple features,我收到了一些有价值的回复。但是,我没有成功地让 KMeans 聚类在超过 4 列的数据帧上工作。

有问题的数据框有 5 列,如下所示:

col1,col2,col3,col4,col5
0.54,0.68,0.46,0.98,0.15
0.52,0.44,0.19,0.29,0.44
1.27,1.15,1.32,0.60,0.14
0.88,0.79,0.63,0.58,0.18
1.39,1.15,1.32,0.41,0.44
0.86,0.80,0.65,0.65,0.11
1.68,1.99,3.97,0.16,0.55
0.78,0.63,0.40,0.36,0.10
2.95,2.66,7.11,0.18,0.15
1.44,1.33,1.79,0.24,0.22

我有一个简单的 KMeans 聚类 python 代码,我尝试将其应用于 5 列数据框,如下所示。

from numpy import unique
from numpy import where
from sklearn.cluster import KMeans
from matplotlib import pyplot
import pandas as pd
import numpy as np

df = pd.read_csv('data.csv')

X = np.array(df)

model = KMeans(n_clusters=5)
model.fit(X)
yhat = model.predict(X)
clusters = unique(yhat)
for cluster in clusters:
    row_ix = where(yhat == cluster)
    pyplot.scatter(X[row_ix, 0], X[row_ix, 1], X[row_ix, 2], X[row_ix, 3], X[row_ix, 4])
pyplot.show()

当我运行代码时,它会抱怨 pyplot.scatter(X[row_ix, 0], X[row_ix, 1], X[row_ix, 2], X[row_ix, 3], X[row_ix, 4]) 行,并显示错误消息“ValueError: Unrecognized marker style [[0.14 0.44 0.22]]' .但是,如果我从数据框中删除第 5 列(即 col5)并从代码中删除 X[row_ix, 4],则聚类工作。

我需要做什么才能让 KMeans 处理我的示例数据框?

[更新:一次 2 或 3 个维度]

在上一篇文章中,有人建议我可以使用以下函数一次表示 2 或 3 个维度来拆分任务。但是,该函数不会产生预期的聚类输出(见附件 output.png)

def plot(self):
    

    import itertools
    combinations = itertools.combinations(range(self.K), 2) # generate all combinations of features
    
    fig, axes = plt.subplots(figsize=(12, 8), nrows=len(combinations), ncols=1) # initialise one subplot for each feature combination

    for (x,y), ax in zip(combinations, axes.ravel()): # loop through combinations and subpltos
        
        
        for i, index in enumerate(self.clusters):
            point = self.X[index].T
            
            # only get the coordinates for this combination:
            px, py = point[x], point[y]
            ax.scatter(px, py)

        for point in self.centroids:
            
            # only get the coordinates for this combination:
            px, py = point[x], point[y]
            
            ax.scatter(px, py, marker="x", color='black', linewidth=2)

        ax.set_title('feature {} vs feature {}'.format(x,y))
    plt.show()

如何修复上述函数以获取聚类输出。

【问题讨论】:

  • 这是 matplotlib 的问题,而不是集群的问题。您正在将一个 numpy 数组传递给 scatter() 在您应该传递标记样式的地方。
  • 你想用上面的代码实现什么?
  • 散点图只接受 plot 2d 但在您的代码中,您提供了错误的格式数据。

标签: python pandas numpy dataframe k-means


【解决方案1】:

正如其他答案和 cmets 中所述,您不能将所有 5 轴绘制在一起。一种方法是使用降维(例如 PCA)将其降为二维并绘图:

import numpy as np
from sklearn.cluster import KMeans
from matplotlib import pyplot
import pandas as pd
from sklearn.decomposition import PCA

df = pd.read_csv('test.csv')

model = KMeans(n_clusters=5)
model.fit(df)
yhat = model.predict(df)
clusters = np.unique(yhat)

dims = PCA(n_components=2).fit_transform(X)
dims = pd.DataFrame(dims,columns=['PC1','PC2'])

fig,ax = plt.subplots(1,1) 
for cluster in clusters:
    ix = yhat == cluster
    ax.scatter(x=dims.loc[ix,'PC1'],y=dims.loc[ix,'PC2'],label=cluster)
ax.legend()

或者您确实使用 seaborn 并可视化所有变量,如果您只有 5 个变量,则可以:

import seaborn as sns
df['cluster'] = yhat
sns.pairplot(data=df,hue='cluster',diag_kind=None)

【讨论】:

    【解决方案2】:

    您的 KMeans 有效,但您希望显示结果的方式不正确。 如果您查看 matplotlib scatter 函数 (https://matplotlib.org/3.3.3/api/_as_gen/matplotlib.pyplot.scatter.html) 的文档,您会发现该函数的前四个参数可以接受类似数组的参数,而第五个参数只接受“MarkerStyle”。这就是为什么只有在添加第五个参数时才会出错。 实际上,您正在尝试在 2 维平面中绘制 5 维数据集,如果不事先进行降维,这是不可能的。 PCA 或 PLSDA 可能是降低数据集维度的好选择。

    【讨论】:

    • 谢谢我已经更新了这个问题,并包含了以前一次考虑 2 个维度的建议。但是,我很难让它产生预期的聚类。关于如何改进建议的功能以使其正常工作的任何想法?
    • 我尽量避免使用 PCA,因为我知道它会导致信息丢失
    • 当你不得不降维时,你无法避免信息丢失。
    猜你喜欢
    • 2018-02-05
    • 2021-08-02
    • 2019-02-14
    • 1970-01-01
    • 2018-04-26
    • 2014-02-02
    • 2013-03-24
    • 2021-10-09
    • 2019-01-23
    相关资源
    最近更新 更多