Numpy 期望最大化(GMM-EM)从未找到正确的参数。(高斯混合)
我试图学习混合高斯(1D)中参数估计的期望最大化。然而,该算法似乎很少找到正确的参数。我想知道我是否做错了什么 数据由3个不同位置的三个高斯数生成(Numpy 期望最大化(GMM-EM)从未找到正确的参数。(高斯混合),numpy,machine-learning,statistics,scipy,gaussian,Numpy,Machine Learning,Statistics,Scipy,Gaussian,我试图学习混合高斯(1D)中参数估计的期望最大化。然而,该算法似乎很少找到正确的参数。我想知道我是否做错了什么 数据由3个不同位置的三个高斯数生成(x=-10、x=5和x=10): 我检查了直方图,x是正确的。通过EM更新完成参数学习: # model and initialization M = 3 # number of mixtures alpha = np.ones(M)*.5 # -> likelihood of the mixture mu = np.random.random
x=-10、x=5和x=10
):
我检查了直方图,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
#模型和初始化
M=3#混合料数量
α=np.一(M)*.5#->混合物的可能性
mu=np.随机.随机(M)*10#->高斯分布的平均值
sigma=np.one(M)*1.0#->高斯分布的标准
w_mt=np.zeros((M,len(x))#->q(混合数据,参数)
#EM
对于范围(100)内的i:
打印“α:”,α,“μ:”,μ,“σ:”,σ
#电子步
对于范围内的m(m):
w_mt[m]=alpha[m]*mlab.normpdf(x,mu[m],sigma[m])
C=np.和(w_mt,轴=0)#归一化
w_mt=w_mt/C
#M步
α=np.和(w_mt,轴=1)/len(x)
μ=np.和(w_mt*x,轴=1)/np.和(w_mt,轴=1)
sigma=np.sum(w_mt*pow(x-mu[:,np.newaxis],2),axis=1)/np.sum(w_mt,axis=1)
西格玛[西格玛<0.1]=0.1#避免数值问题
我希望算法(至少有时)能够找到std~=1.0的正确的mu
(即-10,5,10)。然而,算法似乎永远无法做到这一点。谢谢你的帮助
更新:
特德·金的修正似乎解决了这个问题。我在计算std时忘了取的平方根。如果有人感兴趣,这里是更新代码的链接:西格玛是标准偏差,但代码中的西格玛是变化(即西格玛**2) 试一试
通过将平均值
mu
视为向量,将Sigma
视为协方差矩阵而不是方差,这也可以推广到更高的维度
例如,k
th高斯的协方差矩阵Sigma_k
可以在EM的M步中用MLE计算,其中phi[i,k]
表示i
th数据点属于k
th簇的概率,在前面的EM算法的E-step中计算
Sigma[k,:,:]=sum([phi[i,k]*np.outer(X[i,:]-mu[k,:],X[i,:]-mu[k,:]),用于范围(n)]内的i)/n_[k]
下图显示了具有k=3
群集中心的GMM-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
sigma = np.sqrt(np.sum(w_mt*pow(x - mu[:,np.newaxis],2),axis=1) / np.sum(w_mt,axis=1))