我可以仅对多个 dtype 的 DataFrame 中的数字数据使用 K-Means 吗?

Posted

技术标签:

【中文标题】我可以仅对多个 dtype 的 DataFrame 中的数字数据使用 K-Means 吗?【英文标题】:Can I use K-Means on only the numerical data in a DataFrame of multiple dtypes? 【发布时间】:2020-01-13 12:40:23 【问题描述】:

我正在做一个分析电子商务网站页面访问量的项目。它监控数值、离散数值(连续数字,但仅限整数)和分类变量。

我的理解是,由于 KMeans 采用均值和对数字/距离进行计算的性质,它不适用于分类变量。我也认为它不适用于数值离散值,因为当这些离散值不应该有分数时,它会使用小数来解释它们。

这是我如何运行 sklearn 的 KMeans 的代码,使用轮廓分数测量 k 个集群并使用得分最高的 k 个集群。我创建了一个名为 cluster_df 的数据框,仅包含原始数据框中的数字特征,然后为每个集群分离数据框:

from sklearn.preprocessing import StandardScaler
scaler = StandardScaler()
cluster_df[cluster_attribs] = scaler.fit_transform(cluster_df[cluster_attribs])

k_rng = range(2,10)
silhouette = []
for k in k_rng:
    kmeans = KMeans(n_clusters=k)
    kmeans.fit(cluster_df[cluster_attribs])
    silhouette.append(silhouette_score(cluster_df[cluster_attribs], kmeans.labels_))

kmeans = KMeans(n_clusters=3)
y_pred = kmeans.fit_predict(cluster_df[cluster_attribs])
cluster_df['cluster'] = y_pred
# inverse StandardScaler to return values to normal
cluster_df[cluster_attribs] = scaler.inverse_transform(cluster_df[cluster_attribs])

cluster0 = cluster_df[cluster_df.cluster==0]
cluster1 = cluster_df[cluster_df.cluster==1]
cluster2 = cluster_df[cluster_df.cluster==2]

然后我根据这 3 个集群执行数据可视化/分析。对数据进行聚类似乎工作得很好,即使在查看分类数据时,即使它们没有包含在实际的聚类中,它似乎也与头脑中的那些数据进行了聚类。

例如,Revenue 是我没有包含在 KMeans 中的二进制列。但我的 3 个集群似乎仅通过在数值变量上运行就将我的客户很好地分为低收入、中等收入和高收入。

我的问题是:

1) KMeans 是否只适用于数值数据,而不适用于离散数值或分类数据? (我已经读过有一些方法可以将分类变量转换为数值,但由于其对这个项目的性质,它看起来很复杂且不可靠。我知道 OneHotEncoder/LabelEncoder/MultiLabelBinarizer,但我的意思是转换它们时保持类别之间的距离记住哪个更复杂)。

2) 仅对您的数值数据运行 KMeans,将其分成集群,然后通过查看所有变量(数值、离散数值、分类)的数据集群如何获得洞察,这是一种可接受的策略吗?分开了吗?

【问题讨论】:

可能值得一提:如果您的特征子集可以可靠地预测您的其他一些特征的值,您可能需要研究特征消除或降维技术 是的,它确实以一种可以理解的方式对我的数据进行聚类,但我无法知道如果我使用更多功能,它是否会“更好”地聚类。因此,这些功能可能就是我所需要的,或者可能是我错过了更好的集群。没有办法真正知道我是否不能同时运行它并进行比较。 【参考方案1】:

1)

我通常将它们转换为使用 oneHot,然后我将 n 的值除为该类别中唯一的数量,通常这工作正常。在这种情况下,您将有更多 n-1 列用于您已经拥有的每个分类列 如果您有序数值,请使用 LabelEncoder,然后按照我之前解释的方式划分它们。在这种情况下,您将保持相同的列数

2)

如果您的数据集在没有分类数据的情况下运行良好,为什么不呢?但我建议您测试更多可能性

【讨论】:

太棒了,我会试试这个。给你几个问题:1)在 OneHotEncoder 之后(使用 drop='first' 表示虚拟变量陷阱),你怎么知道哪些列是哪个类别并将它们全部划分? 2)你是否除以n个类别或n-1,因为我们为每个类别删除了虚拟变量? (或者为此不需要删除)3)有没有一种简单的方法可以从 OneHotEncoder 和 LabelEncoder 转换回来以分析原始形式的数据? 如果你使用的是pandas get_dummies,原来的变量会在名字上,只需要过滤。您除以 n 是该变量上的类别数。例如,如果您在变量中包含美国的州并且您对它们进行编码,您会将每个新变量除以 50。您需要删除原始变量。在 Sklearn 中,您有函数 inverse_transform。如果您使用的是 get_dummies,我认为您可以使用 ***.com/questions/50607740/… 你也可以尝试使用Kmodes,对于分类的,它会通过模式,真的很好github.com/nicodv/kmodes 还可以查看 k-prototypes,它是 kmodes 和 kmeans 的组合。如果已经有你的答案,请市场回答 plz:p

以上是关于我可以仅对多个 dtype 的 DataFrame 中的数字数据使用 K-Means 吗?的主要内容,如果未能解决你的问题,请参考以下文章

分配 pandas 数据框列 dtypes

DataFrame的分配无法正常工作,但dtypes已更改

Concat DataFrame Reindexing 仅对具有唯一值的 Index 对象有效

如何在 DataFrame 对象 dtype 中正确识别包含点的浮点值 [0, 1]?

基于原始列的 dtype 是对象,在数据框中创建多个虚拟变量的最佳方法是啥?

pandas使用select_dtypes函数筛选dataframe中的所有数值数据列(all numeric columns of a dataframe)