forked from PRML/PRMLT
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmixDpGb.m
47 lines (46 loc) · 1.46 KB
/
mixDpGb.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
function [label, Theta, w, llh] = mixDpGb(X, alpha, theta)
% Collapsed Gibbs sampling for Dirichlet process (infinite) mixture model.
% Any component model can be used, such as Gaussian.
% Input:
% X: d x n data matrix
% alpha: parameter for Dirichlet process prior
% theta: class object for prior of component distribution (such as Gauss)
% Output:
% label: 1 x n cluster label
% Theta: 1 x k structure of trained components
% w: 1 x k component weight vector
% llh: loglikelihood
% Written by Mo Chen ([email protected]).
n = size(X,2);
[label,Theta,w] = mixDpGbOl(X,alpha,theta);
nk = n*w;
maxIter = 200;
llh = zeros(1,maxIter);
for iter = 1:maxIter
for i = randperm(n)
x = X(:,i);
k = label(i);
Theta{k} = Theta{k}.delSample(x);
nk(k) = nk(k)-1;
if nk(k) == 0 % remove empty cluster
Theta(k) = [];
nk(k) = [];
which = label>k;
label(which) = label(which)-1;
end
Pk = log(nk)+cellfun(@(t) t.logPredPdf(x), Theta);
P0 = log(alpha)+theta.logPredPdf(x);
p = [Pk,P0];
llh(iter) = llh(iter)+sum(p-log(n));
k = discreteRnd(exp(p-logsumexp(p)));
if k == numel(Theta)+1 % add extra cluster
Theta{k} = theta.clone.addSample(x);
nk = [nk,1];
else
Theta{k} = Theta{k}.addSample(x);
nk(k) = nk(k)+1;
end
label(i) = k;
end
end
w = nk/n;