I would like to fit a mixture model in R, manually. Then, I would like to store the observation for each component of the mixture model separately. That is, I would like my code to retain the observations drawn from each component. Here is an example of a mixture model using the EM-algorithm from here.
I would like to know what are the observations of each mixture component. I need the value of these observations.
e_step <- function(x, mu.vector, sd.vector, alpha.vector) {
comp1.prod <- dnorm(x, mu.vector[1], sd.vector[1]) * alpha.vector[1]
comp2.prod <- dnorm(x, mu.vector[2], sd.vector[2]) * alpha.vector[2]
sum.of.comps <- comp1.prod + comp2.prod
comp1.post <- comp1.prod / sum.of.comps
comp2.post <- comp2.prod / sum.of.comps
sum.of.comps.ln <- log(sum.of.comps, base = exp(1))
sum.of.comps.ln.sum <- sum(sum.of.comps.ln)
list("loglik" = sum.of.comps.ln.sum,
"posterior.df" = cbind(comp1.post, comp2.post))
}
m_step <- function(x, posterior.df) {
comp1.n <- sum(posterior.df[, 1])
comp2.n <- sum(posterior.df[, 2])
comp1.mu <- 1/comp1.n * sum(posterior.df[, 1] * x)
comp2.mu <- 1/comp2.n * sum(posterior.df[, 2] * x)
comp1.var <- sum(posterior.df[, 1] * (x - comp1.mu)^2) * 1/comp1.n
comp2.var <- sum(posterior.df[, 2] * (x - comp2.mu)^2) * 1/comp2.n
comp1.alpha <- comp1.n / length(x)
comp2.alpha <- comp2.n / length(x)
list("mu" = c(comp1.mu, comp2.mu),
"var" = c(comp1.var, comp2.var),
"alpha" = c(comp1.alpha, comp2.alpha))
}
for (i in 1:50) {
if (i == 1) {
# Initialization
e.step <- e_step(wait, wait.summary.df[["mu"]], wait.summary.df[["std"]],
wait.summary.df[["alpha"]])
m.step <- m_step(wait, e.step[["posterior.df"]])
cur.loglik <- e.step[["loglik"]]
loglik.vector <- e.step[["loglik"]]
} else {
# Repeat E and M steps till convergence
e.step <- e_step(wait, m.step[["mu"]], sqrt(m.step[["var"]]),
m.step[["alpha"]])
m.step <- m_step(wait, e.step[["posterior.df"]])
loglik.vector <- c(loglik.vector, e.step[["loglik"]])
loglik.diff <- abs((cur.loglik - e.step[["loglik"]]))
if(loglik.diff < 1e-6) {
break
} else {
cur.loglik <- e.step[["loglik"]]
}
}
}
loglik.vector