Fuzzy C-Means Clustering(模糊C均值)
別看了 有錯的 我懶得改了
強推https://www.bilibili.com/video/BV18J411a7yY?t=591
看完你還不會那我也沒辦法了
\
算法原理
??模糊c-均值聚類算法 fuzzy c-means algorithm (FCMA)或稱(FCM)。在眾多模糊聚類算法中,模糊C-均值(FCM)算法應用最廣泛且較成功,它通過優化目標函數得到每個樣本點對所有類中心的隸屬度,從而決定樣本點的類屬以達到自動對樣本數據進行分類的目的。
??先來講講這個算法的名字噢,什么叫Fuzzy,什么叫模糊呢,在經典的集合理論,一個元素是否屬于集合,只有真或者假兩種情況,也可以說只有0和1兩種情況,0為假1為真。比如我們想要定義一個集合表示“年輕人”,那么我們需要設置一個閾值,當一個人的年齡小于這閾值的時候,就認為這個人屬于這個集合,反之則不屬于。假如用A表示年輕人這個集合,以20歲為閾值。則這個集合的隸屬度函數可以表示如下:
μA(z)={1,z<200,z≥20\mu_A(z)= \begin{cases} 1, z < 20 \\ 0, z \geq 20 \end{cases} μA?(z)={1,z<200,z≥20?
上面的公式可以用下面左圖表示:
??使用經典的集合理論,我們會面臨著一些實際的問題,比如當一個人的年齡是20歲零1秒的時候,這個人就不再是年輕人了,這種粗暴的分類方式,在實際中并不實用。因此我們需要有過渡的函數來描述這個情況。上圖中右邊的圖提供了一種解決方法,圖中的斜線表示年齡的過渡。
于是就可以定義三個隸屬度函數來確定年齡與三個模糊子集的關系:
μA(z)={1,z≤2030?z10,20<z<300,z≥30\mu_A(z)= \begin{cases} 1, z \leq 20 \\ \frac {30-z}{10}, 20< z < 30 \\ 0, z \geq 30 \end{cases} μA?(z)=??????1,z≤201030?z?,20<z<300,z≥30?
??OK,模糊的概念大概懂了,那么C-Means的C又是什么東西呢,額這個,好像沒有什么含義,就像K-Means的k一樣,只是代表聚類的個數,可能是cluster的c?又可能是模糊控制器(Fuzzy Controller)里的c。但是這個無關緊要,懂得模糊的概念就好了。
??然后我們來正式說一下模糊c-均值是什么。模糊c-均值是一種允許一個數據屬于一個或多個簇的方法,它不同于K-Means一個數據只能屬于一個簇,它自發明以來廣泛應用于模式識別中。
??那么這種算法它的優化目標、目標函數是什么呢?看下面的公式:
minJm=∑i=1N∑j=1Cμijm∣∣xi?vj∣∣2,1<m<∞s.t.∑j=1Cμij=1(1)min\ \ J_m=\sum_{i=1}^N \sum_{j=1}^C \mu_{ij}^m||x_i-v_j||^2, 1<m<\infty \tag1\\ s.t.\ \ \sum_{j=1}^C \mu_{ij}=1 min??Jm?=i=1∑N?j=1∑C?μijm?∣∣xi??vj?∣∣2,1<m<∞s.t.??j=1∑C?μij?=1(1)
符號定義:
N:N:N: 是樣本總個數
C:C:C: 簇心數目,就是一開始輸入的參數,你想這N個數據分成3份就將C置為3,5份就置為5,懂吧
μ:\mu:μ: 一個N×CN\times CN×C的矩陣,其中μij\mu_{ij}μij?是xix_ixi?屬于類別jjj的隸屬度
vj:v_j:vj?: 第jjj個類別的中心
m:m:m: 跟CCC一樣是自己設置的參數,不同的mmm會有不同的聚類效果,需要根據不同的數據集進行調節
這個公式呢就是說每一個數據xix_ixi?到每一個聚類中心vjv_jvj?距離的二范式再乘上xix_ixi?屬于類別jjj的隸屬度的mmm次方,要最小化它們的總和,直觀一點就是希望每一個數據盡可能與它們所屬的聚類中心接近。
??那么就開始求如何使這個函數最小化了,(眾所周知),求最小嘛,基本操作將它對某個變量求偏導,令偏導結果為零即可,因為有一個等式約束,我們先引入拉格朗日乘子λ\lambdaλ,于是原式可以寫成:
minJ=∑i=1N∑j=1Cμijm∣∣xi?vj∣∣2?λ(∑j=1Cμij?1)(2)min\ \ J=\sum_{i=1}^N \sum_{j=1}^C \mu_{ij}^m||x_i-v_j||^2 -\lambda(\sum_{j=1}^C \mu_{ij}-1) \tag2 min??J=i=1∑N?j=1∑C?μijm?∣∣xi??vj?∣∣2?λ(j=1∑C?μij??1)(2)
然后對λ\lambdaλ求偏導并令其為零,得:
?J?λ=∑j=1Cμij?1=0(3)\frac{\partial J}{\partial\lambda}=\sum_{j=1}^C \mu_{ij}-1=0 \tag3 ?λ?J?=j=1∑C?μij??1=0(3)
再對μij\mu_{ij}μij?求偏導并令其為零,得:
?J?μij=m?μijm?1∣∣xi?vj∣∣2?λ=0(4)\frac{\partial J}{\partial\mu_{ij}}=m\cdot \mu_{ij}^{m-1} ||x_i-v_j||^2 -\lambda=0 \tag4 ?μij??J?=m?μijm?1?∣∣xi??vj?∣∣2?λ=0(4)
由(4)可得
μij=(λm∣∣xi?vj∣∣2)1m?1(5)\mu_{ij}=\left( \frac{\lambda}{m||x_i-v_j||^2}\right)^\frac{1}{m-1} \tag5 μij?=(m∣∣xi??vj?∣∣2λ?)m?11?(5)
將(5)代入(3)得:
∑j=1C(λm∣∣xi?vj∣∣2)1m?1?1=0∑j=1C(λm)1m?1(1∣∣xi?vj∣∣2)1m?1?1=0(λm)1m?1∑j=1C(1∣∣xi?vj∣∣2)1m?1?1=0\begin{aligned} \sum_{j=1}^C \left( \frac{\lambda}{m||x_i-v_j||^2}\right)^\frac{1}{m-1}-1 &=0 \\ \sum_{j=1}^C \left( \frac{\lambda}{m}\right)^\frac{1}{m-1} \left( \frac1{||x_i-v_j||^2}\right)^\frac{1}{m-1}-1 &=0 \\ \left( \frac{\lambda}{m}\right)^\frac{1}{m-1}\sum_{j=1}^C \left( \frac1{||x_i-v_j||^2}\right)^\frac{1}{m-1}-1 &=0 \end{aligned} j=1∑C?(m∣∣xi??vj?∣∣2λ?)m?11??1j=1∑C?(mλ?)m?11?(∣∣xi??vj?∣∣21?)m?11??1(mλ?)m?11?j=1∑C?(∣∣xi??vj?∣∣21?)m?11??1?=0=0=0?
于是我們就可以得到:
(λm)1m?1=1∑j=1C(1∣∣xi?vj∣∣2)1m?1(6)\left( \frac{\lambda}{m}\right)^\frac{1}{m-1} =\frac1{\sum_{j=1}^C \left( \frac1{||x_i-v_j||^2}\right)^\frac{1}{m-1}} \tag6 (mλ?)m?11?=∑j=1C?(∣∣xi??vj?∣∣21?)m?11?1?(6)
將(6)再代入(4)得:
μij=1∑k=1C(1∣∣xi?vk∣∣2)1m?1(1∣∣xi?vj∣∣2)1m?1=1∑k=1C(∣∣xi?vj∣∣2∣∣xi?vk∣∣2)1m?1(7)\mu_{ij} = \frac1{\sum_{k=1}^C \left( \frac1{||x_i-v_k||^2}\right)^\frac{1}{m-1}} \left( \frac1{||x_i-v_j||^2}\right)^\frac{1}{m-1} = \frac1{\sum_{k=1}^C \left( \frac{||x_i-v_j||^2}{||x_i-v_k||^2}\right)^\frac{1}{m-1}} \tag7 μij?=∑k=1C?(∣∣xi??vk?∣∣21?)m?11?1?(∣∣xi??vj?∣∣21?)m?11?=∑k=1C?(∣∣xi??vk?∣∣2∣∣xi??vj?∣∣2?)m?11?1?(7)
再對viv_ivi?求偏導并令其為零,得:
?J?vi=?2∑i=1Nμijm(xi?vj)(8)\frac{\partial J}{\partial v_i}=-2\sum_{i=1}^N\mu_{ij}^m(x_i-v_j) \tag8 ?vi??J?=?2i=1∑N?μijm?(xi??vj?)(8)
vj=∑i=1Nμijmxi∑i=1Nμijm(9)v_j=\frac{\sum_{i=1}^N\mu_{ij}^mx_i}{\sum_{i=1}^N\mu_{ij}^m}\tag9 vj?=∑i=1N?μijm?∑i=1N?μijm?xi??(9)
式(9)即為聚類中心vjv_jvj?的更新公式。
總結一下模糊C均值的更新公式如下:
μij=1∑k=1C(∣∣xi?vj∣∣2∣∣xi?vk∣∣2)1m?1vj=∑i=1Nμijmxi∑i=1Nμijm\mu_{ij}=\frac1{\sum_{k=1}^C \left( \frac{||x_i-v_j||^2}{||x_i-v_k||^2}\right)^\frac{1}{m-1}}\ \ \ \ \ \ \ \ v_j=\frac{\sum_{i=1}^N\mu_{ij}^mx_i}{\sum_{i=1}^N\mu_{ij}^m} μij?=∑k=1C?(∣∣xi??vk?∣∣2∣∣xi??vj?∣∣2?)m?11?1?????????vj?=∑i=1N?μijm?∑i=1N?μijm?xi??
算法步驟
??Calculate UtU_tUt? with Vt?1V_{t-1}Vt?1? and (7)
??Calculate VtV_tVt? with UtU_tUt? and (9)
??If Et=∣∣Vt?Vt?1∣∣err≤εE_t=||V_t-V_{t-1}||_{err} \leq \varepsilonEt?=∣∣Vt??Vt?1?∣∣err?≤ε
??Stop and put (Uf,Vf)=(Ut,Vt)(U_f, V_f)=(U_t, V_t)(Uf?,Vf?)=(Ut?,Vt?); Else
Next t
舉個例子
我們考慮FCM在一維下應用的情況。 使用二十個數據和三個聚類來初始化算法并計算U矩陣。 下圖顯示了每個基準面和每個聚類的成員隸屬度。 根據隸屬函數,數據的顏色是最近的群集的顏色。
在上圖所示的仿真中,我們使用了模糊系數 m=2m = 2m=2,其中模糊分布取決于簇的特定位置。 因為尚未執行任何步驟,所以無法很好地識別群集。 現在可以運行算法,直到驗證停止條件為止。 下圖顯示了在第8步達到的最終條件,其中 m=2m = 2m=2 和 ε=0.3\varepsilon= 0.3ε=0.3:
不同的初始化會導致算法的不同演化,它們可以收斂到相同的結果,但是迭代步驟的數量就不一樣了。
python實現FCM對iris數據集進行聚類
import numpy as np from sklearn import datasets import matplotlib.pyplot as plt from sklearn.decomposition import PCA import scipy.io as scioC = 3 m = 2 # T = 5000 # EPS = 0.0000001 colors = ['r', 'b', 'g']def norm2(x):x = np.mat(x)return np.dot(x.reshape(1, -1), x.reshape(-1, 1))def cal(x_i, c_j, c_k):x_i = np.mat(x_i).reshape(1, -1)c_j = np.mat(c_j).reshape(1, -1)c_k = np.mat(c_k).reshape(1, -1)return float(np.power(norm2(x_i-c_j)/norm2(x_i-c_k), 2.0/(m-1)))def fuzzy_c_means(data, m, C, EPS, T):data = np.mat(data)n, p = data.shapeV = [np.random.random([1, p]) for _ in range(C)]U = [[0 for i in range(C)] for j in range(n)]for i in range(n):for j in range(C):down = 0for k in range(C):down += cal(data[i], V[j], V[k])U[i][j] = 1.0/downfor _ in range(T):for j in range(C):down = 0V[j] = np.zeros([1, p])for i in range(n):u_i_j_m = pow(U[i][j], m)V[j] += data[i]*u_i_j_mdown += u_i_j_mV[j] /= downupgrade = 0for i in range(n):for j in range(C):down = 0for k in range(C):down += cal(data[i], V[j], V[k])tmp = 1.0 / downupgrade += abs(U[i][j]-tmp)U[i][j] = tmpif upgrade < EPS:breakfor i in range(n):idx = np.argmax(U[i])plt.scatter(float(data[i][:, 0]), float(data[i][:, 1]), c=colors[idx])plt.show()if __name__ == '__main__':a = datasets.load_iris()data = a['data']pca = PCA(n_components=2)data = pca.fit_transform(data)fuzzy_c_means(data=data, m=2, C=C, EPS=1e-7, T=5000)原數據通過PCA降到二維空間中的分布情況如下圖所示
通過FCM進行聚類后的結果如下圖所示
參考博客
http://home.deib.polimi.it/matteucc/Clustering/tutorial_html/cmeans.html
https://blog.csdn.net/einsdrw/article/details/37930331
總結
以上是生活随笔為你收集整理的Fuzzy C-Means Clustering(模糊C均值)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 没有 CMS,能使用 DITA 吗?
- 下一篇: 第一天(杨庆东)