有趣的问题。感谢您让我注意到这篇论文 - K-Means++: The Advantages of Careful Seeding
简单来说,聚类中心最初是从输入观察向量集中随机选择的,如果x 不在任何先前选择的中心附近,则选择向量x 的概率很高。
这是一个一维的例子。我们的观察结果是 [0, 1, 2, 3, 4]。令第一个中心c1 为0。下一个聚类中心c2 为x 的概率与||c1-x||^2 成正比。因此,P(c2 = 1) = 1a,P(c2 = 2) = 4a,P(c2 = 3) = 9a,P(c2 = 4) = 16a,其中 a = 1/(1+4+9+ 16).
假设 c2=4。那么,P(c3 = 1) = 1a,P(c3 = 2) = 4a,P(c3 = 3) = 1a,其中a = 1/(1+4+1)。
我已经用 Python 编写了初始化过程;不知道对你有没有帮助。
def initialize(X, K):
C = [X[0]]
for k in range(1, K):
D2 = scipy.array([min([scipy.inner(c-x,c-x) for c in C]) for x in X])
probs = D2/D2.sum()
cumprobs = probs.cumsum()
r = scipy.rand()
for j,p in enumerate(cumprobs):
if r < p:
i = j
break
C.append(X[i])
return C
编辑澄清:cumsum 的输出为我们提供了划分区间 [0,1] 的边界。这些分区的长度等于相应点被选为中心的概率。那么,由于r 是在[0,1] 之间统一选择的,它将恰好落入这些区间之一(因为break)。 for 循环检查r 在哪个分区。
例子:
probs = [0.1, 0.2, 0.3, 0.4]
cumprobs = [0.1, 0.3, 0.6, 1.0]
if r < cumprobs[0]:
# this event has probability 0.1
i = 0
elif r < cumprobs[1]:
# this event has probability 0.2
i = 1
elif r < cumprobs[2]:
# this event has probability 0.3
i = 2
elif r < cumprobs[3]:
# this event has probability 0.4
i = 3