Modeling a Gaussian mixture with mle2 / optim

I have a model mle2that I developed here to demonstrate this problem. I generate values ​​from two separate Gaussian distributions x1and x2, combining them together to form x=c(x1,x2), and then create an MLE that tries to reclassify the values xas belonging to the left edge of a specific xvalue or right to a specific value xusing a parameter xsplit.

The problem is that the parameters found are not ideal. In particular, it xsplitalways returns as any of its initial values. And if I change my initial value (for example, as 4 or 9), then there will be big differences in the probabilistic probability of the journal.

Here is a fully reproducible example:

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)
hist(x,breaks=20)
ff = function(m1,m2,sd1,sd2,xsplit) {
  outs = rep(NA,length(xvals))
  for(i in seq(1,length(xvals))) {
    if(xvals[i]<=xsplit) {
      outs[i] = dnorm(xvals[i],mean=m1,sd=sd1,log=T)
    }
    else {
      outs[i] = dnorm(xvals[i],mean=m2,sd=sd2,log=T)
    }
  }
  -sum(outs)
}

# change xsplit starting value here to 9 and 4
# and realize the difference in log likelihood
# Why isn't mle finding the right value for xsplit?
mo = mle2(ff,
          start=list(m1=1,m2=2,sd1=0.1,sd2=0.1,xsplit=9), 
          data=list(xvals=x))

#print mo to see log likelihood value
mo

#plot the result
c=coef(mo)
m1=as.numeric(c[1])
m2=as.numeric(c[2])
sd1=as.numeric(c[3])
sd2=as.numeric(c[4])
xsplit=as.numeric(c[5])
leftx = x[x<xsplit]
rightx = x[x>=xsplit]
y1=dnorm(leftx,mean=m1,sd=sd1)
y2=dnorm(rightx,mean=m2,sd=sd2)
points(leftx,y1*40,pch=20,cex=1.5,col="blue")
points(rightx,y2*90,pch=20,cex=1.5,col="red")

How can I change my mle2 to fix the correct parameters, especially for xsplit?

+4
source share
1 answer

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 :

## ff can be written more compactly:
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))
}

## ML estimation
mo <- mle2(ff2,
           start=list(m1=1,m2=2,sd1=0.1,sd2=0.1,xsplit=9), 
           data=list(xvals=x))

## refit with a different starting value for xsplit
mo2 <- update(mo,start=list(m1=1,m2=2,sd1=0.1,sd2=0.1,xsplit=4))

## not used here, but maybe handy
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 = 9

xsplit=4:

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 . , , ...

 ## bound x values between lwr and upr
 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))
 ## Coefficients:
 ##          m1          m2      logsd1      logsd2      xsplit 
 ##  3.99915532 12.00242510 -0.09344953 -1.13971551  8.43767997 

.

+8

Source: https://habr.com/ru/post/1525817/


All Articles