通过在PROC NLMIXED中处理;程序因错误而停止

时间:2017-09-19 19:10:44

标签: sas simulation

我模拟了500次重复,并计划使用BY处理在NLMIXED中分析每次重复。我的NLMIXED代码如下:

PROC NLMIXED DATA=MELS GCONV=1E-12 QPOINTS=11;
    BY Rep;
    PARMS LMFI=&LMFI.
          SMFI=&SMFI.
          LMRIvar=&LMRIvar. 
          SMRIvar=0 TO 0.15 BY 0.005; 
    mu = LMFI + b0i;
    evar = EXP(SMFI + t0i);
    MODEL Y ~ NORMAL(mu,evar);
    RANDOM b0i t0i ~ NORMAL([0,0],[LMRIvar,0,SMRIvar]) SUBJECT=PersonID;
    ODS OUTPUT FitStatistics=Fit2 ConvergenceStatus=Conv2 ParameterEstimates=Parm2;
RUN;

对于其中一些复制,方差分量被采样为较小,因此预期会出现一些非零数的收敛错误(请注意ODS OUTPUT语句中的ConvergenceStatus请求)。但是,当我收到以下警告时,NLMIXED退出处理,无论剩余要分析的复制数量如何。

WARNING: The final Hessian matrix is full rank but has at least one negative eigenvalue. Second-order optimality condition violated.
ERROR: QUANEW Optimization cannot be completed.

我错过了什么吗?我认为NLMIXED可以确认该复制的错误,但继续进行剩余的复制。我们对此表示赞赏!

最佳, 莱恩

1 个答案:

答案 0 :(得分:1)

以下是我认为正在发生的事情。差异必须是非负的要求以及方差估计的分布是长尾的这一事实使得差异很难估计。方差分量估计更新可导致一个或多个估计的负值。 NLMIXED过程尝试计算模型方差分量的特征值。那时,NLMIXED崩溃。

但请注意

V[Y] = (sd[Y])^2
V[Y] = exp(ln(V[Y]))
V[Y] = exp(2*ln(sd[Y]))
V[Y] = exp(2*ln_sd_Y)

现在,假设我们将ln_sd_Y作为参数。对V [Y]的引用需要写为上面最后一个语句中显示的函数。由于参数ln_sd_Y的域是(-infinity,infinity),因此ln_sd_Y没有下限。函数exp(2 * ln_sd_Y)将始终产生非负方差估计。实际上,考虑到数字计算机的限制,无法表示负无穷大,只有前导到负无穷大的值,函数exp(2 * ln_sd_Y)将始终产生正参数估计。估计可能非常非常接近0.但估计总是从上面的0。这应该阻止SAS尝试计算负数的特征值。

您的代码略有改动会将LMRIvar和SMRIvar写为ln_sd_LMRIvar和ln_sd_SMRIvar的函数。

PROC NLMIXED DATA=MELS GCONV=1E-12 QPOINTS=11;
    BY Rep;
    PARMS LMFI=&LMFI.
          SMFI=&SMFI.
          ln_sd_LMRIvar=%sysfunc(log(%sysfunc(sqrt(&LMRIvar.)))) 
          ln_sd_SMRIvar=-5 to -1 by 0.1;
    mu = LMFI + b0i;
    evar = EXP(SMFI + t0i);
    MODEL Y ~ NORMAL(mu,evar);
    RANDOM b0i t0i ~ NORMAL([0,0],
                            [exp(2*ln_sd_LMRIvar), 0,
                               exp(2*ln_sd_SMRIvar)]) SUBJECT=PersonID;
    ODS OUTPUT FitStatistics=Fit2 ConvergenceStatus=Conv2 ParameterEstimates=Parm2;
RUN;

或者,您可以使用bounds语句来防止LMRIvar和/或SMRIvar的更新变为负数。您可以保留原始代码,插入语句

bounds LMRIvar SMRIvar > 0;

这比根据允许消极的参数编写模型更简单。但是,我的经验是使用具有域(-infinity,infinity)的参数实际上是更好的方法。