Mixture of Two Univariate Normal Distributions
mix2normal.RdEstimates the five parameters of a mixture of two univariate normal distributions by maximum likelihood estimation.
Usage
mix2normal(lphi = "logitlink", lmu = "identitylink", lsd =
"loglink", iphi = 0.5, imu1 = NULL, imu2 = NULL, isd1 =
NULL, isd2 = NULL, qmu = c(0.2, 0.8), eq.sd = TRUE,
nsimEIM = 100, zero = "phi")Arguments
- lphi,lmu,lsd
Link functions for the parameters \(\phi\), \(\mu\), and \(\sigma\). See
Linksfor more choices.
- iphi
Initial value for \(\phi\), whose value must lie between 0 and 1.
- imu1, imu2
Optional initial value for \(\mu_1\) and \(\mu_2\). The default is to compute initial values internally using the argument
qmu.- isd1, isd2
Optional initial value for \(\sigma_1\) and \(\sigma_2\). The default is to compute initial values internally based on the argument
qmu. Currently these are not great, therefore using these arguments where practical is a good idea.- qmu
Vector with two values giving the probabilities relating to the sample quantiles for obtaining initial values for \(\mu_1\) and \(\mu_2\). The two values are fed in as the
probsargument intoquantile.- eq.sd
Logical indicating whether the two standard deviations should be constrained to be equal. If
TRUEthen the appropriate constraint matrices will be used.- nsimEIM
- zero
May be an integer vector specifying which linear/additive predictors are modelled as intercept-only. If given, the value or values can be from the set \(\{1,2,\ldots,5\}\). The default is the first one only, meaning \(\phi\) is a single parameter even when there are explanatory variables. Set
zero = NULLto model all linear/additive predictors as functions of the explanatory variables. SeeCommonVGAMffArgumentsfor more information.
Details
The probability density function can be loosely written as
$$f(y) = \phi \, N(\mu_1,\sigma_1) +
(1-\phi) \, N(\mu_2, \sigma_2)$$
where \(\phi\) is the probability an observation belongs
to the first group.
The parameters \(\mu_1\) and \(\mu_2\) are the
means, and \(\sigma_1\) and \(\sigma_2\) are the
standard deviations. The parameter \(\phi\) satisfies
\(0 < \phi < 1\).
The mean of \(Y\) is
\(\phi \mu_1 + (1-\phi) \mu_2\)
and this is returned as the fitted values.
By default, the five linear/additive predictors are
\((logit(\phi),\mu_1,\log(\sigma_1),\mu_2,\log(\sigma_2))^T\).
If eq.sd = TRUE then \(\sigma_1 = \sigma_2\)
is enforced.
Value
An object of class "vglmff"
(see vglmff-class).
The object is used by modelling functions
such as vglm,
and vgam.
References
McLachlan, G. J. and Peel, D. (2000). Finite Mixture Models. New York: Wiley.
Everitt, B. S. and Hand, D. J. (1981). Finite Mixture Distributions. London: Chapman & Hall.
Warning
Numerical problems can occur and
half-stepping is not uncommon.
If failure to converge occurs, try inputting better initial
values,
e.g., by using iphi,
qmu,
imu1,
imu2,
isd1,
isd2,
etc.
This VGAM family function is experimental and should be used with care.
Note
Fitting this model successfully to data can be difficult due to numerical problems and ill-conditioned data. It pays to fit the model several times with different initial values and check that the best fit looks reasonable. Plotting the results is recommended. This function works better as \(\mu_1\) and \(\mu_2\) become more different.
Convergence can be slow, especially when the two component
distributions are not well separated.
The default control argument trace = TRUE is to encourage
monitoring convergence.
Having eq.sd = TRUE often makes the overall optimization
problem easier.
Examples
if (FALSE) mu1 <- 99; mu2 <- 150; nn <- 1000
sd1 <- sd2 <- exp(3)
(phi <- logitlink(-1, inverse = TRUE))
#> [1] 0.2689414
rrn <- runif(nn)
mdata <- data.frame(y = ifelse(rrn < phi, rnorm(nn, mu1, sd1),
rnorm(nn, mu2, sd2)))
#> Error: object 'mu1' not found
fit <- vglm(y ~ 1, mix2normal(eq.sd = TRUE), data = mdata)
#> Error in eval(mf, parent.frame()): object 'mdata' not found
# Compare the results
cfit <- coef(fit)
#> Error in h(simpleError(msg, call)): error in evaluating the argument 'object' in selecting a method for function 'coef': object 'fit' not found
round(rbind('Estimated' = c(logitlink(cfit[1], inverse = TRUE),
cfit[2], exp(cfit[3]), cfit[4]),
'Truth' = c(phi, mu1, sd1, mu2)), digits = 2)
#> Error: object 'cfit' not found
# Plot the results
xx <- with(mdata, seq(min(y), max(y), len = 200))
#> Error: object 'mdata' not found
plot(xx, (1-phi) * dnorm(xx, mu2, sd2), type = "l", xlab = "y",
main = "red = estimate, blue = truth",
col = "blue", ylab = "Density")
#> Error in h(simpleError(msg, call)): error in evaluating the argument 'x' in selecting a method for function 'plot': object 'xx' not found
phi.est <- logitlink(coef(fit)[1], inverse = TRUE)
#> Error in h(simpleError(msg, call)): error in evaluating the argument 'object' in selecting a method for function 'coef': object 'fit' not found
sd.est <- exp(coef(fit)[3])
#> Error in h(simpleError(msg, call)): error in evaluating the argument 'object' in selecting a method for function 'coef': object 'fit' not found
lines(xx, phi*dnorm(xx, mu1, sd1), col = "blue")
#> Error: object 'xx' not found
lines(xx, phi.est * dnorm(xx, Coef(fit)[2], sd.est), col = "red")
#> Error: object 'xx' not found
lines(xx, (1-phi.est)*dnorm(xx, Coef(fit)[4], sd.est), col="red")
#> Error: object 'xx' not found
abline(v = Coef(fit)[c(2,4)], lty = 2, col = "red")
#> Error in h(simpleError(msg, call)): error in evaluating the argument 'object' in selecting a method for function 'Coef': object 'fit' not found
abline(v = c(mu1, mu2), lty = 2, col = "blue")
#> Error: object 'mu1' not found
# \dontrun{}