我编写了一个函数,它以data
、K
和n
(迭代次数)作为输入执行k均值集群。我可以设置n=100
,以便函数计算欧几里得距离,分配集群和计算新的集群质心100倍,然后才能完成。当将此结果与sklearn的KMeans (使用相同的data
和K
)进行比较时,我得到了相同的质心。
我希望我的函数只运行到收敛(以避免不必要的迭代),因此它不再需要迭代次数作为输入。为了实现这一点,我使用了一个while循环,而在我最初的函数中,我使用了迭代n
次数的for循环。我的代码的一般步骤如下:
centroids
.
centroids
.
centroids
.
EucDist
的数据点存储在变量中,存储基于聚类索引cluster
的数据点。然后计算分离簇的均值,并将其赋值为新的centroids
.。然后,步骤2-4被循环,直到收敛。下面是我的while循环的代码(我知道这里可能有一些不必要的代码,但是我不知道这个问题是从哪里产生的,甚至是一个问题)。
while True:
previouscentroids = centroids
EucDist = np.array([]).reshape(a, 0)
for k in range(K):
Dist = np.sqrt(np.sum((data - centroids[:, k]) ** 2, axis = 1))
EucDist = np.c_[EucDist, Dist]
cluster = np.argmin(EucDist, axis = 1) + 1
points = {}
for k in range(K):
points[k + 1] = np.array([]).reshape(2, 0)
for i in range(a):
points[cluster[i]] = np.c_[points[cluster[i]], data[i]]
for k in range(K):
points[k + 1] = points[k + 1].T
for k in range(K):
centroids[:, k] = np.mean(points[k + 1], axis = 0)
if np.all(previouscentroids - centroids == 0):
break
我对此的理解是,一旦centroids
与迭代(previouscentroids
)开始时的情况相同,循环就会中断,我将得到最后的集群。我假设这将与我的原始函数产生的质心相同(与sklearn一样),因为我认为一旦达到收敛,无论您迭代循环多少次,集群都将保持不变(质心也是如此)。下面是用于比较的原始函数的for循环(更改很少)。
for i in range(n):
EucDist = np.array([]).reshape(a, 0)
for k in range(K):
Dist = np.sqrt(np.sum((data - centroids[:, k]) ** 2, axis = 1))
EucDist = np.c_[EucDist, Dist]
cluster = np.argmin(EucDist, axis = 1) + 1
points = {}
for k in range(K):
points[k + 1] = np.array([]).reshape(2, 0)
for i in range(a):
points[cluster[i]] = np.c_[points[cluster[i]], data[i]]
for k in range(K):
points[k + 1] = points[k + 1].T
for k in range(K):
centroids[:, k] = np.mean(points[k + 1], axis = 0)
发布于 2021-12-10 05:13:02
K-均值是一种非确定性算法.如果您没有相同的初始化与在scikit中学习,您并不一定会找到相同的集群。在scikit-学习文档中,它被写成:
如果
有足够的时间,K-均值总是收敛的,但是这可能是一个局部的最小值。这在很大程度上取决于质心的初始化。因此,计算常常要多次进行,对质心进行不同的初始化。
。
发布于 2021-12-10 05:17:29
每次运行时,chosen都会发生变化,因为初始的集群成员将被随机选择。所以,除非你有同样的初始俱乐部,否则结果就不会一样。
https://stackoverflow.com/questions/70302684
复制