1

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

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

结尾

4

1 回答 1

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));

因此,我们不是在一个额外的变量中累积分母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));

到目前为止,什么都没有实现。下溢只是从循环内移动到lg之后g的指数转换。

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

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

通过减法,对数值从 -2000 之类的东西(不能在指数中幸存)移动到 +50 或 -30 之类的东西。现在的值g是合理的,并且可以很容易地标准化以达到正确的最终结果。

于 2015-01-24T19:28:37.307 回答