简化 EM 的公式

simplifying the formula for EM

我想在 Matlab 中计算以下公式(多项混合模型的 EM 的 E 步),

g和θ是矩阵,θ和λ有以下约束:


但是 m 的计数超过 1593,当计算 θ 的乘积时,数字变得非常小,Matlab 将其保存为零。 任何人都可以简化 g 公式或使用其他技巧来解决这个问题?

更新:

数据: 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

结束

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

首先,我们稍微重新格式化 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));

因此,我们没有将分母累加到一个额外的变量中 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));

到目前为止,一无所获。下溢只是从循环内移动到之后通过指数从 lgg 的转换。

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

lg = bsxfun(@minus, lg, mean(lg, 2));
g = exp(lg);
g = bsxfun(@rdivide, g, sum(g, 2));

通过减法,对数值从 -2000 之类的值移动到 +50 或 -30 之类的值,它在指数中不存在。 g 的值现在是合理的,可以很容易地归一化以达到正确的最终结果。