高斯混合模型是一种概率式的聚类方法,它假定所有的数据样本 x x 由 k k 个混合多元高斯分布组合成的混合分布生成。
# 高斯分布的概率密度函数
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 ,通过给定的数据集,以某一种参数估计的方法,推导出每一个混合成分的参数:均值向量 μ μ ,协方差矩阵 Σ Σ 和混合系数 α α 。每一个多元高斯分布成分即对应于聚类后的一个簇。高斯混合模型在训练时使用了极大似然估计法,最大化以下对数似然函数:
对于混合系数 αi α i 除了要最大化 L L 式(1.3),还需要满足 αi≥0,∑ki=1αi=1 α i ≥ 0 , ∑ i = 1 k α i = 1 ,考虑 L L 的拉格朗日形式
输入:样本集 D={x1,x2,...,xm} D = { x 1 , x 2 , . . . , x m }
高斯混合成分个数 k k
将周志华的《机器学习》上面的例子:以西瓜数据集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 ,
# 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
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 提供了从训练数据中学习高斯混合模型的方法。
优点: 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实现)