EM算法
2019-04-02 本文已影响1人
Vophan
含有隐参数的混合模型的参数估计方法
不是所有问题都可以求得解析解(最简单的似然估计可以)。
迭代的算法。
分为E步,M步。
E step: 得到Q函数
M step: 求使Q函数最大的
高斯混合模型GMM
高斯:高斯分布
多个高斯分布叠加而成
x:观察变量
z:隐变量,表示的对应的样本x属于哪一个高斯分布。(离散的随机变量)
(x,z) :完全数据
为什么用EM算法:
因为在高维的高斯分布问题上,用MLE得不到解析解,首先log里面是连加,很难算出解析解,而且高维的高斯分布式子本身就很难计算。
EM算法的导出:
事实上,EM算法是通过迭代逐步近似极大化的,我们希望新的估计值可以让增加,即逐步到达最大值。
为此,两者的差:
然后利用jenson不等式,得到差的下界:
下界:
为什么要求下界呢?
通过下界,我们可以发现我们将前面提到的log中的连加变成了连乘,而且下界增大的方向一定可以使增大。
然后,我们省去在对求偏导时为常数的项:
由于是近似逼近的方法,所以EM算法并不能保证取到全局最优解。
代码:
import numpy as np
import math
class EmAlgorithm:
"""
Implements of EM algorithm
"""
def __init__(self, data, models_num):
self.data = np.array(data)
self.data_num = len(data)
self.models_num = models_num
self.mu = np.array([[1,2]]).T
self.theta = np.array([[1,1]]).T
self.alpha = np.array([0.1, 0.9],dtype=float).reshape(1,2)
self.gama = np.zeros((self.models_num, self.data_num))
self.max_iters = 500
def compute_gama(self):
self.gauss = self._compute_Guass(self.data, self.mu, self.theta)
print(self.gauss,"\n",self.alpha.T)
self.gama = self.gauss*self.alpha.T / np.sum(self.gauss*self.alpha.T,axis=0)
def _compute_Guass(self, x, mu, theta):
x = np.tile(x, (self.models_num,1))
mu = np.tile(mu, (1,self.data_num))
theta = np.tile(theta, (1,self.data_num))
return 1/np.sqrt(2*np.pi)*theta*np.exp((x-mu)**2/2*theta**2)
def update(self):
self.mu = (np.sum(self.gama*self.data, axis=1) / np.sum(self.gama, axis=1)).T.reshape(self.models_num,1)
self.theta = (np.sum((((np.tile(self.data, (2,1)).T - self.mu.T)**2)*self.gama.T).T,axis=1) / np.sum(self.gama, axis=1)).T.reshape(self.models_num,1)
self.alpha = ((np.sum(self.gama, axis=1) / self.data_num).T.reshape(self.models_num,1)).T
def train(self):
for i in range(self.max_iters):
print(i)
self.compute_gama()
self.update()
print("----------------------------")
print("alpha:", self.alpha)
print("mu:", self.mu)
print("theta:", self.theta)
没时间排版了,有空在做吧。