# GMM model
# 2015/7/22
library(mvtnorm)
set.seed(1)
n1 = 1000
n2 = 1000
mu1 = c(0,1)
mu2 = c(-5,-6)
sigma1 = matrix(c(1,.5,.5,2),nrow=2)
sigma2 = matrix(c(2,.5,.5,1),nrow=2)
y1 = rep(1,n1)
y2 = rep(2,n2)
x1 = rmvnorm(n1, mean=mu1, sigma=sigma1)
x2 = rmvnorm(n2, mean=mu2, sigma=sigma2)
x = rbind(x1,x2)
y = rbind(y1,y2)
ns = 2
ngrid = 100
mv.gauss = function(x,y,mu,sigma)
{
nx = length(x)
ny = length(y)
z = matrix(0,nrow=ny, ncol=nx)
sigma_inv = solve(sigma)
det_sigma = det(sigma)
for (i in 1:nx){
for (j in 1:ny){
z[i,j] = 1/(2*pi*sqrt(det_sigma)) * exp(-t(c(x[i], y[j]) - mu) %*% sigma_inv %*% t(t(c(x[i], y[j]) - mu)))
}
}
return(z)
}
gauss_density = function(x,mu,sigma)
{
nx = length(x)
ny = length(y)
z = matrix(0,nrow=ny, ncol=nx)
sigma_inv = solve(sigma)
det_sigma = det(sigma)
value = 1/(2*pi*sqrt(det_sigma)) * exp(-1/2* t(x - mu) %*% sigma_inv %*% t(t(x - mu)))
return(value)
}
plot_contour = function(ngrid, ns, mv.gauss, mu1,sigma1,mu2,sigma2){
x.range1 = seq(mu1[1]-ns*sigma1[1],mu1[1]+ns*sigma1[1],length.out=ngrid)
y.range1 = seq(mu1[2]-ns*sigma1[4],mu1[2]+ns*sigma1[4],length.out=ngrid)
x.range2 = seq(mu2[1]-ns*sigma2[1],mu2[1]+ns*sigma2[1],length.out=ngrid)
y.range2 = seq(mu2[2]-ns*sigma2[4],mu1[2]+ns*sigma2[4],length.out=ngrid)
z1 = mv.gauss(x.range1, y.range1, mu1, sigma1)
z2 = mv.gauss(x.range2, y.range2, mu2, sigma2)
contour(x.range1, y.range1, z1, add=TRUE,col="red", lwd = 3)
contour(x.range2, y.range2, z2, add=TRUE,col="blue", lwd = 3)
}
plot_iter = function(ngrid,x1,x2,mv.gauss, mu1,sigma1,mu2,sigma2, iter=1){
x = rbind(x1,x2)
plot(x[,1], x[,2], type='p',
main=sprintf("Iter %d: mu1=(%.2f, %.2f)/(-5,-6) mu2=(%.2f, %.2f)/(0,1)",
iter, mu1[1],mu1[2], mu2[1], mu2[2]))
points(mu1[1], mu1[2], col='red', pch=15)
points(mu2[1], mu2[2], col='blue', pch=15)
plot_contour(ngrid,4,mv.gauss, mu1,sigma1,mu2,sigma2)
}
obj_value = function(x,phi, mu1, sigma1, mu2, sigma2){
n = dim(x)[1]
res = 0
for (i in i:n){
res = res + log(phi[1]*gauss_density(x[i,], mu1, sigma1)+phi[2]*gauss_density(x[i,], mu2, sigma2))
}
return(res)
}
plot_iter(ngrid,x1,x2,mv.gauss, mu1,sigma1,mu2,sigma2)
mu1_i = c(0,0)
mu2_i = c(1,0)
sigma1_i = matrix(c(1,0,0,1),nrow=2)
sigma2_i = matrix(c(1,0,0,1),nrow=2)
plot_iter(ngrid,x1,x2,mv.gauss, mu1_i,sigma1_i,mu2_i,sigma2_i,0)
n = n1+n2
w = array(0,dim=c(n,2))
phi1 = 0.5
phi2 = 0.5
num_iter = 12
obj_val = rep(0,num_iter)
for (ii in 1:num_iter){
# E-step
for (i in 1:n){
w[i,1] = phi1 * gauss_density(x[i,], mu1_i, sigma1_i)
w[i,2] = phi2 * gauss_density(x[i,], mu2_i, sigma2_i)
tmp = sum(w[i,])
w[i,1] = w[i,1] / tmp
w[i,2] = w[i,2] / tmp
}
# M-step
phi1 = mean(w[,1])
phi2 = mean(w[,2])
mu1_i = colSums(w[,1]*x) / sum(w[,1])
mu2_i = colSums(w[,2]*x) / sum(w[,2])
tmp = matrix(0,nrow=2,,ncol=2)
mu = mu1_i
for (i in 1:n){
tmp = tmp + w[i,1] * (t(t(x[i,] - mu)) %*% t(x[i,] - mu))
}
sigma1_i = tmp / sum(w[,1])
tmp = matrix(0,nrow=2,ncol=2)
mu = mu2_i
for (i in 1:n){
tmp = tmp + w[i,2] * (t(t(x[i,] - mu)) %*% t(x[i,] - mu))
}
sigma2_i = tmp / sum(w[,2])
plot_iter(ngrid,x1,x2,mv.gauss, mu1_i,sigma1_i,mu2_i,sigma2_i, ii)
obj_val[ii] = obj_value(x,c(phi1,phi2), mu1_i,sigma1_i, mu2_i, sigma2_i)
}
plot(obj_val,type="l",main="Objective function: log likelihood",xlab="#Iteration")
print(c(phi1, phi2))
print(sigma1_i)
print(sigma2_i)