我正在尝试学习高斯混合模型中参数估计的期望最大化算法(1D)。然而,这个算法似乎很少能找到正确的参数。我想知道我是否做错了什么。
数据是由三个高斯分布在三个不同的位置生成的(x=-10,x=5和x=10)。
我期望算法(至少有时)能够找到正确的
更新:Ted Kim的修复似乎已经解决了这个问题。我在计算
数据是由三个高斯分布在三个不同的位置生成的(x=-10,x=5和x=10)。
import numpy as np
import matplotlib.mlab as mlab
import matplotlib.pyplot as plt
# dataset is generated with 3 gaussians at with mean at -10, 10 and 5.
x1 = 1.0 * np.random.randn(10000) - 10.0
x2 = 1.0 * np.random.randn(10000) + 10.0
x3 = 1.0 * np.random.randn(10000) + 5.0
x = np.hstack([x1,x2,x3]) # final data set
我检查了直方图,x是正确的。参数学习使用EM更新完成:
# model and initialization
M = 3 # number of mixtures
alpha = np.ones(M)*.5 # -> likelihood of the mixture
mu = np.random.random(M)*10 # -> mean of the gaussian
sigma = np.ones(M)*1.0 # -> std of the gaussian
w_mt = np.zeros((M,len(x))) # -> q(mixture | data, parameter)
# EM
for i in range(100):
print "alpha:", alpha, "mu:", mu, "sigma:", sigma
# E-step
for m in range(M):
w_mt[m] = alpha[m] * mlab.normpdf(x,mu[m],sigma[m])
C = np.sum(w_mt, axis=0) # normalization
w_mt = w_mt / C
# M-step
alpha = np.sum(w_mt,axis=1) / len(x)
mu = np.sum(w_mt*x,axis=1)/np.sum(w_mt,axis=1)
sigma = np.sum(w_mt*pow(x - mu[:,np.newaxis],2),axis=1) / np.sum(w_mt,axis=1)
sigma[sigma < 0.1] = 0.1 # avoid numerical problems
我期望算法(至少有时)能够找到正确的
mu
(即-10、5、10),其标准差为约1.0。然而,似乎该算法从未能做到这一点。如有任何帮助,将不胜感激。更新:Ted Kim的修复似乎已经解决了这个问题。我在计算
std
时忘记取平方根了。如果有人感兴趣,这里是更新后的代码链接:链接。