Lecture 21 EM in R

This is the R session for week 7. In lecture 19 the EM algorithm was introduced and an ascent property was proved. In example 19.4 the E and M steps were illustrated for a two-component normal mixture. Today we will type the two steps into R functions, check the functions against the hand computation from the example, and then run the functions on a simulated sample of size 200200. We will conclude by considering the problem of label switching and the effect of a bad start. The written reference for this session is appendix B.

21.1 The E and M Steps as R Functions

Throughout, the parameter is the vector θ=(π,μ1,μ2)\theta=(\pi,\mu_{1},\mu_{2}) and the common standard deviation σ\sigma is known. The E step of example 19.4 computes the responsibilities γi\gamma_{i}, the M step computes the updates (19.2), and both involve only vector arithmetic. The function dnorm is also used to compute the normal density. We also need to compute the observed-data log-likelihood ℓ\ell. By theorem 19.2, this must increase.

resp <- function(x, theta, sigma) {
a <- theta[1] * dnorm(x, mean = theta[2], sd = sigma)
b <- (1 - theta[1]) * dnorm(x, mean = theta[3], sd = sigma)
a / (a + b)
}
mstep <- function(x, gamma) {
c(mean(gamma),
sum(gamma * x) / sum(gamma),
sum((1 - gamma) * x) / sum(1 - gamma))
}
loglik <- function(x, theta, sigma) {
sum(log(theta[1] * dnorm(x, mean = theta[2], sd = sigma) +
(1 - theta[1]) * dnorm(x, mean = theta[3], sd = sigma)))
}

We first test our function on the data from example 19.4. For this we use the five observations x=(0,1,5,6,7)x=(0,1,5,6,7) where σ=1\sigma=1 and initial value θ0=(1/2,2,4)\theta_{0}=(1/2,2,4). The results of one iteration of the algorithm are then compared to the responsibilities and iterate θ1\theta_{1} and to the two values for the log-likelihood computed by hand.

x <- c(0, 1, 5, 6, 7)
theta <- c(0.5, 2, 4)
gamma <- resp(x, theta, 1)
round(gamma, 4)
theta1 <- mstep(x, gamma)
theta1
c(loglik(x, theta, 1), loglik(x, theta1, 1))
## [1] 0.9975 0.9820 0.0180 0.0025 0.0003
## [1] 0.4000671 0.5444727 5.9709581
## [1] -17.518842 -9.212934

Everything agrees with the hand computation (μ2,1\mu_{2,1} differs in the last digit because the example rounded the intermediate sums), and the last line is the check for exercise 19.3. We now iterate, keeping the parameter and the log-likelihood after each step in a matrix. Before you run the loop, predict the log-likelihood after the second iteration: far above −9.21-9.21, slightly above it, or equal to it?

theta <- c(0.5, 2, 4)
path <- matrix(0, nrow = 4, ncol = 4,
dimnames = list(1:4, c("pi", "mu1", "mu2", "loglik")))
for (k in 1:4) {
theta <- mstep(x, resp(x, theta, 1))
path[k, ] <- c(theta, loglik(x, theta, 1))
}
round(path, 4)
## pi mu1 mu2 loglik
## 1 0.4001 0.5445 5.971 -9.2129
## 2 0.4000 0.5001 6.000 -9.2097
## 3 0.4000 0.5001 6.000 -9.2097
## 4 0.4000 0.5001 6.000 -9.2097

The second iteration gains only 0.0030.003, and after it nothing moves: the responsibilities are so close to 0 and 11 that each mean is the mean of its own group, and the iteration has reached its fixed point, a root of the likelihood equation by proposition 19.3.

21.2 A Larger Sample

Convergence in two steps is a consequence of the large difference between the two groups. Here we simulate a sample where the groups overlap. We can simulate such a sample by first randomly choosing a group, using rbinom to get Zi=1Z_{i}=1 with probability π=0.3\pi=0.3. We then simulate the measurements from the normal distribution corresponding to the group, i.e. with means 0 and 33 and σ=1\sigma=1. The command ifelse can be used to choose the correct mean for each observation. The box below contains the complete script for simulation and EM iteration, with lines shuffled (except for the body of the loop). Before you can run the script, you have to arrange these lines into a working script. The loop finishes when the log-likelihood increases by less than 10−810^{-8}, as described in section 19.5. The vector ll stores the log-likelihood after each iteration, with the initial value at position 11.

theta <- c(0.5, q[1], q[2])
for (k in 1:1000) {
theta <- mstep(x, resp(x, theta, 1))
ll[k + 1] <- loglik(x, theta, 1)
if (ll[k + 1] - ll[k] < 1e-8) break
}
z <- rbinom(n, size = 1, prob = 0.3)
n <- 200
q <- quantile(x, c(0.25, 0.75), names = FALSE)
set.seed(2026)
ll <- loglik(x, theta, 1)
x <- rnorm(n, mean = ifelse(z == 1, 0, 3), sd = 1)

