k均值|| 又名可扩展K均值++


12

Bahman Bahmani等。引入了k-means ||,这是k-means ++的更快版本。

k均值的初始化||

此算法取自其论文的第4页,Bahmani,B.,Moseley,B.,Vattani,A.,Kumar,R.,&Vassilvitskii,S.(2012)。可扩展的k-均值++。VLDB基金会论文集,5(7),622-633。

不幸的是,我不理解那些花哨的希腊字母,因此我需要一些帮助以了解其工作原理。据我了解,该算法是k-means ++的改进版本,它使用过采样来减少迭代次数:k-means ++必须迭代次,其中k是所需簇的数量。kk

通过一个有关k-means ++如何工作的具体示例,我得到了很好的解释,因此我将再次使用相同的示例。

我有以下数据集:

(7,1),(3,4),(1,5),(5,8),(1,3),(7,8),(8,2),(5,9),(8 ,0)

(所需簇数)k=3

(过采样因子)=2

k均值||的示例数据集

我开始进行计算,但是不确定是否正确,也不知道第2步,第4步或第5步。

  • 步骤1:X随机地均匀采样一个点CX

    比方说,所述第一质心是(同k均值++)(8,0)

  • 步骤2:ψϕX(C)

    不知道

  • 第三步:

    • d2(x,C)=[2,41,74,73,58,65,4,90]

      我们计算到每个点最近的中心的平方距离。在这种情况下,我们只有一个中心,到目前为止,(8,0)

    • d2(x,C)=[4,81,148,146,116,130,8,180]

      (因为在这种情况下。)=2

    • cumulative d2(x,C)=[4,85,233,379,495,625,633,813]

      =2[0,813)246.90659.42[379,495)[633,813)

    • O(logψ)ψ

  • xCwxXxC
  • Ck

总体上或在此特定示例中的任何帮助都将非常有用。

Answers:


10

数据点:(7,1),(3,4),(1,5),(5,8),(1,3),(7,8),(8,2),(5,9) ,(8,0)

l = 2 //过采样系数

k = 3 //不。所需集群

步骤1:

C{c1}={(8,0)}X={x1,x2,x3,x4,x5,x6,x7,x8}={(7,1),(3,4),(1,5),(5,8),(1,3),(7,8),(8,2),(5,9)}

第2步:

ϕX(C)XCXCX

dC2(xi)xiCψ=i=1ndC2(xi)

CXdC2(xi)Cxiϕ=i=1n||xic||2

ψ=i=1nd2(xi,c1)=1.41+6.4+8.6+8.54+7.61+8.06+2+9.4=52.128 log(ψ)=log(52.128)=3.95=4(rounded)

C

第三步:

log(ψ)

XXxipx=ld2(x,C)/ϕX(C)ld2(x,C)ϕX(C) 在步骤2中进行了说明。

该算法很简单:

  • Xxi
  • xipxi
  • [0,1]pxiC
  • CC

lX

for(int i=0; i<4; i++) {

  // compute d2 for each x_i
  int[] psi = new int[X.size()];
  for(int i=0; i<X.size(); i++) {
    double min = Double.POSITIVE_INFINITY;
    for(int j=0; j<C.size(); j++) {
      if(min>d2(x[i],c[j])) min = norm2(x[i],c[j]);
    }
    psi[i]=min;
  }

  // compute psi
  double phi_c = 0;
  for(int i=0; i<X.size(); i++) phi_c += psi[i];

  // do the drawings
  for(int i=0; i<X.size(); i++) {
    double p_x = l*psi[i]/phi;
    if(p_x >= Random.nextDouble()) {
      C.add(x[i]);
      X.remove(x[i]);
    }
  }
}
// in the end we have C with all centroid candidates
return C;

步骤4:

wC0XxiXjCw[j]1w

double[] w = new double[C.size()]; // by default all are zero
for(int i=0; i<X.size(); i++) {
  double min = norm2(X[i], C[0]);
  double index = 0;
  for(int j=1; j<C.size(); j++) {
    if(min>norm2(X[i],C[j])) {
      min = norm2(X[i],C[j]);
      index = j;
    }
  }
  // we found the minimum index, so we increment corresp. weight
  w[index]++;
}

步骤5:

wkkp(i)=w(i)/j=1mwj

for(int k=0; k<K; k++) {
  // select one centroid from candidates, randomly, 
  // weighted by w
  // see kmeans++ and you first idea (which is wrong for step 3)
  ... 
}  

像kmeans ++一样,前面的所有步骤都继续使用聚类算法的正常流程

我希望现在更加清楚。

[稍后,稍后编辑]

我还发现了作者所做的一个演示,在该演示中,您不能清楚地知道每次迭代都可能选择多个点。演示在这里

[稍后编辑@pera的问题]

log(ψ)

Clog(ψ)

要注意的另一件事是同一页面上的以下注意事项:

在实践中,我们在第5节中的实验结果表明,仅几轮就足以达成一个好的解决方案。

log(ψ)


您能否以我的示例计算来扩展您的答案?
user1930254'2

我是一名程序员,我想我可以用比在这里键入:)更快的代码编写代码。希望它能解释算法。
rapaio 2015年

您能否解释一下log(Ksi)迭代次数的想法?我不理解其内在的想法,似乎迭代次数将取决于对象的值范围,这似乎并不合理。例如,如果对象的属性值约为1000,则可能会导致错误(例如)约为1000,这意味着将进行3次迭代。另一方面,如果值在10的范围内,则可能导致误差约为10,从而导致1次迭代。迭代次数不应该取决于对象数吗?
Marko 2015年

@pera我更新了答案以澄清您提出的问题
rapaio 2015年

@rapaio感谢您的回答,我已经在寻找一种解决方案,该解决方案将根据类固醇的数量来确定迭代次数。可以增加x以获得更好的初始化,但要花更多的迭代时间。根据您给出的第二部分,您还可以吗?再次感谢。
Marko'Apr
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.