一尘不染

如何实现K-Means ++算法?

algorithm

我无法完全了解K-Means++算法。我很感兴趣第一个k质心的选取方式,即初始化,其余的就像原始的K-Means算法一样

  1. 使用的概率函数是基于距离还是高斯?
  2. 同时,为新质心选取了最远的距离点(与其他质心相对)。

我将逐步解释并举例说明。维基百科中的那个还不够清楚。一个注释非常好的源代码也将有所帮助。如果您使用的是6个数组,请告诉我们哪个数组适合什么。


阅读 337

收藏
2020-07-28

共1个答案

一尘不染

有趣的问题。感谢您使本文引起我的注意-K-Means++:谨慎播种的优势

简而言之,聚类中心最初是从一组输入观察向量中随机选择的,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
2020-07-28