The rule is the one from lecture 9: each line must come after all lines on which it depends, so the order of lines must be seed, n, z and x, quartiles q, start value, first entry of ll, and then the loop. The start values are chosen such that the weight is at 1/21/2 and the two means are at the two quartiles. This is a cheap way to split the sample into two groups. Before you try the script, try to answer the following two questions: How many iterations will the loop take? (In the hand example from lecture, two iterations were needed.) Will the values for the log-likelihood increase by the same amount in each iteration, or differently?

table(z)
k
round(theta, 4)
round(ll[1:6], 3)
round(ll[k + 1], 3)
## z
## 0 1
## 152 48
## [1] 28
## [1] 0.2397 0.2202 3.0761
## [1] -375.257 -370.274 -365.880 -362.046 -359.040 -356.973
## [1] -354.505

The fixed point θ^=(0.240,0.220,3.076)\hat{\theta}=(0.240,0.220,3.076) recovers the true group-1 proportion 48/200=0.2448/200=0.24 and the two means to within about two tenths. The loop required 2828 iterations, because the responsibilities of the two means were far away from 0 and 11 and because in each iteration the means were only slightly changed. The recorded values are increasing with each iteration, as theorem 19.2 guarantees, but at decreasing rates: 5.05.0, then 4.44.4, 3.83.8, 3.03.0, 2.12.1, as predicted by the geometric convergence of section 19.5. By proposition 19.3 the fixed point is a root of the likelihood equation. To test this, we can use optim, as shown in lecture 18, by maximising loglik with the same starting values as we used in the EM algorithm. If we use the command hessian = TRUE, we can get the standard errors from section 17.3. (The EM algorithm does not provide the standard errors.)

fit <- optim(c(0.5, q[1], q[2]), function(par) -loglik(x, par, 1),
hessian = TRUE)
round(fit$par, 4)
round(sqrt(diag(solve(fit$hessian))), 4)
## [1] 0.2397 0.2202 3.0761
## [1] 0.0383 0.1965 0.0961

The two methods agree to four decimal places, and the standard errors say that the fitted weight is 0.240±0.0380.240\pm 0.038, with the smaller group’s mean determined only half as well as the larger group’s. At the fixed point the responsibility of group 1 is a decreasing function of xx which equals 1/21/2 where π⁢φσ⁢(x−μ1)=(1−π)⁢φσ⁢(x−μ2)\pi\varphi_{\sigma}(x-\mu_{1})=(1-\pi)\varphi_{\sigma}(x-\mu_{2}). Before you look at figure 21.1, predict where the crossing lies: at the midpoint 1.651.65 of the two fitted means, or above or below this point?

gamma <- resp(x, theta, 1)
half <- (theta[3]^2 - theta[2]^2) / (2 * (theta[3] - theta[2])) +
log(theta[1] / (1 - theta[1])) / (theta[3] - theta[2])
round(half, 3)
plot(x, gamma, pch = ifelse(z == 1, 16, 1), xlab = "x",
ylab = "responsibility of group 1")
## [1] 1.244
Two panels. Top: histogram of 200 observations with
modes at 0.22 and 3.08, together with the fitted mixture density
(solid line) and its two weighted components (dashed lines). Bottom:
Responsibilities as a function of x, showing an S-shaped curve which
decreases from 1 to 0. The curve crosses the level 1/2 at x = 1.244
(dotted lines). Filled points on the left, open points on the
right, both mixed between 0.7 and 1.6.
Figure 21.1: The fitted mixture density with its two weighted components (top panel) and the responsibilities of group 1 at the fixed point as a function of the observations (bottom panel). The filled circles give the observations which were assigned to group 1. The dotted lines give the responsibility 1/21/2 and the crossing point 1.2441.244.

The crossing happens at 1.2441.244, well below the mid-point 1.6481.648, since the weights are unequal: an observation which is half-way between the means has three times the probability of being from the larger group. The filled and open circles give the true group of each observation, which cannot be known by EM: the responsibilities agree with the truth when the observations are far away from the crossing point, but between 0.70.7 and 1.61.6 both types of observations can be found and the group cannot be decided. The top panel is also plotted using the script R/S21-mixture.R; the three functions are given in R/S21-hand.R.

21.3 Label Switching and a Bad Start

Section 19.5 lists two ways in which a start can lead EM astray; both cases are represented in the sample. The script R/S21-starts.R encapsulates the loop as a function em and then runs this function with four different starts: the quartile start, the start with the two means swapped, the start (1/2,3,3)(1/2,3,3) with both means equal, and the start (1/2,2.39,2.41)(1/2,2.39,2.41) with nearly equal means. Before you look at the table, predict the outcome of each row. Where does the start with the swapped means end up? What is the log-likelihood there? What happens to the responsibilities when μ1=μ2\mu_{1}=\mu_{2} and thus to the next update?

good <- em(x, c(0.5, q[1], q[2]), 1)
swapped <- em(x, c(0.5, q[2], q[1]), 1)
equal <- em(x, c(0.5, 3, 3), 1)
near <- em(x, c(0.5, 2.39, 2.41), 1)
## pi mu1 mu2 loglik iterations
## good 0.2397 0.2202 3.0761 -354.5046 28
## swapped 0.7603 3.0761 0.2202 -354.5046 28
## equal 0.5000 2.3915 2.3915 -421.8067 2
## near 0.2397 0.2202 3.0761 -354.5046 33

