高斯混合聚类有一个重要的前提:
假定样本集是从若干个(需要聚类的个数)满足高斯分布的集合中按照一定的比例随机抽取生成的。而高斯混合聚类的任务就是上面假定的逆过程,从这些杂乱的高斯分布中抽取出来的样本集,重新归类到集合中。
既然高斯混合聚类是从若干个满足高斯分布的集合中抽取而成,那么高斯分布是怎么样的呢?根据定义多元的高斯分布的概率密度函数长下面这个样子。
p ( x ) = 1 ( 2 π ) n / 2 ∣ Σ ∣ − 1 e − 1 2 ( x − μ ) T Σ − 1 ( x − μ ) p(\boldsymbol x)=\frac{1}{(2\pi)^{n/2}|\Sigma|^{-1}}e^{- \frac{1}{2}(\boldsymbol x - \boldsymbol \mu)^{T} \Sigma^{-1} (\boldsymbol x - \boldsymbol \mu)} p(x)=(2π)n/2∣Σ∣−11e−21(x−μ)TΣ−1(x−μ)
这个样子简直太麻烦了,所以我们换成下面这种简单的:
p ( x ∣ μ , Σ ) p(\boldsymbol x | \boldsymbol \mu , \Sigma) p(x∣μ,Σ)
表示概率密度值由后面两个变量决定,一个是均值,一个是协方差矩阵。均值大家肯定都理解,协方差矩阵不好理解,先放着,有时间在看。
那接下来就是说混合高斯应该是什么样子的呢?不就是若干个(假设为k个)简单加起来吗,一定概率,则是说每个高斯类别具有不同的权重,简单来说就是多了个系数 a i a_i ai呗。
p M ( x ) = ∑ i = 1 k a i p ( x ∣ μ i , Σ i ) p_M(\boldsymbol x)=\sum_{i=1}^{k}a_i p(\boldsymbol x | \boldsymbol \mu_i , \Sigma_i) pM(x)=i=1∑kaip(x∣μi,Σi)
既然 a i a_i ai表示为概率,则总和为1,表示样本只能从这几个高斯分布中抽取。官方说法叫做 混合系数
∑ i = i k a i = 1 \sum_{i=i}^{k}a_i =1 i=i∑kai=1
现在,假定我从样本集中随机选出一个样本 x j \boldsymbol x_j xj,则这个样本是属于这k个高斯集合中的哪个的呢?很显然,这就是我们聚类要干的事情。虽然不知道是哪个,但是属于任何一个的概率我们是知道的。设这个样本属于 z j z_j zj
p ( z j = i ) = a i 对 于 任 意 的 i = 1 , 2 , 3 , . . . , k p(z_j=i)=a_i 对于任意的i=1,2,3,...,k p(zj=i)=ai对于任意的i=1,2,3,...,k
为什么?因为样本集我们就是按照 a i a_i ai权重从各个集合中取出的呀。
接下来就是最为关键的推到了,对于一个已知的一个样本 x j \boldsymbol x_j xj, p ( z j = i ) p(z_j=i) p(zj=i)又是多少呢?(前面的是随机抽取一个样本,会得到什么结果我们未知.) 这明显是一个条件概率的问题。也就是在条件 x j \boldsymbol x_j xj下,求取 p ( z j = i ) p(z_j=i) p(zj=i)的值。根据贝叶斯公式 p ( x ∣ y ) ⋅ p ( y ) = p ( y ∣ x ) ⋅ p ( x ) p(x|y) \cdot p(y)=p(y|x) \cdot p(x) p(x∣y)⋅p(y)=p(y∣x)⋅p(x)
p M ( z j = i ∣ x j ) = p ( z j = i ) p M ( x j ∣ z j = i ) p M ( x j ) p M ( z j = i ∣ x j ) = a i ⋅ p ( x j ∣ x i , Σ i ) ∑ l = 1 k a l p ( x j ∣ μ l , Σ l ) p_M(z_j = i | \boldsymbol x_j)=\frac{p(z_j=i)p_M(\boldsymbol x_j|z_j=i)}{p_M(\boldsymbol x_j)} \\ \\ p_M(z_j = i | \boldsymbol x_j)=\frac{a_i \cdot p(\boldsymbol x_j| \boldsymbol x_i,\boldsymbol \Sigma_i) }{\sum_{l=1}^{k}a_l p(\boldsymbol x_j | \boldsymbol \mu_l, \Sigma_l)} pM(zj=i∣xj)=pM(xj)p(zj=i)pM(xj∣zj=i)pM(zj=i∣xj)=∑l=1kalp(xj∣μl,Σl)ai⋅p(xj∣xi,Σi)
转化很明显, p M ( x j ∣ z j = i ) p_M(\boldsymbol x_j|z_j=i) pM(xj∣zj=i) 后面的条件表面只属于第i个集合,则概率记为第i个集合的概率,分母则是混合高斯的组成公式的展开。
简单记作:
γ j i = p M ( z j = i ∣ x j ) \gamma_{ji}= p_M(z_j = i | \boldsymbol x_j) γji=pM(zj=i∣xj)
表示在 x j x_j xj的条件下, x j x_j xj属于第i个集合的概率,这时一个很关键的概率。
如果混合高斯分布已知,则我们只需要将所有i(1~k)的概率都计算出来,概率最大的即可以认为 x j x_j xj 属于这个概率最大的高斯分布(假设为第 λ j 个 \lambda_j个 λj个),则:
λ j = a r g max i ∈ { 1 , 2 , . . k } γ j i \lambda_j= arg \max_{i \in \{1,2,..k\}} \gamma_{ji} λj=argi∈{1,2,..k}maxγji
讲解到这里,问题已经很明显了:
我们的目的是求出使得参数 γ j i \gamma_{ji} γji最大的变量i,作为 x j \boldsymbol x_j xj的类别标记。
但是要求解参数i, 则需要获得混合高斯分布 p M ( x ) p_M(\boldsymbol x) pM(x)的参数
问题转化为:如何求解混合高斯分布 p M ( x ) p_M(\boldsymbol x) pM(x)的各个参数,从而求解每一个样本对应的 λ \lambda λ(也就是我们所说的标记)
我们从未知的分布 p M ( x ) p_M(\boldsymbol x) pM(x)(也就是混合高斯分布)中采取了样本集,现在要计算分布中的各个参数,这不就是传说中的参数估计问题吗?由于我们要用这些参数去计算概率,所以必然是点估计,点估计中与条件有关的,最好使的不就是极大似然估计吗?
要使用极大似然估计,必然要先搞清楚,我们需要估计的参数是什么对吧。是时候把我们需要估计的模型(也就是刚刚的概率分布公式啦)拿出来了。
p M ( x ) = ∑ i = 1 k a i p ( x ∣ μ i , Σ i ) p_M(\boldsymbol x)=\sum_{i=1}^{k}a_i p(\boldsymbol x | \boldsymbol \mu_i , \Sigma_i) pM(x)=i=1∑kaip(x∣μi,Σi)
明显的,我们需要估计{ a i , μ i , Σ i a_i,\mu_i,\Sigma_i ai,μi,Σi|i=1,2,…k} 也就是k组这三个量。
接下来计算极大似然函数(取对数形式),对于含由m个样本的集合D,
L L ( D ) = ln ( ∏ j = 1 m p M ( x j ) ) = ∑ j = 1 m ln ( ∑ i = 1 k a i p ( x j ∣ μ i , Σ i ) ) \begin{aligned} LL(D)&= \ln (\prod_{j=1}^{m} p_M(\boldsymbol x_j))\\ &=\sum_{j=1}^{m} \ln (\sum_{i=1}^{k}a_i p(\boldsymbol x_j | \boldsymbol \mu_i , \Sigma_i)) \\ \end{aligned} LL(D)=ln(j=1∏mpM(xj))=j=1∑mln(i=1∑kaip(xj∣μi,Σi))
也就说在已知{ m , k , x m,k,\boldsymbol x m,k,x}的情况下,计算使得 L L ( D ) LL(D) LL(D)最大的参数{ a i , μ i , Σ i ∣ 1 ≤ i ≤ k a_i,\mu_i,\Sigma_i| 1 \leq i \leq k ai,μi,Σi∣1≤i≤k} 。
假设我们有一组参数{ a i , μ i , Σ i ∣ 1 ≤ i ≤ k a_i,\mu_i,\Sigma_i| 1 \leq i \leq k ai,μi,Σi∣1≤i≤k} 使得值最大,则:
∂ L L ( D ) ∂ μ i = 0 = ∑ j = 1 m a i ⋅ p ( x j ∣ μ i , Σ i ) ∑ i = 1 k a i p ( x j ∣ μ i , Σ i ) ( x j − μ i ) = ∑ j = 1 m γ i j ( x j − μ i ) = 0 \begin{aligned} \frac{\partial LL(D)}{\partial \boldsymbol \mu_i} & =0 \\ & = \sum_{j=1}^{m} \frac{a_i \cdot p(\boldsymbol x_j | \boldsymbol \mu_i , \Sigma_i)}{\sum_{i=1}^{k}a_i p(\boldsymbol x_j | \boldsymbol \mu_i , \Sigma_i)}(\boldsymbol x_j - \boldsymbol \mu_i ) \\ & = \sum_{j=1}^{m} \gamma_{ij} (\boldsymbol x_j - \boldsymbol \mu_i ) = 0 \end{aligned} ∂μi∂LL(D)=0=j=1∑m∑i=1kaip(xj∣μi,Σi)ai⋅p(xj∣μi,Σi)(xj−μi)=j=1∑mγij(xj−μi)=0
所以有
μ i = ∑ j = 1 m γ j i x j ∑ j = 1 m γ j i \boldsymbol \mu_i = \frac{\sum_{j=1}^{m} \gamma_{ji} \boldsymbol x_j}{\sum_{j=1}^{m} \gamma_{ji}} μi=∑j=1mγji∑j=1mγjixj
类似的,根据
∂ L L ( D ) ∂ Σ i = 0 \begin{aligned} \frac{\partial LL(D)}{\partial \boldsymbol \Sigma_i} & =0 \\ \end{aligned} ∂Σi∂LL(D)=0
可以得
【实际上,这些公式的推导都十分麻烦,包含了大量的矩阵内容,我还没搞懂,后面搞懂了补上】
Σ i = ∑ j = 1 m γ j i ( x j − μ i ) ( x j − μ i ) T ∑ j = 1 m γ j i \boldsymbol \Sigma_i = \frac{\sum_{j=1}^{m} \gamma_{ji}( \boldsymbol x_j - \boldsymbol \mu_i)( \boldsymbol x_j - \boldsymbol \mu_i)^T}{ \sum_{j=1}^{m} \gamma_{ji}} Σi=∑j=1mγji∑j=1mγji(xj−μi)(xj−μi)T
对于参数a,有条件 a i ≥ 0 a_i \geq 0 ai≥0,并且 ∑ i = 1 m a i = 1 , \sum_{i=1}^{m}a_i =1, ∑i=1mai=1,
∂ ( L L ( D ) + ( ∑ i = 1 m a i − 1 ) ) ∂ a i = 0 = ∑ j = 1 m p ( x j ∣ μ i , Σ i ) ∑ l = 1 k a l ∗ p ( x j ∣ μ i , Σ i ) + λ = 0 \begin{aligned} \frac{\partial (LL(D)+(\sum_{i=1}^{m}a_i -1))}{\partial a_i} & =0 \\ & = \sum_{j=1}^{m} {\frac{p(\boldsymbol x_j | \boldsymbol \mu_i, \boldsymbol \Sigma_i)}{\sum_{l=1}^{k}a_l *p(\boldsymbol x_j | \boldsymbol \mu_i, \boldsymbol \Sigma_i)}}+\lambda = 0 \end{aligned} ∂ai∂(LL(D)+(∑i=1mai−1))=0=j=1∑m∑l=1kal∗p(xj∣μi,Σi)p(xj∣μi,Σi)+λ=0
两边同时乘以 a i a_i ai, 对所有样本求和可知,
λ = − m a i = 1 m ∑ j = 1 m γ j i \begin{aligned} \lambda & = -m \\ a_i & = \frac{1}{m} \sum_{j=1}^{m} \gamma_{ji} \end{aligned} λai=−m=m1j=1∑mγji
接下来就是EM算法了,
python sklearn 库中有现成的算法:
import matplotlib.pyplot as plt
import numpy as np
from sklearn.mixture import GaussianMixture as GMM
from sklearn.datasets.samples_generator import make_blobs
if __name__ == "__main__":
#Generate some data for train
X, y_true = make_blobs(n_samples=400, centers=4,
cluster_std=0.60, random_state=0)
X = X[:, ::-1] # flip axes for better plotting
#plt.figure(1)
ax=plt.subplot(1, 2, 1)
ax.scatter(X[:, 0], X[:, 1], s=40, zorder=2)
gmm = GMM(n_components=4, random_state=42)
labels = gmm.fit(X).predict(X)
bx=plt.subplot(1, 2, 2)
bx.scatter(X[:, 0], X[:, 1], c=labels, s=40, cmap='viridis', zorder=2)
plt.show()
代码引用https://jakevdp.github.io/PythonDataScienceHandbook/05.12-gaussian-mixtures.html
原理部分主要参考西瓜书
实际上是有一点粗糙,后续代码实战过程中手撕它。