原型聚类之高斯混合聚类及Python实现

高斯混合模型聚类(Gaussian Mixture Mode,GMM)

高斯混合模型是一种概率式的聚类方法,它假定所有的数据样本 x x k k 个混合多元高斯分布组合成的混合分布生成。

p(x)=i=1kαip(x|μi,Σi)(1.1) (1.1) p ( x ) = ∑ i = 1 k α i ⋅ p ( x | μ i , Σ i )

其中 p(x|μ,Σ) p ( x | μ , Σ ) 为服从高斯分布的n维随机向量 x x 的概率密度函数
p(x)=1(2π)n2|Σ|12e12(xμ)TΣ1(xμ)(1.2) (1.2) p ( x ) = 1 ( 2 π ) n 2 | Σ | 1 2 e − 1 2 ( x − μ ) T Σ − 1 ( x − μ )

python 代码实现如下:

# 高斯分布的概率密度函数
def prob(x, mu, sigma):
    n = np.shape(x)[1]
    expOn = float(-0.5 * (x - mu) * (sigma.I) * ((x - mu).T))
    divBy = pow(2 * np.pi, n / 2) * pow(np.linalg.det(sigma), 0.5)  # np.linalg.det 计算矩阵的行列式
    return pow(np.e, expOn) / divBy

式(1.2)中 μ μ n n 维均值向量 Σ Σ n×n n × n 的协方差矩阵,因此式(1.1)中 μi μ i Σi Σ i 是第 i i 个高斯混合成分的参数,而 αi>0 α i > 0 为相应的“混合系数”(mixture coefficient), ki=1αi=1 ∑ i = 1 k α i = 1
那么,利用GMM进行聚类的过程是利用GMM生成数据样本的“逆过程”:给定聚类簇数 k k ,通过给定的数据集,以某一种参数估计的方法,推导出每一个混合成分的参数:均值向量 μ μ ,协方差矩阵 Σ Σ 和混合系数 α α 。每一个多元高斯分布成分即对应于聚类后的一个簇。高斯混合模型在训练时使用了极大似然估计法,最大化以下对数似然函数:

L=logj=1mp(x)=j=1mlogi=1k(αip(x|μi,Σi))(1.3) (1.3) L = l o g ∏ j = 1 m p ( x ) = ∑ j = 1 m l o g ∑ i = 1 k ( α i ⋅ p ( x | μ i , Σ i ) )

显然,该优化式无法直接通过解析方式求得解,常采用EM算法进行迭代优化求解,简单的推导如下:
若参数 {(αi,μi,Σi)|(1ik)} { ( α i , μ i , Σ i ) | ( 1 ≤ i ≤ k ) } 能使(1.3)最大化,则由 Lμi=0 ∂ L ∂ μ i = 0
j=1mαip(xj|μi,Σi)kl=1αlp(xj|μl,Σi)(xjμi)=0(1.4) (1.4) ∑ j = 1 m α i ⋅ p ( x j | μ i , Σ i ) ∑ l = 1 k α l ⋅ p ( x j | μ l , Σ i ) ( x j − μ i ) = 0

γji=αip(xj|μi,Σi)kl=1αlp(xj|μl,Σi)(1.5) (1.5) γ j i = α i ⋅ p ( x j | μ i , Σ i ) ∑ l = 1 k α l ⋅ p ( x j | μ l , Σ i )
可知它表示了样本 xj x j 由第 i i 个混合成分生成的后验概率。于是由式(1.4)可得
μi=mj=1(γjixj)mj=1γji(1.6) (1.6) μ i = ∑ j = 1 m ( γ j i ⋅ x j ) ∑ j = 1 m γ j i

即各混合成分的均值可通过样本加权平均来估计,样本权重是每个样本属于该成分的后验概率。类似的,由 LΣi=0 ∂ L ∂ Σ i = 0 可得,
Σi=mj=1γji(xjμi)(xjμi)Tmj=1γji(1.7) (1.7) Σ i = ∑ j = 1 m γ j i ( x j − μ i ) ( x j − μ i ) T ∑ j = 1 m γ j i

对于混合系数 αi α i 除了要最大化 L L 式(1.3),还需要满足 αi0,ki=1αi=1 α i ≥ 0 , ∑ i = 1 k α i = 1 ,考虑 L L 的拉格朗日形式

L+λ(i=1kαi1)(1.8) (1.8) L + λ ( ∑ i = 1 k α i − 1 )

其中 λ λ 为拉格朗日乘子,由式(1.8)对 αi α i 的导数为0,有
j=1mp(xj|μi,Σi)kl=1αlp(xj|μl,Σl)+λ=0(1.9) (1.9) ∑ j = 1 m p ( x j | μ i , Σ i ) ∑ l = 1 k α l ⋅ p ( x j | μ l , Σ l ) + λ = 0

两边同时乘以 αi α i ,对所有样本求和可知 λ=m λ = − m ,有
αi=1mj=1mγji(1.10) (1.10) α i = 1 m ∑ j = 1 m γ j i


输入:样本集 D={x1,x2,...,xm} D = { x 1 , x 2 , . . . , x m }
高斯混合成分个数 k k

  1. 初始化K个多元高斯分布以及其权重
  2. 根据贝叶斯定理,估计每个样本由每个成分生成的后验概率,见式(1.5);(EM方法中的E步)
  3. 根据均值,协方差的定义以及2步求出的后验概率,更新均值向量,见式(1.6)、协方差矩阵式,见式(1.7)和权重,见式(1.10);(EM方法的M步)
  4. 重复2~3步,直到似然函数增加值已小于收敛阈值,或达到最大迭代次数
  5. 对于每一个样本点,根据贝叶斯定理计算出其属于每一个簇的后验概率,并将样本划分到后验概率最大的簇上去

