如何使用 Python 从最高到最低设置 k-Means 聚类标签?
How to set k-Means clustering labels from highest to lowest with Python?
我有一个数据集,包含 38 间公寓及其早上、下午和晚上的用电量。我正在尝试使用 scikit-learn 中的 k-Means 实现对该数据集进行聚类,并且得到了一些有趣的结果。
第一个聚类结果:
一切都很好,对于 4 个集群,我显然得到了与每个公寓关联的 4 个标签 - 0、1、2 和 3。使用 KMeans
方法的 random_state
参数,我可以修复质心随机初始化的种子,所以我始终得到相同公寓的相同标签。
但是,由于此特定案例涉及能源消耗,因此可以在最高和最低消费者之间执行可测量的分类。因此,我想将标签 0 分配给消费水平最低的公寓,将标签 1 分配给消费多一点的公寓,依此类推。
截至目前,我的标签是 [2 1 3 0],或 ["black"、"green"、"blue"、"red"];我希望它们是 [0 1 2 3] 或 ["red"、"green"、"black"、"blue"]。我应该如何继续这样做,同时仍然保持质心初始化随机(使用固定种子)?
非常感谢您的帮助!
通过 查找 table 转换标签是实现您想要的目标的直接方法。
首先我生成一些模拟数据:
import numpy as np
np.random.seed(1000)
n = 38
X_morning = np.random.uniform(low=.02, high=.18, size=38)
X_afternoon = np.random.uniform(low=.05, high=.20, size=38)
X_night = np.random.uniform(low=.025, high=.175, size=38)
X = np.vstack([X_morning, X_afternoon, X_night]).T
然后我对数据进行聚类:
from sklearn.cluster import KMeans
k = 4
kmeans = KMeans(n_clusters=k, random_state=0).fit(X)
最后,我使用 NumPy 的 argsort
创建一个查找 table,如下所示:
idx = np.argsort(kmeans.cluster_centers_.sum(axis=1))
lut = np.zeros_like(idx)
lut[idx] = np.arange(k)
样本运行:
In [70]: kmeans.cluster_centers_.sum(axis=1)
Out[70]: array([ 0.3214523 , 0.40877735, 0.26911353, 0.25234873])
In [71]: idx
Out[71]: array([3, 2, 0, 1], dtype=int64)
In [72]: lut
Out[72]: array([2, 3, 1, 0], dtype=int64)
In [73]: kmeans.labels_
Out[73]: array([1, 3, 1, ..., 0, 1, 0])
In [74]: lut[kmeans.labels_]
Out[74]: array([3, 0, 3, ..., 2, 3, 2], dtype=int64)
idx
显示聚类中心标签从最低到最高消费水平排序。 lut[kmeans.labels_]
为0
/3
的公寓属于消费水平最低/最高的集群。
也许根据质心的 向量大小 对质心进行排序更好,因为您可以使用它来预测使用同一模型的其他数据。这是我在 my repo
中的实现
from sklearn.cluster import KMeans
def sorted_cluster(x, model=None):
if model == None:
model = KMeans()
model = sorted_cluster_centers_(model, x)
model = sorted_labels_(model, x)
return model
def sorted_cluster_centers_(model, x):
model.fit(x)
new_centroids = []
magnitude = []
for center in model.cluster_centers_:
magnitude.append(np.sqrt(center.dot(center)))
idx_argsort = np.argsort(magnitude)
model.cluster_centers_ = model.cluster_centers_[idx_argsort]
return model
def sorted_labels_(sorted_model, x):
sorted_model.labels_ = sorted_model.predict(x)
return sorted_model
示例:
import numpy as np
arr = np.vstack([
100 + np.random.random((2,3)),
np.random.random((2,3)),
5 + np.random.random((3,3)),
10 + np.random.random((2,3))
])
print('Data:')
print(arr)
cluster = KMeans(n_clusters=4)
print('\n Without sort:')
cluster.fit(arr)
print(cluster.cluster_centers_)
print(cluster.labels_)
print(cluster.predict([[5,5,5],[1,1,1]]))
print('\n With sort:')
cluster = sorted_cluster(arr, cluster)
print(cluster.cluster_centers_)
print(cluster.labels_)
print(cluster.predict([[5,5,5],[1,1,1]]))
输出:
Data:
[[100.52656263 100.57376566 100.63087757]
[100.70144046 100.94095196 100.57095386]
[ 0.21284187 0.75623797 0.77349013]
[ 0.28241023 0.89878796 0.27965047]
[ 5.14328748 5.37025887 5.26064209]
[ 5.21030632 5.09597417 5.29507699]
[ 5.81531591 5.11629056 5.78542656]
[ 10.25686526 10.64181304 10.45651994]
[ 10.14153211 10.28765705 10.20653228]]
Without sort:
[[ 10.19919868 10.46473505 10.33152611]
[100.61400155 100.75735881 100.60091572]
[ 0.24762605 0.82751296 0.5265703 ]
[ 5.38963657 5.19417453 5.44704855]]
[1 1 2 2 3 3 3 0 0]
[3 2]
With sort:
[[ 0.24762605 0.82751296 0.5265703 ]
[ 5.38963657 5.19417453 5.44704855]
[ 10.19919868 10.46473505 10.33152611]
[100.61400155 100.75735881 100.60091572]]
[3 3 0 0 1 1 1 2 2]
[1 0]
我有一个数据集,包含 38 间公寓及其早上、下午和晚上的用电量。我正在尝试使用 scikit-learn 中的 k-Means 实现对该数据集进行聚类,并且得到了一些有趣的结果。
第一个聚类结果:
一切都很好,对于 4 个集群,我显然得到了与每个公寓关联的 4 个标签 - 0、1、2 和 3。使用 KMeans
方法的 random_state
参数,我可以修复质心随机初始化的种子,所以我始终得到相同公寓的相同标签。
但是,由于此特定案例涉及能源消耗,因此可以在最高和最低消费者之间执行可测量的分类。因此,我想将标签 0 分配给消费水平最低的公寓,将标签 1 分配给消费多一点的公寓,依此类推。
截至目前,我的标签是 [2 1 3 0],或 ["black"、"green"、"blue"、"red"];我希望它们是 [0 1 2 3] 或 ["red"、"green"、"black"、"blue"]。我应该如何继续这样做,同时仍然保持质心初始化随机(使用固定种子)?
非常感谢您的帮助!
通过 查找 table 转换标签是实现您想要的目标的直接方法。
首先我生成一些模拟数据:
import numpy as np
np.random.seed(1000)
n = 38
X_morning = np.random.uniform(low=.02, high=.18, size=38)
X_afternoon = np.random.uniform(low=.05, high=.20, size=38)
X_night = np.random.uniform(low=.025, high=.175, size=38)
X = np.vstack([X_morning, X_afternoon, X_night]).T
然后我对数据进行聚类:
from sklearn.cluster import KMeans
k = 4
kmeans = KMeans(n_clusters=k, random_state=0).fit(X)
最后,我使用 NumPy 的 argsort
创建一个查找 table,如下所示:
idx = np.argsort(kmeans.cluster_centers_.sum(axis=1))
lut = np.zeros_like(idx)
lut[idx] = np.arange(k)
样本运行:
In [70]: kmeans.cluster_centers_.sum(axis=1)
Out[70]: array([ 0.3214523 , 0.40877735, 0.26911353, 0.25234873])
In [71]: idx
Out[71]: array([3, 2, 0, 1], dtype=int64)
In [72]: lut
Out[72]: array([2, 3, 1, 0], dtype=int64)
In [73]: kmeans.labels_
Out[73]: array([1, 3, 1, ..., 0, 1, 0])
In [74]: lut[kmeans.labels_]
Out[74]: array([3, 0, 3, ..., 2, 3, 2], dtype=int64)
idx
显示聚类中心标签从最低到最高消费水平排序。 lut[kmeans.labels_]
为0
/3
的公寓属于消费水平最低/最高的集群。
也许根据质心的 向量大小 对质心进行排序更好,因为您可以使用它来预测使用同一模型的其他数据。这是我在 my repo
中的实现from sklearn.cluster import KMeans
def sorted_cluster(x, model=None):
if model == None:
model = KMeans()
model = sorted_cluster_centers_(model, x)
model = sorted_labels_(model, x)
return model
def sorted_cluster_centers_(model, x):
model.fit(x)
new_centroids = []
magnitude = []
for center in model.cluster_centers_:
magnitude.append(np.sqrt(center.dot(center)))
idx_argsort = np.argsort(magnitude)
model.cluster_centers_ = model.cluster_centers_[idx_argsort]
return model
def sorted_labels_(sorted_model, x):
sorted_model.labels_ = sorted_model.predict(x)
return sorted_model
示例:
import numpy as np
arr = np.vstack([
100 + np.random.random((2,3)),
np.random.random((2,3)),
5 + np.random.random((3,3)),
10 + np.random.random((2,3))
])
print('Data:')
print(arr)
cluster = KMeans(n_clusters=4)
print('\n Without sort:')
cluster.fit(arr)
print(cluster.cluster_centers_)
print(cluster.labels_)
print(cluster.predict([[5,5,5],[1,1,1]]))
print('\n With sort:')
cluster = sorted_cluster(arr, cluster)
print(cluster.cluster_centers_)
print(cluster.labels_)
print(cluster.predict([[5,5,5],[1,1,1]]))
输出:
Data:
[[100.52656263 100.57376566 100.63087757]
[100.70144046 100.94095196 100.57095386]
[ 0.21284187 0.75623797 0.77349013]
[ 0.28241023 0.89878796 0.27965047]
[ 5.14328748 5.37025887 5.26064209]
[ 5.21030632 5.09597417 5.29507699]
[ 5.81531591 5.11629056 5.78542656]
[ 10.25686526 10.64181304 10.45651994]
[ 10.14153211 10.28765705 10.20653228]]
Without sort:
[[ 10.19919868 10.46473505 10.33152611]
[100.61400155 100.75735881 100.60091572]
[ 0.24762605 0.82751296 0.5265703 ]
[ 5.38963657 5.19417453 5.44704855]]
[1 1 2 2 3 3 3 0 0]
[3 2]
With sort:
[[ 0.24762605 0.82751296 0.5265703 ]
[ 5.38963657 5.19417453 5.44704855]
[ 10.19919868 10.46473505 10.33152611]
[100.61400155 100.75735881 100.60091572]]
[3 3 0 0 1 1 1 2 2]
[1 0]