今天给大家写一个非常经典的结构方程模型的例子,这个例子是用来研究精神错乱的,模型总共有3个因子,一个社会经济地位SES,另外两个分别是1967年和1971年的精神错乱alien。每个因子两个测量指标,其中社会经济地位SES是以教育education和职业sei两个指标变量测量,精神错乱alien用无力感powerless和混乱anomia两个指标测量。
我们想验证的模型结构为1966年的SES会对1967年和1971年的精神错乱造成影响,而1967年的精神错乱会对1971年的精神错乱有影响。同时模型允许精神错乱的测量指标间有共变。
根据以上的叙述我们可以就写出模型:
# 协方差矩阵
wheaton.cov = as.matrix(read.csv('D:/接单数据/bootcamp/dataset/wheaton_cov.csv', row.names=1))
wheaton.model = '
# 测量模型
ses =~ education + sei
alien67 =~ anomia67 + powerless67
alien71 =~ anomia71 + powerless71
# 结构模型
alien71 ~ aa*alien67 + ses
alien67 ~ sa*ses
# 残差相关
anomia67 ~~ anomia71
powerless67 ~~ powerless71
# 间接效应
IndirectEffect := sa*aa
'
alienation <- sem(wheaton.model, sample.cov=wheaton.cov, sample.nobs=932)
我们的模型图示如下:
运行上面的代码我们就可以出结果:
我们将标准化的路径系数在图上进行了展示,下图是结果:
上面的模型拟合其实很好,大家可以自己运行看看拟合指标,因为结果输出很长,这儿没有给大家截屏完。
接下来给大家写写结构方程模型中的常见问题
识别问题
识别问题牵扯到我们能不能给要拟合的参数找到一个独特的解。
看一个很简单的方程:a+b=2
对于这个方程我们肯定是找不到独特解的。我们知道其实结构方程模型就是在同时求解很多个回归方程,所有的方程解的情况可以根据我们独立方程的个数和求解参数的个数的关系分为以下三种情况(独立方程个数p*,这个P*=p(p + 1)/2,其中p为测量变量的个数):
- 当我们的独立方程个数和拟合参数个数相等的时候,这个时候自由度为0,叫做恰好识别。
- 当拟合参数个数大于我们的独立方程的个数的时候,叫做不识别,这是有问题的。
- 当拟合参数个数小于独立方程个数的时候,叫做超识别,这是最常见的情况,此时我们可以进行模型的比较。
看例子:我们把之前的结构方程中其中一个测量部分拆出来:
此时我们已知信息包括X1,X2的方差和他们之间的协方差,我们有3个已知或者说3个独立方程,此时我们要估计的参数有:两个载荷,潜变量方差和两个显变量的残差方差,共5个参数。
当然啦,我们会固定一个作为标尺,为啥固定请看我之前的文章。比如我们会将其中一个载荷固定为1,那么我们还有4个参数要估计,但是我们只有3个独立的方程哦,所以此时模型是不识别的。
模型不识别会出现什么情况呢?我们来操作一下:
modelUnder = 'LV =~ x1 + x2'
underModel = cfa(modelUnder, data=cbind(x1,x2,x3))
summary(underModel)
运行后你会看见输出结果是没有标准误的:
如果我再加上一个显变量,估计如下的模型:
我们再来剖析一下识别问题:我们现在的已知或者说独立方程个数变成了 N(N+1)/2=3∗4/2=6,我们要估计的参数有3个方差,3个协方差,还有潜变量方差,所以我们共要估计7个参数,记住,我们会固定一个参数作为标度,所以恰好估计6个就行,此时便是恰好识别。
我们还是将恰好识别的模型也跑一遍,加深印象:
modelJust = 'LV =~ x1 + x2 + x3'
justModel = cfa(modelJust, data=cbind(x1,x2,x3))
summary(justModel, fit=T)
这个时候你会发现输出的模型结果是没有拟合指数的:
再回到我们的完整实例
在这个实例中,我们有6个显变量,所以我们共6*7/2 = 21个独立方程,我们要估计的参数包括:3个潜变量方差,6个显变量方差和2个显变量协方差,3条路径系数和6个载荷,共20个参数,但是记住,我们会固定3个参数作为标尺,所以我们共要估计17个参数,我们有21-17=4个自由度。属于超识别,此时我们会有模型拟合指标,可以进行模型比较。
拟合指标
结构方程模型的拟合指标贼多,所以大家一定要有全局观,切不可因某一个指标拖累全局,我们还是看看上面例子的拟合情况:
运行代码:
fitMeasures(alienation, c('chisq', 'df', 'pvalue', 'cfi', 'rmsea', 'srmr', 'AIC'))
当然你直接在summary的参数中加上fit.measures=T也是可以出来常见的拟合指标的,这儿给大家一个一个解释各个指标的意义。
首先是卡方检验:
the χ2χ2 test measures the discrepancy between the observed correlations and those implied by the model.
这个卡方是模型和数据符合情况的一个表达,卡方检验显著就说明我们的模型和数据不符。影响卡方值的东西很多,比如样本量,比如数据的非正态性等等,所以这个指标我们一般不是很重视。
然后就是CFI等:
The Comparative Fit Index compares the fitted model to a null model that assumes there is no relationship among the measured items
CFI就是把我们的模型和零模型进行比较,它的取值在0到1之间,越大说我们的模型越好,通常的要求是大于0.9,还有比如TLI和IFI等以I结尾的拟合指标的取值范围和要求都是一样的,但是这一类指标特别容易受协变量的影响,一般是模型越复杂这些指标的值就会越好。
RMSEA和SRMR:
The root mean squared error of approximation is a measure that also centers on the model-implied vs. sample covariance matrix, and, all else being equal, is lower for simpler models and larger sample sizes.
The standardized root mean squared residual is the mean absolute correlation residual, i.e. the difference between the observed and model-implied correlations.
这两个东西都是来衡量我们模型的协方差矩阵和原始数据的协方差矩阵的差异的,值越小越好,都要求小于0.05.
修正指数
通过lavaan做结构方程模型可以很容易地获得修正指数,我们对模型修正的目的就是要提高模型的拟合优度,就是让我们的模型更好地符合我们的数据,所以修正的过程就是一个对模型参数释放的过程:就是说你给更多的参数进行自由估计,那么肯定模型优度会更好,所以我们的操作就是把修正指数列出来,从小到大依次将相应的参数释放重新拟合。
但是一定要注意理论支持,切不可为了提高优度乱来。其实有学者就很不支持使用修正指数,因为本来结构方程模型就是一个以强有力理论为基础验证性研究,你单单凭一个修正指数就要修改某某路径,就是说理论驱动让位给了数据驱动,很多大佬是不愿意的。当然,咱们做研究根据修正指数修改修改都是没问题的。
模型比较
因为好多东西即便是有理论,理论也有争议,也有探索的空间嘛,所以有可能你会在研究中提出多个可能的模型,这个时候就涉及到模型比较了。
模型比较看两个东西AIC和BIC
AIC和BIC本身不说明问题,但是越好的模型AIC和BIC会越小,所以通过对它两的比较就可以说明问题
看例子:
比如我想要对比alienation, alienationNoInd这两个模型,我就可以写出代码如下:
compareFit(alienation, alienationNoInd)
根据模型比较的结果,fit1明显要好点。
小结
今天依然是通过实例给大家写了部分结构方程模型的知识,感谢大家耐心看完,自己的文章都写的很细,代码都在原文中,希望大家都可以自己做一做,请关注后私信回复“数据链接”获取所有数据和本人收集的学习资料。如果对您有用请先收藏,再点赞转发。
也欢迎大家的意见和建议,大家想了解什么统计方法都可以在文章下留言,说不定我看见了就会给你写教程哦。