[Depmix-commits] r313 - trunk
noreply at r-forge.r-project.org
noreply at r-forge.r-project.org
Sun Nov 29 19:42:57 CET 2009
Author: ingmarvisser
Date: 2009-11-29 19:42:56 +0100 (Sun, 29 Nov 2009)
New Revision: 313
Added:
trunk/start.R
Log:
Trial version of em.mix with start value generation
Added: trunk/start.R
===================================================================
--- trunk/start.R (rev 0)
+++ trunk/start.R 2009-11-29 18:42:56 UTC (rev 313)
@@ -0,0 +1,240 @@
+#
+# Maarten Speekenbrink 23-3-2008
+#
+
+em <- function(object,maxit=100,tol=1e-6,verbose=FALSE,...) {
+ if(!is(object,"mix")) stop("object is not of class '(dep)mix'")
+ call <- match.call()
+ if(is(object,"depmix")) {
+ call[[1]] <- as.name("em.depmix")
+ } else {
+ call[[1]] <- as.name("em.mix")
+ }
+ object <- eval(call, parent.frame())
+ object
+}
+
+# em for lca and mixture models
+em.mix <- function(object,maxit=100,tol=1e-6,verbose=FALSE,start=FALSE,...) {
+ if(!is(object,"mix")) stop("object is not of class 'mix'")
+
+ ns <- object at nstates
+
+ ntimes <- ntimes(object)
+ lt <- length(ntimes)
+ et <- cumsum(ntimes)
+ bt <- c(1,et[-lt]+1)
+
+ converge <- FALSE
+ j <- 0
+
+ # compute response probabilities
+ B <- apply(object at dens,c(1,3),prod)
+ gamma <- object at init*B
+ LL <- sum(log(rowSums(gamma)))
+ # normalize
+ gamma <- gamma/rowSums(gamma)
+
+ if(start) {
+ nr <- sum(ntimes(object))
+ snt <- nstates(object)
+ gamma <- matrix(runif(nr*snt),nr=nr,nc=snt)
+ gamma <- gamma/rowSums(gamma)
+ }
+
+ LL.old <- LL + 1
+
+ while(j <= maxit & !converge) {
+
+ # maximization
+
+ # should become object at prior <- fit(object at prior)
+ object at prior@y <- gamma[bt,,drop=FALSE]
+ object at prior <- fit(object at prior, w=NULL,ntimes=NULL)
+ object at init <- dens(object at prior)
+
+ for(i in 1:ns) {
+ for(k in 1:nresp(object)) {
+ object at response[[i]][[k]] <- fit(object at response[[i]][[k]],w=gamma[,i])
+ # update dens slot of the model
+ object at dens[,k,i] <- dens(object at response[[i]][[k]])
+ }
+ }
+
+ # expectation
+ B <- apply(object at dens,c(1,3),prod)
+ gamma <- object at init*B
+ LL <- sum(log(rowSums(gamma)))
+ # normalize
+ gamma <- gamma/rowSums(gamma)
+
+ # print stuff
+ if(verbose&((j%%5)==0)) {
+ cat("iteration",j,"logLik:",LL,"\n")
+ }
+
+ if( (LL >= LL.old) & (LL - LL.old < tol)) {
+ cat("iteration",j,"logLik:",LL,"\n")
+ converge <- TRUE
+ }
+
+ LL.old <- LL
+ j <- j+1
+
+ }
+
+ class(object) <- "mix.fitted"
+
+ if(converge) object at message <- "Log likelihood converged to within tol."
+ else object at message <- "'maxit' iterations reached in EM without convergence."
+
+ # no constraints in EM
+ object at conMat <- matrix()
+ object at lin.lower <- numeric()
+ object at lin.upper <- numeric()
+
+ object
+
+}
+
+# em for hidden markov models
+em.depmix <- function(object,maxit=100,tol=1e-6,verbose=FALSE,start=FALSE,...) {
+
+ if(!is(object,"depmix")) stop("object is not of class '(dep)mix'")
+
+ ns <- object at nstates
+
+ ntimes <- ntimes(object)
+ lt <- length(ntimes)
+ et <- cumsum(ntimes)
+ bt <- c(1,et[-lt]+1)
+
+ converge <- FALSE
+ j <- 0
+
+ # A <- object at trDens
+ # B <- object at dens
+ # init <- object at init
+
+ # initial expectation
+ fbo <- fb(init=object at init,A=object at trDens,B=object at dens,ntimes=ntimes(object),stationary=object at stationary)
+ LL <- fbo$logLike
+ LL.old <- LL + 1
+
+ if(start) {
+ nr <- sum(ntimes(object))
+ snt <- nstates(object)
+ fbo$gamma <- matrix(runif(nr*snt),nr=nr,nc=snt)
+ fbo$gamma <- fbo$gamma/rowSums(fbo$gamma)
+ }
+
+ while(j <= maxit & !converge) {
+
+ # maximization
+
+ # should become object at prior <- fit(object at prior)
+ object at prior@y <- fbo$gamma[bt,,drop=FALSE]
+ object at prior <- fit(object at prior, w=NULL,ntimes=NULL)
+ object at init <- dens(object at prior)
+
+ trm <- matrix(0,ns,ns)
+ for(i in 1:ns) {
+ if(max(ntimes(object)>1)) { # skip transition parameters update in case of latent class model
+ if(!object at stationary) {
+ object at transition[[i]]@y <- fbo$xi[,,i]/fbo$gamma[,i]
+ object at transition[[i]] <- fit(object at transition[[i]],w=as.matrix(fbo$gamma[,i]),ntimes=ntimes(object)) # check this
+ } else {
+ for(k in 1:ns) {
+ trm[i,k] <- sum(fbo$xi[-c(et),k,i])/sum(fbo$gamma[-c(et),i])
+ }
+ # FIX THIS; it will only work with a specific trinModel
+ object at transition[[i]]@parameters$coefficients <- object at transition[[i]]@family$linkfun(trm[i,],base=object at transition[[i]]@family$base)
+ }
+ # update trDens slot of the model
+ object at trDens[,,i] <- dens(object at transition[[i]])
+ }
+ }
+
+ for(i in 1:ns) {
+
+ for(k in 1:nresp(object)) {
+ object at response[[i]][[k]] <- fit(object at response[[i]][[k]],w=fbo$gamma[,i])
+ # update dens slot of the model
+ object at dens[,k,i] <- dens(object at response[[i]][[k]])
+ }
+ }
+
+ # expectation
+ fbo <- fb(init=object at init,A=object at trDens,B=object at dens,ntimes=ntimes(object),stationary=object at stationary)
+ LL <- fbo$logLike
+
+ if(verbose&((j%%5)==0)) cat("iteration",j,"logLik:",LL,"\n")
+ if( (LL >= LL.old) & (LL - LL.old < tol)) {
+ cat("iteration",j,"logLik:",LL,"\n")
+ converge <- TRUE
+ }
+
+ LL.old <- LL
+ j <- j+1
+
+ }
+
+ #if(class(object)=="depmix") class(object) <- "depmix.fitted"
+ #if(class(object)=="mix") class(object) <- "mix.fitted"
+
+ class(object) <- "depmix.fitted"
+
+ if(converge) object at message <- "Log likelihood converged to within tol."
+ else object at message <- "'maxit' iterations reached in EM without convergence."
+
+ # no constraints in EM
+ object at conMat <- matrix()
+ object at lin.lower <- numeric()
+ object at lin.upper <- numeric()
+
+ object
+}
+
+
+data(speed)
+
+# 2-state model on rt and corr from speed data set with Pacc as covariate on the transition matrix
+# starting values for the transition pars (without those EM does not get off the ground)
+set.seed(1)
+tr=runif(6)
+trst=c(tr[1:2],0,tr[3:5],0,tr[6])
+
+mod1 <- depmix(list(rt~1,corr~1),data=speed,transition=~Pacc,nstates=2,
+family=list(gaussian(),multinomial()))
+
+logLik(mod1)
+
+fm <- em(mod1,start=TRUE,verb=TRUE)
+
+data(balance)
+# four binary items on the balance scale task
+
+
+# note that ntimes argument is used to make this a mixture model
+mod4 <- mix(list(d1~1,d2~1,d3~1,d4~1), data=balance, nstates=2,
+ family=list(multinomial(),multinomial(),multinomial(),multinomial()))
+
+fmod4 <- em(mod4,start=T,verb=TRUE)
+
+
+# add age as covariate on class membership by using the prior argument
+instart=c(0.5,0.5,0,0) # we need the initial probs and the coefficients of age
+set.seed(2)
+respstart=runif(16)
+mod5 <- mix(list(d1~1,d2~1,d3~1,d4~1), data=balance, nstates=2,
+ family=list(multinomial(),multinomial(),multinomial(),multinomial()),
+ instart=instart, respstart=respstart, prior=~age, initdata=balance)
+
+fmod5 <- fit(mod5)
+
+mod5 <- mix(list(d1~1,d2~1,d3~1,d4~1), data=balance, nstates=2,
+ family=list(multinomial(),multinomial(),multinomial(),multinomial()),
+ prior=~age, initdata=balance)
+
+fm6 <- em(mod5,start=TRUE,verb=TRUE)
+
Property changes on: trunk/start.R
___________________________________________________________________
Name: svn:executable
+ *
Name: svn:eol-style
+ native
More information about the depmix-commits
mailing list