lavaan提供了跨组约束参数的机会.假设我的数据中有两组.假设以下型号:
library(RCurl)
library(lavaan)
x <- getURL("https://gist.githubusercontent.com/aronlindberg/dfa0115f1d80b84ebd48b3ed52f9c5ac/raw/3abf0f280a948d6273a61a75415796cc103f20e7/growth_data.csv")
growth_data <- read.csv(text = x)
model_regressions <- ' i =~ 1*t1 + 1*t2 + 1*t3 + 1*t4 + 1*t5 + 1*t6 + 1*t7 + 1*t8 + 1*t9 + 1*t10 + 1*t11 + 1*t12 + 1*t13+ 1*t14 + 1*t15 + 1*t16 + 1*t17 + 1*t18 + 1*t19 + 1*t20
s =~ 0*t1 + 1*t2 + 2*t3 + 3*t4 + 4*t5 + 5*t6 + 6*t7 + 7*t8 + 8*t9 + 9*t10 + 10*t11 + 11*t12 + 12*t13 + 13*t14 + 14*t15 + 15*t16 + 16*t17 + 17*t18 + 18*t19 + 19*t20
# fixing error-variances
t8 ~~ 0.01*t8
t17 ~~ 0.01*t17
t18 ~~ 0.01*t18
# regressions
s ~ h_index
i ~ h_index'
fit_UNconstrained <- growth(model_regressions, data=growth_data, group = "type")
Run Code Online (Sandbox Code Playgroud)
然后使用以下我可以约束两组的截距:
fit_constrained_intercepts <- growth(model_regressions, data=growth_data, group = "type", group.equal = c("intercepts"))
Run Code Online (Sandbox Code Playgroud)
然而,当我将该模型与无约束模型进行比较时,自由度和Chi2的差异为零(0).这怎么可能?
此外,当我约束其他参数时,例如方差,例如:
fit_constrained_variances <- growth(model_regressions, data=growth_data, group = "type", group.equal = c("lv.variances"))
Run Code Online (Sandbox Code Playgroud)
...并且将约束模型与无约束模型进行比较,自由度的差异为2,而不是像我期望的那样约束单个参数:
fitMeasures(fit_UNconstrained, "df")
fitMeasures(fit_constrained_intercepts, "df")
fitMeasures(fit_constrained_variances, "df")
Run Code Online (Sandbox Code Playgroud)
因此,我的问题是:如何限制各种参数(尤其是截距和方差)会影响熔岩的自由度?
这是因为您正在建模增长曲线:当您使用growth()函数时lavaan,所有截距都会自动约束为零!这就是为什么当您将"无约束"模型与限制截距的模型进行比较时,您获得相同的输出 - 模型实际上是相同的.
要进一步探索这一点,请尝试使用sem()而不是growth()运行模型拟合.我们将sem()简单地使用它来更好地了解自由度如何变化,因为它不会自动强制执行任何约束.让我们再来看一下自由度:
> fitMeasures(fit_UNconstrained, "df")
df
416
> fitMeasures(fit_constrained_intercepts, "df")
df
434
Run Code Online (Sandbox Code Playgroud)
请注意,我们通过修复截距获得18个自由度.我会把它分解如下:
你的模型有20个观测变量(t1:t20),所以我们可能会认为通过修正每个观测变量的截距来获得20个自由度.但是,我们实际上是将每个潜在变量中的所有截距限制为相同(在这种情况下,您有两个潜在变量,i和s).我们不是像以前那样拟合20个截距,而是拟合2个截距(每个潜在变量一个),从而产生18个自由度的净增益.
在你的问题中,你提到过:
"......自由度的差异是2,而不是1,正如我所期望的那样,约束一个参数......"
不幸的是,这不太对.在SEM模型中,自由度不依赖于我们约束的参数"类型"的数量,而是取决于模型中"自由参数"的总数.
使用时lv.variances,实际上是在约束潜在变量的方差.如上所述,您有两个潜在变量i和s,因此每个约束一个参数,从而获得两个自由度.
让我们拟合一个小型SEM,然后手动计算自由度.由于您正在对增长曲线进行建模,因此我们将使用您自己的增长模型的简化版本.我们将使用三个时间点而不是二十个时间点.
model_regressions <- ' i =~ 1*t1 + 1*t2 + 1*t3
s =~ 0*t1 + 1*t2 + 2*t3'
fit_UNconstrained <- growth(model_regressions, data=growth_data, group = "type")
summary(fit_UNconstrained) # note the use of "summary()" here
Run Code Online (Sandbox Code Playgroud)
我们可以直接使用这个公式计算自由度:
自由度=(唯一观察的数量) - (自由参数的数量)
1.让我们先计算独特观测的数量:
对于您的增长模型,每组中唯一观测数的公式为k(k + 1)/ 2 + k,其中k是您拥有的观测变量的数量.这来自于你的观察变量有k(k + 1)/ 2协方差,k观察到的平均值.在这种情况下,您有3个观察到的变量,因此每组中有3(3 + 1)/ 2 + 3 = 9个独特的观察值.你也有两组,所以我们实际上总共有(9*2)= 18个观测值.
2.现在进入免费参数.我们适合(每个小组):
这给了我们8个自由参数,但同样,你有两个组,所以(8*2)总共给我们16个自由参数.
使用上述公式,18-16 = 2个自由度.让我们看看是否lavaan同意:
> fit_UNconstrained
lavaan 0.6-3 ended normally after 64 iterations
Optimization method NLMINB
Number of free parameters 16
Number of observations per group
Exploration 87
Exploitation 125
Estimator ML
Model Fit Test Statistic 62.079
Degrees of freedom 2
P-value (Chi-square) 0.000
Run Code Online (Sandbox Code Playgroud)
瞧!我希望这能让你更清楚.请记住,如果您选择使用s ~ h_index等方式修复回归,这也会改变您的自由度.通常,您应该使用summary()以查看您估计的自由参数的数量,并且可以用来inspect(..., "sampstat")查看您拥有的独特观察数量.
我建议玩一些更简单的SEM结构,以更好地了解它们的工作原理.祝你好运,快乐造型!