Mixture models contain many technical problems (symmetry when re-labeling components, etc.); if you don't have special needs, you might be better off using one of the many special-purpose modeling packages that were written for R (only library("sos"); findFn("{mixture model}")or findFn("{mixture model} Gaussian")).
, , / xsplit "" (.. ). , x1, x2 , , x1 x2 ( ). , , - , Nelder-Mead, . : (1) - (, = "SANN" optim()); (2) xsplit (.. xsplit, ); (3) (.. ); (4) , .
set.seed(1001)
library(bbmle)
x1 = rnorm(n=100,mean=4,sd=0.8)
x2 = rnorm(n=100,mean=12,sd=0.4)
x = c(x1,x2)
ff :
ff2 <- function(m1,m2,sd1,sd2,xsplit) {
p <- xvals<=xsplit
-sum(dnorm(xvals,mean=ifelse(p,m1,m2),
sd=ifelse(p,sd1,sd2),log=TRUE))
}
mo <- mle2(ff2,
start=list(m1=1,m2=2,sd1=0.1,sd2=0.1,xsplit=9),
data=list(xvals=x))
mo2 <- update(mo,start=list(m1=1,m2=2,sd1=0.1,sd2=0.1,xsplit=4))
plotfun <- function(mo,xvals=x,sizes=c(40,90)) {
c <- coef(mo)
hist(xvals,col="gray")
p <- xvals <= c["xsplit"]
y <- with(as.list(coef(mo)),
dnorm(xvals,mean=ifelse(p,m1,m2),
sd=ifelse(p,sd1,sd2))*sizes[ifelse(p,1,2)])
points(xvals,y,pch=20,cex=1.5,col=c("blue","red")[ifelse(p,1,2)])
}
plot(slice(mo),ylim=c(-0.5,10))
plot(slice(mo2),ylim=c(-0.5,10))
, xsplit:
xsplit=9:

xsplit=4:

. p. 243 Bolker 2008.
:
, , , . plogis() xsplit , 2 ( , , , ...) , , , x<xsplit 1, x>xsplit 2, , xsplit, 50/50 , 1, x xsplit. ; " ", , . ( , / 0 1, , ...)
; ( 0 0 1 ), . clamp() (plogis), 0 1 ; clamp() () , - NaN . , , ...
clamp <- function(x,lwr=0.001,upr=0.999) {
pmin(upr,pmax(lwr,x))
}
ff3 <- function(m1,m2,logsd1,logsd2,xsplit) {
p <- clamp(plogis(2*(xvals-xsplit)))
-sum(log((1-p)*clamp(dnorm(xvals,m1,exp(logsd1)),upr=Inf)+
p*clamp(dnorm(xvals,m2,exp(logsd2)),upr=Inf)))
}
xvals <- x
ff3(1,2,0.1,0.1,4)
mo3 <- mle2(ff3,
start=list(m1=1,m2=2,logsd1=-1,logsd2=-1,xsplit=4),
data=list(xvals=x))
.