代码改变世界

fuzzy c-means

2013-03-06 16:21  ggzwtj  阅读(4328)  评论(0编辑  收藏  举报

  在k-means中,每个元素只能属于所有类别中的一类。那这样会带来一些问题:

  • 所有的元素对于计算聚类中心的贡献都是相同的。

  因为从根本上,对于属于一个类的所有元素来说,在k-means中是无法将他们区别开的(如果非要用距离什么的来区分也可以,但是这部分功能不是k-mean擅长的)。而在fuzzy c-means中,元素可能属于任何一类,不同的是它们之间的可能性是不同的。数学表示如下:

Jm = ΣΣuijm × |xi - ci|2

其中:

  1. xi:元素;
  2. cj:聚类中心;
  3. uij:元素xi对于聚类中心cj的隶属度(属于这个类的可能性);
  4. m:大于1的实数,一般取值2.0;

  Jm用来评估聚类效果,Jm越大,聚类效果越差。那么聚类的过程其实就是找Jm的极小值的过程。其实从函数的角度看,Jm取得极小值时偏导数为0,也就是说uijcj的变换都接近于0,而这里其实我们只需要考虑一个(比如在uij趋于不变时通常cj也趋于稳定),而这里选择uij的原因是衡量起来简单一点(取值范围为[0,1],设置一个比较小的阀值即可)。

求极值是一个迭代的过程,更新聚类中心cj的方法与k-means非常相似,如下:

  cj = (Σuijm × xi) / Σuijm

更新隶属度uij的方法如下:

  uij = 1 / (∑((|xi - cj|/|xi - ck|)2 / (m - 1)))

那么迭代结束的条件显然是:

  max{|uijk+1 - uijk|} < ε

这样,fuzzy c-means的整体的过程如下:

  1. 初始化隶属度矩阵;
  2. 计算聚类中心C
  3. 更新隶属度矩阵U
  4. 如果max{|uijk+1 - uijk|} < ε或者迭代次数达到上限,结束迭代,否则转2;

注:不管是k-means还是fuzzy c-means,有没有感觉这个过程和迭代法求线性方程组的解的过程非常相似?其实有时候感觉这两个过程本来就是相同的。

fuzzy c-means迭代式的推导

利用拉格朗日乘子法构造新的函数:

  Jm = ΣΣuijm × |xi - ci|2 + λ × (Σuij - 1)

Jm取得极值时满足如下条件:

∂J / ∂λ = Σuij - 1 = 0

∂J / ∂uij = m × uijm-1 × |xi - cj|2 - λ = 0

∂J / ∂cj = Σuijm × xi - cj × Σuijm = 0

根据后面的两条即可得到uijcj的迭代式(想想在第二条中如何消掉λ?提示:利用∑uij = 1)。

----- -- -

end