简化EM的公式

Mic*_*cle 1 math matlab mixture-model

我想在Matlab中计算下面的公式(EM的E-step for Multinomial Mixture Model),
在此输入图像描述

g和θ是矩阵,θ和λ具有以下约束:
在此输入图像描述
在此输入图像描述
但是m的计数大于1593,当计算θ的乘积时,数字变得非常小,Matlab将其保存为零.任何人都可以简化g公式或使用其他技巧来解决这个问题?

更新:

data: data.txt (下载后,将文件扩展名更改为'mat')

码:

function EM(data)
%% initialize
K=2;
[N M]=size(data);
g=zeros(N,K);
landa=ones(K,1) .* 0.5;
theta = rand(M, K);
theta = bsxfun(@rdivide, theta, sum(theta,1))';
%% EM
for i=1:10
%% E Step
    for n=1:N
        normalize=0;
        for k=1:K
            g(n,k)=landa(k) * prod(theta(k,:) .^ data(n,:));
            normalize=normalize + landa(k) * prod(theta(k,:) .^ data(n,:));
        end
        g(n,:)=g(n,:) ./ normalize;
    end
%% M Step 
    for k=1:K
        landa(k)=sum(g(:,k)) / N ;
        for m=1:M
            theta(k,m)=(sum(g(:,k) .* data(:,m)) + 1) / (sum(g(:,k) .* sum(data,2)) + M);
        end
    end
end
Run Code Online (Sandbox Code Playgroud)

结束

A. *_*nda 5

您可以使用对数的计算而不是实际值来避免下溢问题.

首先,我们稍微重新格式化E步骤代码:

for n = 1 : N
    for k = 1 : K
        g(n, k) = lambda(k) * prod(theta(k, :) .^ data(n, :));
    end
end
g = bsxfun(@rdivide, g, sum(g, 2));
Run Code Online (Sandbox Code Playgroud)

因此normalize,我们不是在一个额外的变量中累积分母,而是在两个循环之后的一步中进行归一化.

现在我们引入一个lg包含以下对数的变量g:

for n = 1 : N
    for k = 1 : K
        lg(n, k) = log(lambda(k)) + sum(log(theta(k, :)) .* data(n, :));
    end
end
g = exp(lg);
g = bsxfun(@rdivide, g, sum(g, 2));
Run Code Online (Sandbox Code Playgroud)

到目前为止,没有任何成就.下溢只是从循环内转移到转换lgg后来通过指数.

但是,在下一行中有标准化步骤,这意味着正确的值g并非真正必要:所有重要的是不同的值在它们之间具有正确的比率.这意味着我们可以将所有共同进入归一化的值除以任意常数,而不改变最终结果.在对数刻度上,这意味着减去某些东西,我们选择这个东西作为算术平均值lg(对应于调和平均值g):

lg = bsxfun(@minus, lg, mean(lg, 2));
g = exp(lg);
g = bsxfun(@rdivide, g, sum(g, 2));
Run Code Online (Sandbox Code Playgroud)

通过减法,对数值从-2000(无法在指数下存活)移动到类似+50或-30的值.g现在的值是明智的,并且可以容易地归一化以达到正确的最终结果.