Can OpenMx fit Factor Mixture Models (FMM)?
Posted on

Dear Users and Maintainers,
Have you used OpenMx to fit Factor Mixture Models (FMM)? I saw that feature in Mplus but I couldn't figure out whether OpenMx can do it or not. Hence the question. Guidance on how to fit FMM using OpenMx would be much appreciated.
FMM
Log in or register to post comments
Example GMM
The latest version of the demo script is run-able with
require(OpenMx)
demo(package='OpenMx', 'GrowthMixtureModel_PathRaw')
Here' the code for inspection.
# -----------------------------------------------------------------------------
require(OpenMx)
# Load Libraries
# -----------------------------------------------------------------------------
data(myGrowthMixtureData)
# Prepare Data
# -----------------------------------------------------------------------------
# residual variances
resVars <- mxPath( from=c("x1","x2","x3","x4","x5"), arrows=2,
free=TRUE, values = c(1,1,1,1,1),
labels=c("residual","residual","residual","residual","residual") )
# latent variances and covariance
latVars <- mxPath( from=c("intercept","slope"), arrows=2, connect="unique.pairs",
free=TRUE, values=c(1,.4,1), labels=c("vari1","cov1","vars1") )
# intercept loadings
intLoads <- mxPath( from="intercept", to=c("x1","x2","x3","x4","x5"), arrows=1,
free=FALSE, values=c(1,1,1,1,1) )
# slope loadings
sloLoads <- mxPath( from="slope", to=c("x1","x2","x3","x4","x5"), arrows=1,
free=FALSE, values=c(0,1,2,3,4) )
# manifest means
manMeans <- mxPath( from="one", to=c("x1","x2", "x3", "x4","x5"), arrows=1,
free=FALSE, values=c(0,0,0,0,0) )
# latent means
latMeans <- mxPath( from="one", to=c("intercept","slope"), arrows=1,
free=TRUE, values=c(0,-1), labels=c("meani1","means1") )
# enable the likelihood vector
funML <- mxFitFunctionML(vector=TRUE)
class1 <- mxModel("Class1", type="RAM",
manifestVars=c("x1","x2","x3","x4","x5"),
latentVars=c("intercept","slope"),
resVars, latVars, intLoads, sloLoads, manMeans, latMeans,
funML)
# latent variances and covariance
latVars2 <- mxPath( from=c("intercept","slope"), arrows=2, connect="unique.pairs",
free=TRUE, values=c(1,.5,1), labels=c("vari2","cov2","vars2") )
# latent means
latMeans2 <- mxPath( from="one", to=c("intercept", "slope"), arrows=1,
free=TRUE, values=c(5,1), labels=c("meani2","means2") )
class2 <- mxModel(class1, name="Class2", latVars2, latMeans2)
# Create an MxModel object
# -----------------------------------------------------------------------------
# request that individual likelihoods are used
# required for correct parameterization of class probabilities
classP <- mxMatrix( type="Full", nrow=2, ncol=1,
free=c(TRUE, FALSE), values=1, lbound=0.001,
labels = c("p1","p2"), name="Props" )
mixExp <- mxExpectationMixture(components=c('Class1', 'Class2'), weights='Props', scale='sum')
fit <- mxFitFunctionML()
dataRaw <- mxData( observed=myGrowthMixtureData, type="raw" )
gmm <- mxModel("Growth Mixture Model",
dataRaw, class1, class2, classP, mixExp, fit)
gmmFit <- mxRun(gmm, suppressWarnings=TRUE)
summary(gmmFit)
# Unscaled mixture proportions
mxEval(Props, gmmFit)
# Scaled mixture proportions
gmmFit$expectation$output$weights
omxCheckCloseEnough(-2*logLik(gmmFit), 8739.05, 0.01)
omxCheckCloseEnough(max(gmmFit$expectation$output$weights), 0.6009, 0.01)
omxCheckCloseEnough(min(gmmFit$expectation$output$weights), 0.3991, 0.01)
# Check to see if results match within the specified bounds
# -----------------------------------------------------------------------------
Note that you could scale the mixture proportions differently if you want. See the
scale
argument of?mxExpectationMixture
for details. Many other software packages only allow "multinomial logisitc regression" or what we call "softmax" scaling.Log in or register to post comments