将周志华的《机器学习》上面的例子:以西瓜数据集4.0为例,令高斯混合成分的个数 k=3 k = 3 。算法开始时,假定将高斯混合分布的模型参数初始化为: α1=α2=α3=13;μ1=x6,μ2=x22,μ3=x27 α 1 = α 2 = α 3 = 1 3 ; μ 1 = x 6 , μ 2 = x 22 , μ 3 = x 27 ,

Σ1=Σ2=Σ3=(0.10.00.00.1)(1.11) (1.11) Σ 1 = Σ 2 = Σ 3 = ( 0.1 0.0 0.0 0.1 )

python代码实现如下:

# EM算法
def EM(dataMat, maxIter):
    m, n = np.shape(dataMat)
    # 1.初始化各高斯混合成分参数
    alpha = [1 / 3, 1 / 3, 1 / 3]  # 1.1初始化 alpha1=alpha2=alpha3=1/3
    mu = [dataMat[5, :], dataMat[21, :], dataMat[26, :]]  # 1.2初始化 mu1=x6,mu2=x22,mu3=x27
    sigma = [np.mat([[0.1, 0], [0, 0.1]]) for x in range(3)]  # 1.3初始化协方差矩阵
    gamma = np.mat(np.zeros((m, 3)))
    for i in range(maxIter):
        for j in range(m):
            sumAlphaMulP = 0
            for k in range(3):
                gamma[j, k] = alpha[k] * prob(dataMat[j, :], mu[k], sigma[k])  # 4.计算混合成分生成的后验概率,即gamma
                sumAlphaMulP += gamma[j, k]
            for k in range(3):
                gamma[j, k] /= sumAlphaMulP
        sumGamma = np.sum(gamma, axis=0)

        for k in range(3):
            mu[k] = np.mat(np.zeros((1, n)))
            sigma[k] = np.mat(np.zeros((n, n)))
            for j in range(m):
                mu[k] += gamma[j, k] * dataMat[j, :]
            mu[k] /= sumGamma[0, k]  # 7.计算新均值向量
            for j in range(m):
                sigma[k] += gamma[j, k] * (dataMat[j, :] - mu[k]).T * (dataMat[j, :] - mu[k])
            sigma[k] /= sumGamma[0, k]  # 8. 计算新的协方差矩阵
            alpha[k] = sumGamma[0, k] / m  # 9. 计算新混合系数
            # print(mu)
    return gamma


# init centroids with random samples
def initCentroids(dataMat, k):
    numSamples, dim = dataMat.shape
    centroids = np.zeros((k, dim))
    for i in range(k):
        index = int(np.random.uniform(0, numSamples))
        centroids[i, :] = dataMat[index, :]
    return centroids

#gmm算法模型实现
def gaussianCluster(dataMat,maxIter):
    Iter=maxIter
    m, n = np.shape(dataMat)
    centroids = initCentroids(dataMat, m)  ## step 1: init centroids
    clusterAssign = np.mat(np.zeros((m, 2)))
    gamma = EM(dataMat,Iter)
    for i in range(m):
        # amx返回矩阵最大值,argmax返回矩阵最大值所在下标
        clusterAssign[i, :] = np.argmax(gamma[i, :]), np.amax(gamma[i, :])  # 15.确定x的簇标记lambda
        ## step 4: update centroids
    for j in range(m):
        pointsInCluster = dataMat[np.nonzero(clusterAssign[:, 0].A == j)[0]]
        centroids[j, :] = np.mean(pointsInCluster, axis=0)  # 计算出均值向量
    return centroids, clusterAssign   

使用scikit-learn包实现EM算法

from sklearn import mixture
def test_GMM(dataMat, components=3,iter = 100,cov_type="full"):
    clst = mixture.GaussianMixture(n_components=n_components,max_iter=iter,covariance_type=cov_type)
    clst.fit(dataMat)
    predicted_labels =clst.predict(dataMat)
    return clst.means_,predicted_labels     # clst.means_返回均值

函数原型参考GaussianMixture,它实现了用来拟合高斯混合模型的 期望最大化 (EM) 算法。GaussianMixture.fit 提供了从训练数据中学习高斯混合模型的方法。

实验结果

完整代码见GitHub。
原型聚类之高斯混合聚类及Python实现_第1张图片
原型聚类之高斯混合聚类及Python实现_第2张图片

GMM的优缺点

优点: GMM的优点是投影后样本点不是得到一个确定的分类标记,而是得到每个类的概率,这是一个重要信息。GMM不仅可以用在聚类上,也可以用在概率密度估计上。
缺点:当每个混合模型没有足够多的点时,估算协方差变得困难起来,同时算法会发散并且找具有无穷大似然函数值的解,除非人为地对协方差进行正则化。GMM每一步迭代的计算量比较大,大于k-means。GMM的求解办法基于EM算法,因此有可能陷入局部极值,这和初始值的选取十分相关了。


更多机器学习干货、最新论文解读、AI资讯热点等欢迎关注”AI学院(FAICULTY)”
欢迎加入faiculty机器学习交流qq群:451429116 点此进群
版权声明:可以任意转载,转载时请务必标明文章原始出处和作者信息.


参考文献

[1]. Spark 2.1.0 入门:高斯混合模型(GMM)聚类算法
[2]. 周志华,机器学习,清华大学出版社,2016
[3]. 机器学习Chapter3-(聚类分析)详解高斯混合模型与EM算法(Python实现)

你可能感兴趣的:(聚类详细讲解)