楼主: xinyusong00
9493 6

[有偿编程] 200个论坛币紧急求助利用MATLAB实现GMM模型的修改 [推广有奖]

  • 0关注
  • 6粉丝

硕士生

17%

还不是VIP/贵宾

-

威望
0
论坛币
17199 个
通用积分
1.5205
学术水平
8 点
热心指数
8 点
信用等级
8 点
经验
727 点
帖子
14
精华
0
在线时间
262 小时
注册时间
2014-5-6
最后登录
2024-4-8

200论坛币
  1. function varargout = gmm(X, K_or_centroids)
  2. % ============================================================
  3. % Expectation-Maximization iteration implementation of
  4. % Gaussian Mixture Model.
  5. %
  6. % PX = GMM(X, K_OR_CENTROIDS)
  7. % [PX MODEL] = GMM(X, K_OR_CENTROIDS)
  8. %
  9. %  - X: N-by-D data matrix.
  10. %  - K_OR_CENTROIDS: either K indicating the number of
  11. %       components or a K-by-D matrix indicating the
  12. %       choosing of the initial K centroids.
  13. %
  14. %  - PX: N-by-K matrix indicating the probability of each
  15. %       component generating each point.
  16. %  - MODEL: a structure containing the parameters for a GMM:
  17. %       MODEL.Miu: a K-by-D matrix.
  18. %       MODEL.Sigma: a D-by-D-by-K matrix.
  19. %       MODEL.Pi: a 1-by-K vector.
  20. % ============================================================

  21.     threshold = 1e-15;
  22.     [N, D] = size(X);

  23.     if isscalar(K_or_centroids)
  24.         K = K_or_centroids;
  25.         % randomly pick centroids
  26.         rndp = randperm(N);
  27.         centroids = X(rndp(1:K), :);
  28.     else
  29.         K = size(K_or_centroids, 1);
  30.         centroids = K_or_centroids;
  31.     end

  32.     % initial values
  33.     [pMiu pPi pSigma] = init_params();

  34.     Lprev = -inf;
  35.     while true
  36.         Px = calc_prob();

  37.         % new value for pGamma
  38.         pGamma = Px .* repmat(pPi, N, 1);
  39.         pGamma = pGamma ./ repmat(sum(pGamma, 2), 1, K);

  40.         % new value for parameters of each Component
  41.         Nk = sum(pGamma, 1);
  42.         pMiu = diag(1./Nk) * pGamma' * X;
  43.         pPi = Nk/N;
  44.         for kk = 1:K
  45.             Xshift = X-repmat(pMiu(kk, :), N, 1);
  46.             pSigma(:, :, kk) = (Xshift' * ...
  47.                 (diag(pGamma(:, kk)) * Xshift)) / Nk(kk);
  48.         end

  49.         % check for convergence
  50.         L = sum(log(Px*pPi'));
  51.         if L-Lprev < threshold
  52.             break;
  53.         end
  54.         Lprev = L;
  55.     end

  56.     if nargout == 1
  57.         varargout = {Px};
  58.     else
  59.         model = [];
  60.         model.Miu = pMiu;
  61.         model.Sigma = pSigma;
  62.         model.Pi = pPi;
  63.         varargout = {Px, model};
  64.     end

  65.     function [pMiu pPi pSigma] = init_params()
  66.         pMiu = centroids;
  67.         pPi = zeros(1, K);
  68.         pSigma = zeros(D, D, K);

  69.         % hard assign x to each centroids
  70.         distmat = repmat(sum(X.*X, 2), 1, K) + ...
  71.             repmat(sum(pMiu.*pMiu, 2)', N, 1) - ...
  72.             2*X*pMiu';
  73.         [dummy labels] = min(distmat, [], 2);

  74.         for k=1:K
  75.             Xk = X(labels == k, :);
  76.             pPi(k) = size(Xk, 1)/N;
  77.             pSigma(:, :, k) = cov(Xk);
  78.         end
  79.     end

  80.     function Px = calc_prob()
  81.         Px = zeros(N, K);
  82.         for k = 1:K
  83.             Xshift = X-repmat(pMiu(k, :), N, 1);
  84.             inv_pSigma = inv(pSigma(:, :, k)+eye(D));
  85.             tmp = sum((Xshift*inv_pSigma) .* Xshift, 2);
  86.             coef = (2*pi)^(-D/2) * sqrt(det(inv_pSigma));
  87.             Px(:, k) = coef * exp(-0.5*tmp);
  88.         end
  89.     end
  90. end
复制代码


MATLAB代码如上,第96行在执行时会出现
警告: 矩阵接近奇异值,或者缩放错误。结果可能不准确。RCOND =  1.718855e-21。
> In gmm>calc_prob at 96
  In gmm at 40
  In gmm_accuracy at 4


代码是从这个网页获取的:http://blog.pluskid.org/?p=39&cpage=1#comments
关于这个问题也有相关的分析和解释:http://freemind.pluskid.org/mach ... ariance-estimation/

我不要求搞懂原理,只需要代码能够运行就好!
200个论坛币悬赏

最佳答案

Yafey 查看完整内容

楼主你好~我目前也遇到了这个问题。经过改错后已经可以运行: 问题原因:代码中没有处理singular问题 改正: 加几句代码,处理singular问题 把你第96行的function换成这个就好 function Px = calc_prob() Px = zeros(N, K); for k = 1:K Xshift = X-repmat(pMiu(k, : ), N, 1);%x-u lemda=1e-5; conv=pSigma(:, :, k)+lemda*diag(diag(ones(D)));%这里处理singular问 ...
关键词:matlab实现 MATLAB atlab GMM模型 matla 模型 function choosing initial either

本帖被以下文库推荐

沙发
Yafey 发表于 2015-2-8 13:43:03 |只看作者 |坛友微信交流群
楼主你好~我目前也遇到了这个问题。经过改错后已经可以运行:
问题原因:代码中没有处理singular问题
改正: 加几句代码,处理singular问题
把你第96行的function换成这个就好
function Px = calc_prob()
        Px = zeros(N, K);
        for k = 1:K
            Xshift = X-repmat(pMiu(k, : ), N, 1);%x-u
            lemda=1e-5;
            conv=pSigma(:, :, k)+lemda*diag(diag(ones(D)));%这里处理singular问题,为协方差矩阵加上一个很小lemda*I
            inv_pSigma = inv(conv);%协方差的逆
            tmp = sum((Xshift*inv_pSigma) .* Xshift, 2);%(X-U_k)sigma.*(X-U_k),tmp是个N*1的向量
            coef = (2*pi)^(-D/2) * sqrt(det(inv_pSigma));%前面的参数
            Px(:, k) = coef * exp(-0.5*tmp);%把数据点 x 带入到 Gaussian model 里得到的值
        end
    end
end

200。。请拿来啊~~

使用道具

藤椅
magicsun 发表于 2015-2-8 13:52:50 |只看作者 |坛友微信交流群
改成pinv
就行了
给我两百吧!

使用道具

板凳
xinyusong00 在职认证  发表于 2015-2-8 14:19:29 |只看作者 |坛友微信交流群
magicsun 发表于 2015-2-8 13:52
改成pinv
就行了
给我两百吧!
试过,
错误使用 svd
SVD 的输入不能包含 NaN 或 Inf。

出错 pinv (line 18)
[U,S,V] = svd(A,'econ');

出错 gmm/calc_prob (line 96)
            inv_pSigma = pinv(pSigma(:, :, k)+eye(D));

出错 gmm (line 40)
        Px = calc_prob();

使用道具

报纸
xinyusong00 在职认证  发表于 2015-2-8 14:30:56 |只看作者 |坛友微信交流群
悬赏还可以再增加,只要能解决问题!

使用道具

我跑DSGE的过程中遇到了同样的问题,不知道是MATLAB版本的问题还是咋滴啊

使用道具

7
zhouyuehua 发表于 2018-11-24 13:25:12 |只看作者 |坛友微信交流群
我在跑这个代码的时候也遇到了这个文题,不知道解决了没有啊

使用道具

您需要登录后才可以回帖 登录 | 我要注册

本版微信群
加好友,备注cda
拉您进交流群

京ICP备16021002-2号 京B2-20170662号 京公网安备 11010802022788号 论坛法律顾问:王进律师 知识产权保护声明   免责及隐私声明

GMT+8, 2024-5-2 05:42