I am new to OpenMx and trying to resolve a problem with non-positive definite covariance matrix. I have looked at other postings in this forum and it looks like it is a starting value problem although not sure. I have tried several combinations and keep getting the same error. I am listing my code and would appreciate any help.
Thanks
I keep getting the following error:
Running Political Democracy CFA
Error: The job for model 'Political Democracy CFA' exited abnormally with the error message: Backing out of parameter space region where expected covariance is non-positive-definite.
>
-----------------------------------------------------------------------------
Load Library
require(OpenMx)
-----------------------------------------------------------------------------
read Data
polidem.data <- read.csv('POLIDEM.csv')
head(polidem.data)
polidem.cfa <- polidem.data[,c("PRESS60","FREOP60","FREEL60","LEGIS60","PRESS65","FREOP65","FREEL65","LEGIS65")]
-----------------------------------------------------------------------------
manifde60=c("PRESS60","FREOP60","FREEL60","LEGIS60")
manifde65=c("PRESS65","FREOP65","FREEL65","LEGIS65")
manifest=c(manifde60,manifde65)
latents=c("demo60","demo65")
--start model-------
PolidemModel <- mxModel("Political Democracy CFA",
type="RAM",
mxData( observed=cov(polidem.cfa),
type="cov",numObs=75 ),
manifestVars=manifest,
latentVars=latents,
residual variances
mxPath(
from=manifest,
arrows=2,
free=TRUE,
values=c(1,0.8,0.8,0.8,0.8,0.8,0.8,0.8),
labels=c("e1","e2","e3","e4","e5","e6","e7","e8") ),
latent variances for exogenous
mxPath(
from=latents,
arrows=2,
free=TRUE,
values=c(0.6,0.6),
labels=c("varF1","varF2") ),
latent covariance
mxPath(
from="demo60",
to="demo65",
arrows=2,
free=TRUE,
values=c(0.5),
labels=c("covF1F2") ),
error covariance
mxPath(
from="PRESS60",to="PRESS65",
arrows=2,
free=TRUE,
values=c(.5),
labels=c("the15") ),
error covariance
mxPath(
from="FREOP60",to="FREOP65",
arrows=2,
free=TRUE,
values=c(.5),
labels=c("the26") ),
error covariance
mxPath(
from="FREEL60",to="FREEL65",
arrows=2,
free=TRUE,
values=c(.5),
labels=c("the37") ),
error covariance
mxPath(
from="LEGIS60",to="LEGIS65",
arrows=2,
free=TRUE,
values=c(.5),
labels=c("the48") ),
error covariance
mxPath(
from="FREOP60",to="LEGIS60",
arrows=2,
free=TRUE,
values=c(.5),
labels=c("the24") ),
error covariance
mxPath(
from="FREOP65",to="LEGIS65",
arrows=2,
free=TRUE,
values=c(.5),
labels=c("the68") ),
-------------------------------------
factor loadings for demo60 variables
mxPath(
from="demo60",
to=manifde60,
arrows=1,
free=c(FALSE,TRUE,TRUE,TRUE),
values=c(1,0.2,0.2,0.2),
labels=c("l1","l2","l3","l4") ),
factor loadings for demo65 variables
mxPath(
from="demo65",
to=manifde65,
arrows=1,
free=c(FALSE,TRUE,TRUE,TRUE),
values=c(1,0.2,0.2,0.2),
labels=c("l1","l2","l3","l4") )
-----------------------------------------------------------------------------
)
close model
-----------------------------------------------------------------------------
run model
PolidemFit <- mxRun(PolidemModel)
get summary
summary(PolidemFit)
get estmates
PolidemFit@output$estimate
I'd first try adding lower bounds to your residual variances. Just add the argument
lbound=.001
(or .01, or .0001) to the mxPath command for your residuals. Often that's enough to keep the optimizer in valid likelihood space.If it works, be sure to check your results. If you find that one of your estimated variances is right up against the lower bound you set, there may be other problems with the model.
What's happening is that the optimizer is moving away from the starting values, but is getting stuck in a bad area of the likelihood space. Restricting variances to be positive may be enough to nudge it into the valid area of the space. I'll talk to the rest of the dev team about making that error message more informative.
Thank you for the quick reply.
The problem seems to be with the two error covariance terms (labels="the24" & "the68" in mycode). I am able to estimate all other parameters. I tried different start values and lbounds for these two parameters and still cannot get it to work.
Any suggestions?
So, change the initial script lines defining these paths to
mxPath(
from="FREOP60",to="LEGIS60",
arrows=2,
free=F,
values=c(0),
labels=c("the24") ),
error covariance
mxPath(
from="FREOP65",to="LEGIS65",
arrows=2,
free=F,
values=c(0),
labels=c("the68") ),
And then after
run model
PolidemFit <- mxRun(PolidemModel)
get summary
summary(PolidemFit)
get estmates
PolidemFit@output$estimate
Add:
PolidemModel2 <- mxModel(PolidemModel,
mxPath(from="FREOP60",to="LEGIS60", arrows=2, free=TRUE, values=c(0), labels=c("the24") ),
error covariance
mxPath(from="FREOP65",to="LEGIS65", arrows=2, free=TRUE, values=c(0), labels=c("the68") )
)
run revised model
PolidemFit2 <- mxRun(PolidemModel2)
get summary
summary(PolidemFit2)
get estmates
PolidemFit2@output$estimate
Thank you. That worked. Zero was one value that I did not try. Since I knew the estimates were far from zero I kept trying positive values.
I'm glad it did. In general, specifying covariances directly in a model runs the risk of generating covariances that exceed the (square root of the product of the corresponding) variances. Usually, starting estimation where the model is positive definite solves the problem (as it did in your case). Inspection of the predicted covariance matrices at the start values is a valuable diagnostic tool.
Sometimes starting certain parameters at zero does not work, especially when the input matrices (or raw data) are not positive definite. In such cases, wherever you start optimization, the optimizer will sail towards the non-positive definite region and either partially or completely fail to find a solution. OpenMx has some built-in algorithms to help steer optimization away from such regions, but if the data are saying that is where it should go, it will, albeit with some complaining and instability of solution.
In many instances it is possible to avoid such problems altogether by re-specifying the model. For example, rather than adding a covariance path between residuals (or observed variables), a latent factor can be added with directional paths to both variables, and with these paths set equal to each other. Doing so would add variance to the targeted variables, as well as covariance to them, so non-positive definiteness would be less of a liability. There would be the possibly unwanted side-effect of forcing the covariance to be positive, but that could be switched to being forced to be negative instead, if needed.