Contents
gmix.m
From A First Course in Machine Learning, Chapter 6. Simon Rogers, 01/11/11 [simon.rogers@glasgow.ac.uk] Fitting a Gaussian mixture
clear all;close all; path(path,'../utilities');
Load the data
load ../data/kmeansdata
Plot the data
figure(1);hold off plot(X(:,1),X(:,2),'ko');

Initilaise the mixture
K = 3; % Try changing this means = randn(K,2); for k = 1:K covs(:,:,k) = rand*eye(2); end priors = repmat(1/K,1,K);
Run the algorithm
MaxIts = 100; N = size(X,1); q = zeros(N,K); D = size(X,2); cols = {'r','g','b'}; plotpoints = [1:1:10,12:2:30 40 50]; B(1) = -inf; converged = 0; it = 0; tol = 1e-2; while 1
it = it + 1; % Update q for k = 1:K const = -(D/2)*log(2*pi) - 0.5*log(det(covs(:,:,k))); Xm = X - repmat(means(k,:),N,1); temp(:,k) = const - 0.5 * diag(Xm*inv(covs(:,:,k))*Xm'); end % Compute the Bound on the likelihood if it>1 B(it) = sum(sum(q.*log(repmat(priors,N,1)))) + ... sum(sum(q.*temp)) - ... sum(sum(q.*log(q))); if abs(B(it)-B(it-1))<tol converged = 1; end end if converged == 1 || it>MaxIts break end temp = temp + repmat(priors,N,1); q = exp(temp - repmat(max(temp,[],2),1,K)); % Minor hack for numerical issues - stops the code crashing when % clusters are empty q(q<1e-60) = 1e-60; q(q>1-1e-60) = 1e-60; q = q./repmat(sum(q,2),1,K); % Update priors priors = mean(q,1); % Update means for k = 1:K means(k,:) = sum(X.*repmat(q(:,k),1,D),1)./sum(q(:,k)); end % update covariances for k = 1:K Xm = X - repmat(means(k,:),N,1); covs(:,:,k) = (Xm.*repmat(q(:,k),1,D))'*Xm; covs(:,:,k) = covs(:,:,k)./sum(q(:,k)); end
Plot the current status
if any(it==plotpoints) figure(1);hold off % Note the following plots points using q as their RGB colour value for n = 1:N plot(X(n,1),X(n,2),'ko','markerfacecolor',q(n,:)); hold on end for k = 1:K plot_2D_gauss(means(k,:),covs(:,:,k),... -2:0.1:6,-6:0.1:6); end ti = sprintf('After %g iterations',it); title(ti) end












end
Plot the bound
figure(1);hold off plot(2:length(B),B(2:end),'k'); xlabel('Iterations'); ylabel('Bound');
