高斯混合模型聚类_GMM: Gaussian Mixed Model(高斯混合模型)
0. 簡介
GMM和Kmeans一樣也屬于聚類,其算法訓練流程也十分相似,Kmeans可認為是“硬聚類”,GMM是“軟聚類”。
給定數據集X,Kmeans算法流程是這樣的----- a 初始化:隨機初始k個中心(即k個點,記為μ);b 矯正數據歸屬:計算X中每個點與k個中心的距離,并將其歸為相距最近的那個中心;c 矯正中心:計算每個中心(共k個)所有點的均值,并將其更新為中心值;d 完成整體訓練:循環b和c,直到聚類到“足夠好”。
GMM算法流程和Kmeans基本一致,區別在于:a 除了初始化k個中心(μ)外,每個中心還對應一個協方差矩陣(Σ)和混合概率(π),其中μ代表高斯分布的中心,Σ代表高斯分布形狀,π代表高斯函數值的大小;b 矯正數據歸屬,GMM中每個數據點并不完全歸屬某個中心,而是歸屬每個中心,只是歸屬的概率不同;c 矯正中心,每個中心矯正更新時考慮數據集X中的所有點,而非某一部分數據點。
以下使用鳶尾花數據集按照a~d的流程解析GMM;導入鳶尾花數據集如下;
from sklearn import datasets import numpy as npiris = datasets.load_iris() X = iris.data N, D = X.shape display(X.shape, X[:10]) (150, 4) array([[5.1, 3.5, 1.4, 0.2],[4.9, 3. , 1.4, 0.2],[4.7, 3.2, 1.3, 0.2],[4.6, 3.1, 1.5, 0.2],[5. , 3.6, 1.4, 0.2],[5.4, 3.9, 1.7, 0.4],[4.6, 3.4, 1.4, 0.3],[5. , 3.4, 1.5, 0.2],[4.4, 2.9, 1.4, 0.2],[4.9, 3.1, 1.5, 0.1]])即鳶尾花數據集是一個150行4列的矩陣。
1. 初始化
定義聚類數量為3類,每一類都初始化一個中心μ、一個協方差矩陣Σ和混合概率π;
mus = X[np.random.choice(X.shape[0], 3, replace=False)] covs = [np.identity(4) for i in range(3)] pis = [1/3] * 32. 矯正數據歸屬
普通高斯概率函數(只有一個中心)如下,其中D是數據維度,此處D=4;
表示數據點x歸屬該中心(μ、Σ)的概率,代碼如下;
def gaussian(X, mu, cov):diff = X - mureturn 1 / ((2 * np.pi) ** (D / 2) * np.linalg.det(cov) ** 0.5) * np.exp(-0.5 * np.dot(np.dot(diff, np.linalg.inv(cov)), diff))當用混合高斯函數(即多個中心)時,表示一個數據點n歸屬中心k(μ_k、Σ_k)的概率函數如下,其中k表示第k個中心,此處總共有3個中心,即K=3;
將上式定義為γ_z_nk,即
代碼如下:
gammas = [] for mu_, cov_, pi_ in zip(mus, covs, pis):# loop each centergamma_ = [[pi_ * gaussian(x_, mu_, cov_)] for x_ in X]# loop each pointgammas.append(gamma_) gammas = np.array(gammas) gamma_total = gammas.sum(0) gammas /= gamma_total3. 矯正中心
根據2.中的gammas值,更新μ、Σ和π值,公式如下,其中N表示數據總個數,此處N=150;
代碼如下;
mus, covs, pis = [], [], [] for gamma_ in gammas:#loop each centergamma_sum = gamma_.sum()pi_ = gamma_sum / Nmu_ = (gamma_ * X).sum(0) / gamma_sumcov_ = []for x_, gamma_i in zip(X, gamma_):diff = (x_ - mu_).reshape(-1, 1)cov_.append(gamma_i * np.dot(diff, diff.T))cov_ = np.sum(cov_, axis=0) / gamma_sumpis.append(pi_)mus.append(mu_)covs.append(cov_)4. 完成整體訓練
將2.~3.作為一個循環單元,寫成一個函數;
def train_step(X, mus, covs, pis):gammas = []for mu_, cov_, pi_ in zip(mus, covs, pis):# loop each centergamma_ = [[pi_ * gaussian(x_, mu_, cov_)] for x_ in X]# loop each pointgammas.append(gamma_)gammas = np.array(gammas)gamma_total = gammas.sum(0)gammas /= gamma_totalmus, covs, pis = [], [], []for gamma_ in gammas:#loop each centergamma_sum = gamma_.sum()pi_ = gamma_sum / Nmu_ = (gamma_ * X).sum(0) / gamma_sumcov_ = []for x_, gamma_i in zip(X, gamma_):diff = (x_ - mu_).reshape(-1, 1)cov_.append(gamma_i * np.dot(diff, diff.T))cov_ = np.sum(cov_, axis=0) / gamma_sumpis.append(pi_)mus.append(mu_)covs.append(cov_)return mus, covs, pis訓練50次;
for _ in range(50):mus, covs, pis = train_step(X, mus, covs, pis)訓練完成后,會得到3個中心,可計算每個點歸屬這三個中心的概率(即γ_z_nk,第n個點歸屬第k個中心的概率),并將其歸屬于概率最大的那個中心;因為數據集是4維,無法可視化,僅選擇前兩維度進行可視化展示如下;
整個訓練過程的動態圖如下;
完整代碼如下;
from sklearn import datasets import numpy as np import matplotlib.pyplot as pltiris = datasets.load_iris() X = iris.data N, D = X.shapemus = X[np.random.choice(X.shape[0], 3, replace=False)] covs = [np.identity(4) for i in range(3)] pis = [1/3] * 3def gaussian(X, mu, cov):diff = X - mureturn 1 / ((2 * np.pi) ** (D / 2) * np.linalg.det(cov) ** 0.5) * np.exp(-0.5 * np.dot(np.dot(diff, np.linalg.inv(cov)), diff))def get_likelihood(gamma_total):return np.log(gamma_total).sum()def train_step(X, mus, covs, pis):gammas = []for mu_, cov_, pi_ in zip(mus, covs, pis):# loop each centergamma_ = [[pi_ * gaussian(x_, mu_, cov_)] for x_ in X]# loop each pointgammas.append(gamma_)gammas = np.array(gammas)gamma_total = gammas.sum(0)gammas /= gamma_totalmus, covs, pis = [], [], []for gamma_ in gammas:#loop each centergamma_sum = gamma_.sum()pi_ = gamma_sum / Nmu_ = (gamma_ * X).sum(0) / gamma_sumcov_ = []for x_, gamma_i in zip(X, gamma_):diff = (x_ - mu_).reshape(-1, 1)cov_.append(gamma_i * np.dot(diff, diff.T))cov_ = np.sum(cov_, axis=0) / gamma_sumpis.append(pi_)mus.append(mu_)covs.append(cov_)return mus, covs, pis, gamma_totallog_LL = [] for _ in range(50):mus, covs, pis, gamma_total = train_step(X, mus, covs, pis)log_LL.append(get_likelihood(gamma_total)) plt.plot(log_LL) plt.grid()總結
以上是生活随笔為你收集整理的高斯混合模型聚类_GMM: Gaussian Mixed Model(高斯混合模型)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 说实话,用完Gradle之后,有点嫌弃M
- 下一篇: 精通Javascript之引用