The start with swapped means ends in the mirror image (0.760,3.076,0.220)(0.760,3.076,0.220) after the same 2828 iterations and with the same log-likelihood: both parameter values lead to the same density, the model is not identifiable in the sense of definition 4.10 and the choice of labelling in the start determines which of the two maxima we reach. The start with equal parameters is the trap. In this case, with μ1=μ2\mu_{1}=\mu_{2}, the two normal densities in the responsibility cancel, all γi\gamma_{i} are equal to π\pi and the M step sets both means equal to the sample mean while leaving the weight unchanged; another step does not change anything and the loop stops after two iterations at (1/2,2.3915,2.3915)(1/2,2.3915,2.3915), effectively a single normal distribution, with a log-likelihood 6767 below the maximum. Theorem 19.2 is not violated: the log-likelihood did not decrease but failed to increase. The resulting resting point is a root of the likelihood equation, by proposition 19.3, but a saddle point instead of a maximum and thus EM will not be able to distinguish between the two. The nearly equal start shows that the trap is narrow: the iteration moves away from the saddle point and then climbs to the maximum, in 3333 iterations, as shown in figure 21.2 for the three traces.

Log-likelihood as a function of iteration number.
The thick, solid curve starts at -375 and gradually flattens to
-354.5. The process ends after iteration 28. The dotted curve
starts at -422, is constant for the first two iterations, and
then increases to the same plateau as the solid curve does. The
process ends in iteration 33. The dash-dotted line with crosses
starts at -459, jumps to -422 in the first iteration, and ends in
iteration~2.
Figure 21.2: Log-likelihood of the given data as a function of the iteration number for the EM algorithm, for the start with quartile-spaced means (solid line), for the start with nearly equal means (dotted line) and for the start with equal means (dash-dotted line with crosses). The trace of the start with interchanged means coincides with the solid line.

For this model, with known common variance, a grid of hundreds of starting values finds only the two mirror-image maxima and the saddle line μ1=μ2\mu_{1}=\mu_{2} as stable solutions. In contrast, if the variances were unknown or if there were three or more components, additional local maxima would occur and the procedure from section 19.5 of starting the EM algorithm with several runs and then choosing the run with the highest observed-data log-likelihood becomes essential. For a two-component mixture, the twelve lines of resp, mstep and loglik are all we need. For serious work there are packages: mclust fits mixtures of this kind, and requireNamespace("mclust", quietly = TRUE) reports whether it is installed. Nothing in this session relies on it.

21.4 A Task to Take Home

The following task is in the style of a practical report. The published scripts of this lecture can be used as a starting point. Using your student ID as the seed, choose a weight π\pi between 0.20.2 and 0.50.5, and choose two means which are two to three units apart. Simulate one sample of size n=300n=300 from the mixture with σ=1\sigma=1. Run the EM algorithm with three different starting values (the quartile start and two of your choice) and show the fixed point, log-likelihood and number of iterations for each run in a table. Justify which run you would keep and mention if label switching occurred. Finally, use optim with hessian = TRUE to estimate the standard errors for the kept run. For each parameter, show the estimate, the standard error and the interval θ^±1.96⁢se(θ^)\hat{\theta}\pm 1.96\,\mathop{\mathrm{se}}\nolimits(\hat{\theta}) from corollary 17.3, in three sentences. For each sentence, state whether the interval contains the value you chose. Plot the responsibilities against the data. Write a short paragraph about how many observations have responsibility values between 0.20.2 and 0.80.8. Comment on how well-separated the two groups are in your plot. Finally, repeat the whole exercise with the two means only one unit apart, and say in one sentence what changes.

Typing the commands yourself is an important step towards understanding how the R scripts work. Before the next session, please type in the commands from this session, and check that you get the same results as shown in the text.

Summary.
  • •
    ​

    The written reference for the R code in this session is appendix B.

  • •
    ​

    The E-step and M-step from example 19.4 involve only a few lines of vector arithmetic. For five observations, these lines can reproduce the manual computation, and the algorithm converges to the fixed point in two steps.

  • •
    ​

    For a sample of size 200200 with overlapping groups, it takes 2828 iterations for EM to converge. The log-likelihood increases in every step, by increasingly small amounts as required by theorem 19.2. The optim function finds the same fixed point as the manual calculation, as predicted by proposition 19.3, and optim can be used to compute the standard errors.

  • •
    ​

    The responsibility of group 1 is a decreasing S-shaped function of xx. The function crosses 1/21/2 below the mid-point of the means when group 1 is the smaller group. Close to the crossing point it is no longer possible to decide which group a sample belongs to.

  • •
    ​

    If the labels are swapped before starting the EM algorithm, the algorithm converges to the mirror-image maximum with the same log-likelihood. If the two groups have the same mean, the EM algorithm converges to a saddle point immediately, i.e. a root of the likelihood equation which is not a maximum. To avoid this, the EM algorithm should be started with different values and the best of the resulting runs should be chosen, based on the log-likelihood of the observed data.