有没有更好的方法来为 Python 中的集群分配数组生成成员矩阵(单热数组)? [复制]

Posted

技术标签:

【中文标题】有没有更好的方法来为 Python 中的集群分配数组生成成员矩阵(单热数组)? [复制]【英文标题】:Is there a better way to produce a membership matrix (one-hot array) for an array of cluster assignments in Python? [duplicate] 【发布时间】:2017-12-09 16:32:11 【问题描述】:

运行 kmeans 后,我可以轻松地获得一个数组,其中包含为每个数据点分配的集群。现在我想获得一个成员矩阵(单热数组),它具有不同的集群作为列,并在矩阵中为每个数据点指示集群分配 1 或 0。

我的代码如下所示,它可以工作,但我想知道是否有更优雅的方式来做同样的事情。

km = KMeans(n_clusters=3).fit(data)
membership_matrix = np.stack([np.where(km.labels_ == 0, 1,0),
                              np.where(km.labels_ == 1, 1,0),
                              np.where(km.labels_ == 2, 1,0)]
                              axis = 1)

【问题讨论】:

【参考方案1】:

因此,您可以根据this question 从集群数组创建与您的成员资格数组等效的“one-hot 数组”。这是使用np.eye的方法

import numpy as np

clusters = np.array([2,1,2,2,0,1])
n_clusters = max(clusters) + 1
membership_matrix = np.eye(n_clusters)[clusters]

输出如下

array([[ 0.,  0.,  1.],
       [ 0.,  1.,  0.],
       [ 0.,  0.,  1.],
       [ 0.,  0.,  1.],
       [ 1.,  0.,  0.],
       [ 0.,  1.,  0.]])

【讨论】:

不要只是从明显的副本中复制答案。举报! 啊,好吧,对不起。【参考方案2】:

这是一种与您拥有的集群数量无关的方法(使用您的方法,如果您有更多集群,您将不得不“堆叠”更多东西)。

此代码示例假设您有 6 个数据点和 3 个集群:

NUM_DATA_POINTS = 6
NUM_CLUSTERS = 3
clusters = np.array([2,1,2,2,0,1]) # hard-coded as an example, but this is your KMeans output

# create your empty membership matrix
membership = np.zeros((NUM_DATA_POINTS, NUM_CLUSTERS)) 
membership[np.arange(NUM_DATA_POINTS), clusters] = 1

这里使用的关键特性是 2D 数组索引 - 在上面的最后一行代码中,我们按顺序索引成员行(np.arange 创建从 0 到 NUM_DATA_POINTS-1 的递增序列)和列使用集群分配的成员资格。这是relevant numpy reference。

它将产生以下成员矩阵:

>>> membership
array([[ 0.,  0.,  1.],
       [ 0.,  1.,  0.],
       [ 0.,  0.,  1.],
       [ 0.,  0.,  1.],
       [ 1.,  0.,  0.],
       [ 0.,  1.,  0.]])   

【讨论】:

【参考方案3】:

您正在寻找LabelBinarizer。试试这个代码:

from sklearn import preprocessing
lb = preprocessing.LabelBinarizer()
membership_matrix = lb.fit_transform(km.labels_)

与这里提出的其他解决方案相比,这种方法:

当标签不是连续数字时生成紧凑的隶属度矩阵。 能够处理分类标签

示例运行:

In [9]: lb.fit_transform([0, 1, 2, 0, 2, 2])
Out[9]: 
array([[1, 0, 0],
       [0, 1, 0],
       [0, 0, 1],
       [1, 0, 0],
       [0, 0, 1],
       [0, 0, 1]])

In [10]: lb.fit_transform([0, 1, 9, 0, 9, 9])
Out[10]: 
array([[1, 0, 0],
       [0, 1, 0],
       [0, 0, 1],
       [1, 0, 0],
       [0, 0, 1],
       [0, 0, 1]])

In [11]: lb.fit_transform(['first', 'second', 'third', 'first', 'third', 'third'])
Out[11]: 
array([[1, 0, 0],
       [0, 1, 0],
       [0, 0, 1],
       [1, 0, 0],
       [0, 0, 1],
       [0, 0, 1]])

【讨论】:

以上是关于有没有更好的方法来为 Python 中的集群分配数组生成成员矩阵(单热数组)? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

有没有一种更简单的方法来为给定 if 条件的变量分配值 - Python?

有没有比 redux persist 更好的方法来为生产环境持久化 redux 状态数据

Python中的光谱聚类和多维缩放

为python中的集群图分配唯一的颜色

如何从 Python 中的 scipy 中的链接/距离矩阵计算集群分配?

这样做的更好方法? C#中的列表索引分配