“The joy of discovery is certainly the liveliest that the mind of man can ever feel” - Claude Bernard -

Principles and Practice of Structural Equation Modeling 4th
rex b kline
https://www.guilford.com/companion-site/Principles-and-Practice-of-Structural-Equation-Modeling-Fourth-Edition/9781462523344/files

차돌아 사랑해

  • 구조방정식 수행까지의 전 과정을 정리해 둘 예정

  • 이 자료는 그냥 윤시기 공부용임. 틀린 내용 있을 수도 있음.
    물론 윤시기가 그럴 일은 없지만 ㅎㅋ

  • 레퍼런스는 여기저기서 가져올 예정

들어가기

도대체 무엇을 공부해야하는가?

  • 우리가 이 복잡한 세상을 완벽하게 이해하는 것은 불가능함.
  • 비록 데이터가 간단한 숫자로만 이루어졌을 지라도 개수가 늘어난다면 파악이 어려움.
    특히 복잡한 숫자로 가득한 데이터는 보기만해도 머리가 아픔.
  • 예를 들어 흑석초 3학년 2반 30명의 수학 점수를 모두 파악하는 것은 꽤 짜증나지만 불가능한 것만은 아님.
    하지만 이를 보다 간편하게 파악하고 위하여 우리는 평균(mean, 보다 정확하게는 arithmatic mean)을 자주 활용함.
    즉, 30개의 개별 수학점수가 아닌 하나의 수치만으로 현상으로 표현한 것.
    여기에 더하여, ’2반과 3반의 수학 점수 비교’라는 궁금증이 생긴다면 3반의 평균만 구하여 비교하면 됨. 이처럼 평균은 집단의 특성을 축약할 수 있는 간단하지만 강력한 도구임
# 흑석초 3학년 2반의 수학 점수
mathscore <- data.frame(no=c(1:30), math=sample(60:100, 30, replace=T))
mathscore %>% head
##   no math
## 1  1   72
## 2  2   77
## 3  3   66
## 4  4   80
## 5  5   85
## 6  6   70
# 흑석초 3학년 2반의 수학 점수 평균
mathscore %>% summarise(math_mean = mean(math))
##   math_mean
## 1  77.63333
  • 문제는 정보의 축약에 따른 information loss가 발생한다는 것.
  • 그런데 채점을 하다보니 의문사항이 들 수 있음.
    ‘차돌이 미대 가고 싶다더니 수학 점수가 떨어졌네 공부를 안하나? 탄희도 미대 가고싶다더니 원래 수학을 못하긴 했는데 얘는…’
    ‘설마 예체능하는 애들은 그렇지 않은 애들에 비해서 수학점수가 낮나?’ 이처럼 궁금한 사항이 툭하고 튀어나옴.
    우리는 이런 궁금증을 해결하고자 함. 그런데 무엇으로 해결할까? 그렇다. 통계
  • 앞으로 내가 써내려갈 내용은 절대반지를 파괴하기 위해 사우론을 찾아 떠나는 반지원정대처럼,
    궁금증(개인적 호기심이건 졸업 때문에 해야만 하는 어쩔 수 없는 것이건 간에… 암튼 해결하고 싶은 무언가)을 파괴하기 위해 여정을 떠나는 과정을 써내려갈 것임.
  • 나는 당신이 지금 당장은 0/3/0 베인일지라도, 결국엔 19/3/11 풀템 베인이 되어 통계의 협곡을 종횡무진 활약하고 다닐 것임을 믿어 의심치 않습니다. (근본 서포터 플레티넘 윤시기가 케어해드립니다)

베인충 굴러보자

  • 그런데 현실은 생각보다 더더 복잡함. 단순히 예체능학생의 수학점수가 더 낮다라는 정보 이외에도 수 많은 정보들이 수학 점수라는 데이터에 녹아 있는 것임.
    3반이 2반보다 평균은 높아도 상위권 학생은 2반에 더 많거나, 성별에 따라서도 수학점수가 다르거나, 장래 희망에 따라 점수가 다른 등(ex. 이과를 지향하는 학생의 점수가 더 높다)
    따라서 연구 문제에 따라 집단별 평균을 활용하는 등 점점 복잡한 계산이 필요해짐.
  • 3학년 2반의 수치를 나타내기 위하여 필요한 것은 1개의 평균이고, 3반과의 비교를 위해서는 2개의 평균을 활용하였음.
    만약 2반과 3반의 학생들에 대하여 향후 진로(이과/ 문과/ 예체능)에 따라 집단별 평균을 구한다면 6개의 평균이 도출될 것임.
  • 하지만 이런 two-way table을 만들고 평균을 만드는 것도 한계가 있음.
  • 그래서 우리는 우리의 연구 문제에 적합한 미지의 통계적 방법론을 찾아 떠나야 함.
##     이과 문과 예체능
## 2반 "a"  "c"  "e"   
## 3반 "b"  "d"  "f"
  • 이 표는 60명의 수학점수를 6개의 셀로 축약하고 현상에 숨겨진 과학적인 정보를 밝혀내는 것이라고 볼 수 있음.

  • 반별 비교와 향후 진로를 동시에 고려하기 위해서는 필요한 평균치가 2개에서 6개로 늘어남.
    달리 말해, 보다 복잡한 현상을 이해하기 위하여 더 복잡한 통계 모형(statistical model)을 활용하는 것이라 볼 수 있음.

  • 그런데 방법론마다 도출되는 모수(parameter)가 각기 상이함.
    (ex. ANOVA에서는 F-score, Sum of Squares 등이 있고 회귀분석에서는 coefficient 등)
    이러한 모수들은 각기 의미하는 바가 상이하며 각 파라미터를 통해 도출할 수 있는 직간접적 연구 문제도 상이함.
    (ex. 일반적인 상황에서 ANOVA의 F-score는 집단 차이를 나타내고, 회귀에서 coefficients는 변화량을 나타냄)

  • 앞의 수학 예시를 모수(parameter)의 관점에서 생각해본다면, 더 많은 파라미터가 필요해진 상황!
    즉, 현상이 복잡할수록, 더 많은 파라미터를 마주해야하는 것은 필연적임.
    (ex. 평균 수치가 많아지거나, 회귀 분석의 계수(coefficient)가 늘어나는 등)

  • 그러므로 모수(paratemer)의 해석이 쉽고, 모수의 개수가 적은 방법론이 좋은 방법론이 될 수도 있겠죠?
    때에 따라서는 복잡한 방법론이 필요할 수도 있으니. 암튼 간명성의 측면에선 모수가 적고 해석이 쉽다면 좋은 방법론일 것임.

  • 연구 문제(research question)에 맞는 연구 설계(research desin)와 방법론(methodology)이 정말로 중요한 것.
    연구 설계와 방법론이 정확하지 않다면 쉬운 현상을 잘못된 방법으로 바라볼 수도 있으며, 분석 자체가 불가능하기 때문에 연구 문제가 뒤틀려버릴 수도 있다.
    또한, 연구 문제가 같을 지라도 방법론이 다르다면 연구 문제를 바라보는 시각이 달라질 수 있다!

    그러므로 연구 문제/ 연구설계/ 방법론은 상호 유기적으로 맞물리며 조화를 이루도록 해야함.

  • 일단 설문돌리고 나중에 어떻게든 되겠지 하다보면, 나중에 그 설문 못써먹을 수도 있음 ㅠㅠ.

  • 그러니까 연구의 수행 이전에 literature review 등을 정말 잘하고 연구를 시작하자.
    연구 문제와 설계만 적합하면 t-test도 충분하다!
    연구 문제라는 재료만 싱싱하면 t-test라는 간단한 조리만으로도 훌륭한 요리(연구)를 도출할 수 있다.

metaphorical explanation about goodness-of-fit

  • 한편, 우리가 돌리는 통계는 사실 세상에 대한 그림을 그리는 것과 같다.

  • 우리가 살고 있는 미지의 이 세계를 저 닥스훈트라고 가정 해보자.

  • 통계 분석의 목적은 이 닥스훈트를 잘 그리는 것임.

  • 이를 위해서는 닥스훈트를 최대한 잘 표현하면서 간명한(parsimony) 통계 모형을 만들어내는게 중요함.

  • 모형이 데이터와 닮았다면 현상을 잘 파악한 것이므로 좋은 것이고, 데이터와 거리가 멀다면 모형이 세상을 파악하는데 좋지 못한 것이므로 안 좋은 모형.
    (Data = Model –> good!)

  • Model1은 복잡하지만 현상을 더 잘 설명하는 모형, Model 2는 극강의 간명한 모형(피카소의 그림임).
    무엇이 더 좋은지는 상황에 따라 다름! 연구자가 선택하는 것.

  • 다시 한 번 모수의 관점에서 생각해보자.
    현상에 관한 깊고 정확한 이해가 필요하다
    –> 닥스훈트를 더 세밀하게 그리려는 노력이 필요.
    –> 해석해야 하는 모수가 많아질 것
    통계를 잘 모르는 분과의 협업을 하거나 대략적인 인사이트를 얻는 것이 주목적이다
    –> 덜 세밀한 모형으로 이해하기 쉬운 모형을 만드는게 더 중요할 수도
    –> 해석해야 하는 모수가 적을 것

  • 여기 까지 중간정리, 연구 문제에 적합한 연구 설계와 방법론이 가장 중요하다!


  • 근데 세상엔 정말 너무나도 많은 방법론이 존재함.
    데이터가 같을 지라도 다양한 방법론이 적용 가능함.
    방법론 마다 저마다의 장단점이 있음
    단순히 적용 가능한 방법론의 도출을 뛰어넘어서 연구에 적합한 research question을 직접적으로 해결해 줄 수 있는 방법론이 가장 좋은 방법론
    적합한 방법론을 찾는 것도 능력임

  • 간단하게는 독립변수와 종속변수의 특성 및 연구 설계에 맞는 방법론을 찾으면 됨.
    수도 없이 배웠으나 왜 중요한지 감이 오지 않았던 명목(norminal), 서열(ordinal), 등간(interval), 비율(ratio) 척도가 여기서 중요한 역할을 함.

  • 리커트 척도(Likert scale) 5점으로 우울감을 측정하였고 성차가 알고 싶다고 가정해보자.
    이를 다시 쓰면 남녀에 따른 우울감을 비교하고 싶은 것이다.
    즉, 독립변수는 남녀라는 명목 척도(norminal scale)이고 종속변수는 리커트척도(interval 또는 ratio scale)이다.
    그러므로 Simple linear regression, ANOVA, T-TEST가 가장 적합한 방법론일 것

  • 이처럼 적합한 방법론을 탐색하기 위해서 고려할 사항으로는 다음과 같은 것들이 있음

    1. 종속 변수 및 독립 변수의 척도
    2. 종속 변수 및 독립 변수의 개수
    3. 반복 여부
    4. 잠재 변수 여부
    5. 집단 비교가 있다면 within인지/ between인지
  • 이 외에도 더 있을 것 같은데 아무튼 이정도만 짚고 넘어가도 큰 문제는 없을 듯

  • 다소 장황했으나 여기까지 정리해보자.

  • 연구문제와 연구설계를 정확히 하고 이에 적합한 방법론을 활용하자! 그리고 방법론의 parameter를 정확하게 해석할 수 있으면 됨.

구조방정식?

  • 그래 방법론마다 장단점이 있고 적합한 방법론을 써야한다는 알겠는데, 구조방정식은 왜이렇게 많이 쓰이는가?

  • 장점이 뭐길래?

  • 정답부터 말하자면, 직접 관찰의 불가능한 심리현상을 다룰 수 있는 방법론이기 때문이다.

  • 물리학, 생물학 등에서 쓰이는 개념들은 대개 직접적으로 측정이 가능하다(ex. 질량, 온도, 횟수 등)
    그러므로, 좋은 줄자나 저울 등의 측정장치가 있으면 됨.

  • 하지만 인간의 심리현상은 직접적인 관찰이 불가능하다.
    따라서, 설문 문항 등을 활용하여 간접적으로 측정한다.(ex. Wechsler Adult Intelligence Scale; WAIS, Beck Depression Index; BDI)
    즉, 지능검사는 문제지(observed variable)를 통해서 지능이라는 어떠한 심리적 요인(factor- latetn variable)를 측정하는 것!

  • 그런데 구조방정식은 직접적으로 측정한 측정치(Observed Variable)를 활용하여 잠재 변수(Latent Variable)라는 눈에 보이지 않는 개념(Construct)을 정량화할 수 있다.

  • 그렇다! 심리현상 관련한 연구문제와 구조방정식의 개념이 궤를 같이 하기 때문에 구조방정식이 좋은 것.

  • 또한 구조방정식은 다양한 방법론과 융합하여 발전하였기 때문에 좀 더 복잡한 파라미터를 감내할 자신이 있다면!
    더욱 복잡한 연구 문제 해결이 가능해졌다!
    왕관을 쓰려는 자, 그 무게를 견뎌라!

  • 나는 개인적으로 큰 그림을 스케치하고 다시 세부적인 것을 말하는 것을 좋아함.
    뭔가 스케치가 비계(scaffold)가 되어서 학습에 도움이 된다고 생각!
    그래서 구조방정식을 세세하게 설명하기 이전에 우선 구조방정식을 적합하기 까지의 전 과정을 훑고 나서 구조방정식을 깊게 설명하고자 함.

  • 그러므로 아래의 분석 과정이 후루룩 넘어가는 것 같아도 그냥 이런 흐름을 거치면서 지나가는 구나 하고 끄덕끄덕 하면 됨.

분석 과정

  1. 기술통계량
  2. EFA
  3. CFA
  4. SEM
  • 일반적인 분석 과정은 위와 같음. 구조방정식 적합을 위해서는 순서대로 착착 진행해야 함.
library(lavaan)
library(dplyr)
library(psych)
library(ggplot2)
library(kableExtra)
  • 필요한 패키지

기술통계량

data("HolzingerSwineford1939") 
id sex ageyr agemo school grade x1 x2 x3 x4 x5 x6 x7 x8 x9
1 1 13 1 Pasteur 7 3.333333 7.75 0.375 2.333333 5.75 1.2857143 3.391304 5.75 6.361111
2 2 13 7 Pasteur 7 5.333333 5.25 2.125 1.666667 3.00 1.2857143 3.782609 6.25 7.916667
3 2 13 1 Pasteur 7 4.500000 5.25 1.875 1.000000 1.75 0.4285714 3.260870 3.90 4.416667
4 1 13 2 Pasteur 7 5.333333 7.75 3.000 2.666667 4.50 2.4285714 3.000000 5.30 4.861111
5 2 12 2 Pasteur 7 4.833333 4.75 0.875 2.666667 4.00 2.5714286 3.695652 6.30 5.916667
6 2 14 1 Pasteur 7 5.333333 5.00 2.250 1.000000 3.00 0.8571429 4.347826 6.65 7.500000
  • 분석에 활용할 예제 데이터
holzdata <- HolzingerSwineford1939 %>% dplyr::select(x1:x9) %>% as_tibble()
holzdata %>% head
## # A tibble: 6 x 9
##      x1    x2    x3    x4    x5    x6    x7    x8    x9
##   <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1  3.33  7.75 0.375  2.33  5.75 1.29   3.39  5.75  6.36
## 2  5.33  5.25 2.12   1.67  3    1.29   3.78  6.25  7.92
## 3  4.5   5.25 1.88   1     1.75 0.429  3.26  3.9   4.42
## 4  5.33  7.75 3      2.67  4.5  2.43   3     5.3   4.86
## 5  4.83  4.75 0.875  2.67  4    2.57   3.70  6.3   5.92
## 6  5.33  5    2.25   1     3    0.857  4.35  6.65  7.5
  • 참고로 이 데이터는 어린이의 학습 능력을 측정했던 자료임
  • X1~x3는 visual
    X4~X6은 textual
    X7~x9는 speeded 에 해당함. 즉 애초에 3개의 요인을 측정하고자 한 자료임.
  • holzdata에 필요한 변수(X1~X9)만 추출
    • x1 Visual perception
    • x2 Cubes
    • x3 Lozenges
    • x4 Paragraph comprehension
    • x5 Sentence completion
    • x6 Word meaning
    • x7 Speeded addition
    • x8 Speeded counting of dots
    • x9 Speeded discrimination straight and curved capitals

단순 descriptive statistics

holzdata %>% describe()
##    vars   n mean   sd median trimmed  mad  min   max range  skew kurtosis   se
## x1    1 301 4.94 1.17   5.00    4.96 1.24 0.67  8.50  7.83 -0.25     0.31 0.07
## x2    2 301 6.09 1.18   6.00    6.02 1.11 2.25  9.25  7.00  0.47     0.33 0.07
## x3    3 301 2.25 1.13   2.12    2.20 1.30 0.25  4.50  4.25  0.38    -0.91 0.07
## x4    4 301 3.06 1.16   3.00    3.02 0.99 0.00  6.33  6.33  0.27     0.08 0.07
## x5    5 301 4.34 1.29   4.50    4.40 1.48 1.00  7.00  6.00 -0.35    -0.55 0.07
## x6    6 301 2.19 1.10   2.00    2.09 1.06 0.14  6.14  6.00  0.86     0.82 0.06
## x7    7 301 4.19 1.09   4.09    4.16 1.10 1.30  7.43  6.13  0.25    -0.31 0.06
## x8    8 301 5.53 1.01   5.50    5.49 0.96 3.05 10.00  6.95  0.53     1.17 0.06
## x9    9 301 5.37 1.01   5.42    5.37 0.99 2.78  9.25  6.47  0.20     0.29 0.06
  • 집단에 따른 기술통계량을 추정하고자 한다면 psych::describeBy() 활용

변수별 분포와 corrleation 등

pairs.panels(holzdata)

correlation matrix

holzdata %>% cor.plot()

기술통계량을 통해 내릴 수 있는 결론

  • 기술통계량을 통해 각 변수의 분포 등 확인 가능 정규분포를 벗어나는 등의 큰 문제는 안보임. 그냥 평이함
  • corrleation matrix를 통해 확인해보니 x1~x3, x4~x6, x7~x9 세 개씩 관련 있는 것처럼 보임
  • 왠지 요인은 3개일 것 같다는 느낌을 갖고 EFA 분석으로 넘어감

EFA

EFA example

  • EFA는 요인 구조에 관한 어떠한 가설이 없을 때, 탐색적으로 수행해 볼 수 있음
    이를 위해서 투입하는 요인에 모두 loading이 생기도록 만들어서 계산을 수행함.
    (어떤 요인이 원인일지 모르니 전부의 효과를 보겠다 이 말)
  • n개의 문항에 대해서 N개의 factor를 가정한 모형은 위의 그림과 같음.
  • 각 요인이 모든 문항을 각각 설명하려고 함. 이 중에 필요 없는 걸 지우고 요인의 관계를 명확하게 정리할 것.
  • EFA 수행 시 중요한 것은,
    1. 요인의 개수를 찾는 것
    2. 추출 방법을 선택하는 것
    3. 회전 방법을 결정하는 것

screeplot 등을 활용한 요인의 개수 탐색

fa.parallel(holzdata)
## Warning in fa.stats(r = r, f = f, phi = phi, n.obs = n.obs, np.obs = np.obs, :
## The estimated weights for the factor scores are probably incorrect. Try a
## different factor score estimation method.

## Parallel analysis suggests that the number of factors =  3  and the number of components =  3
  • scree plot과 평행 분석 결과 3개의 요인이 가장 적절할 것으로 추정됨
  • 기술통계량에서 요인의 개수가 3개일 것만 같았던 것과 결과가 같음. 기분이 좋음

앞에서 탐지한 요인의 개수에 대하여 적합한 rotation method 적용

  • 회전 방법에 따른 factor loading 비교
  • none(무회전)/ oblimin/ varimax에서 도출되는 요인계수 잘 비교해봐요.
myefa3_none <- holzdata %>% fa(nfactors = 3, ., rotate="none")
myefa3_none$loadings
## 
## Loadings:
##    MR1    MR2    MR3   
## x1  0.576  0.169  0.342
## x2  0.308         0.388
## x3  0.400  0.309  0.444
## x4  0.769 -0.355 -0.107
## x5  0.751 -0.404 -0.164
## x6  0.763 -0.327       
## x7  0.308  0.433 -0.486
## x8  0.394  0.541 -0.270
## x9  0.505  0.453       
## 
##                  MR1   MR2   MR3
## SS loadings    2.827 1.215 0.816
## Proportion Var 0.314 0.135 0.091
## Cumulative Var 0.314 0.449 0.540
fa.diagram(myefa3_none)

+ 하나의 변수가 두개 이상의 요인에 걸리는 경우가 많음 + X1을 보면 MR1과 MR3 모두에 영향을 받는 것처럼 보임 + 그리고 그림을 보면 X2는 MR1, MR3에 의한 영향이 거의 비슷함. 나머지도 보면 요인 계수 해석이 다소 난해하고 어려움

myefa3_oblimin <- holzdata %>% fa(nfactors = 3, ., rotate="oblimin")
## Loading required namespace: GPArotation
myefa3_oblimin$loadings
## 
## Loadings:
##    MR1    MR3    MR2   
## x1  0.196  0.592       
## x2         0.509 -0.122
## x3         0.686       
## x4  0.846              
## x5  0.886              
## x6  0.805              
## x7        -0.152  0.737
## x8         0.125  0.686
## x9         0.382  0.456
## 
##                  MR1   MR3   MR2
## SS loadings    2.197 1.275 1.239
## Proportion Var 0.244 0.142 0.138
## Cumulative Var 0.244 0.386 0.523
fa.diagram(myefa3_oblimin)

+ 회전하지 않은 방법보다 깔끔하게 나뉨. + X1을 보면 MR3에 의해서만 영향 받는 것처럼 보임(MR1은 작아서 무시가능)

myefa3_varimax <- holzdata %>% fa(nfactors = 3,., rotate="varimax")
myefa3_varimax$loadings
## 
## Loadings:
##    MR1    MR3    MR2   
## x1  0.279  0.613  0.152
## x2  0.102  0.494       
## x3         0.660  0.129
## x4  0.832  0.161       
## x5  0.859              
## x6  0.799  0.214       
## x7                0.709
## x8         0.171  0.699
## x9  0.130  0.415  0.521
## 
##                  MR1   MR3   MR2
## SS loadings    2.187 1.342 1.329
## Proportion Var 0.243 0.149 0.148
## Cumulative Var 0.243 0.392 0.540
fa.diagram(myefa3_varimax)

+ 회전하지 않은 방법보다 깔끔하게 나뉨.
하지만 oblimin보다는 덜 깔끔함
+ X1을 보면 MR3에 의해서만 영향 받는 것처럼 보임(비록 MR1의 요인계수가 크지 않으나 oblimin 방법보다는 큼)
+ 이게 무엇인지 아래에서 그림으로 그려서 다시 봐봅시다.

rotation_comparison <- 
  bind_rows(
    myefa3_none$loadings[1:9,] %>% as.data.frame() %>% tibble::rownames_to_column() %>%  
      rename("textual"="MR1","speed"="MR2","visual"="MR3") %>% mutate(rotation ="none"),
        # rotation method = none
    myefa3_oblimin$loadings[1:9,] %>% as.data.frame() %>% tibble::rownames_to_column() %>%  
      rename("textual"="MR1","speed"="MR2","visual"="MR3") %>% mutate(rotation="oblimin"),
        # rotation method = oblimin(oblique)
    myefa3_varimax$loadings[1:9,] %>% as.data.frame() %>% tibble::rownames_to_column() %>%  
      mutate(rotation="varimax") %>% 
      rename("textual"="MR1","speed"="MR2","visual"="MR3"))
        # rotation method = varimax(orthogonal)

ggplot(rotation_comparison, aes(x=textual, y=visual)) + 
  geom_hline(yintercept=0) + 
  geom_vline(xintercept = 0) + 
  geom_point(col="red") + 
  geom_text(aes(label=rowname), hjust=1,vjust=-.2) +
  facet_grid(cols=vars(rotation)) + 
  coord_fixed()

  • rotation method 에 따른 결과 비교
  • oblimin(oblique) 방법이 더 나음!
    왜? simple structure를 도출해주니까.
    (하나의 변수는 하나의 요인에 의해서만 영향을 받는게 simple structure) 예를들어 none의 가장 왼쪽 위에 있는 값(X2)은 textual 0.27 visual 0.40임. 이 문항은 두 요인 중 무엇이 주요하게 영향을 미치는지 파악이 애매함
    oblimin이나 varimax에서 X2는 Y축에 거의 붙어있는 것을 볼 수 있음. 즉 textual 요인에 의한 설명량은 거의 없고 visual에 의하여 영향 받는 변수라는 것임.
    즉, 주요한 요인이 x인지(textual) y인지(visual)인지 보다 명확히 파악 가능함.
    값들이 축에 가까이 있을 수록 좋은 것 ! (원인이 명확하니까!) 즉, x1의 원인이 되는 요인이 무엇인지 가장 명확한 방법은 oblimin인 것이고 그다음은 varimax 가장 명확하지않은건 rotate=none임.
  • oblimin은 oblique rotation의 일종이다. factor간 correlation을 가정하는 방법으로 축 회전시 회전각도가 90도가 아니다.
  • 심리학 등 사회과학 분야의 데이터는 요인 간 관련이 있는 경우가 많다.
    그러므로, 어지간하면 oblique method가 나을 것임
    • orthogonal rotation
    • oblique rotation
  • 암튼 EFA 결론: 3개의 요인이 적절할 듯. 그러므로 여기까지 한 결과를 토대로 CFA를 수행해보자.
  • EFA에서 exploratory 하게 요인 구조를 파악하고, 이를 바탕으로 confirm 해보는게 CFA임.
  • 사실 EFA랑 CFA는 다른 데이터 가지고 수행해야함. 데이터를 반쪼개서 반은 EFA하고 나머지 반으로 CFA를 하고…
    근데 데이터 수집이 어려우므로(시간, 돈 etc …), 이렇게 하기 어려울 것임
    그리고 졸업논문 쓰겠다고 피같은 내 돈 써가면서 설문 157명도 겨우 모았는데 어떻게 쪼개서 쓰느냐!

CFA

  • 앞에서 말하였듯이 요인은 직접적으로 관찰되는 개념이 아님. 따라서 요인은 척도조차 존재하지 않음.
    그렇기 때문의 요인의 분산을 어떻게 정의할지가 애매함.
    이를 위해 두 가지 방법을 씀
    1. 특정 indicator를 marker로 활용하여 이의 variance를 잠재 변수의 variance로 쓰는 법
    2. 요인의 분산을 그냥 1로 고정하는 법.

marker indicator를 활용하는 방법

# 완전형(모든 파라미터를 수동으로 지정)
mycfa_model_marker <- "
visual =~ 1*x1 + x2 + x3
textual =~ 1*x4 + x5 + x6
speed =~ 1*x7 + x8 + x9
visual ~~ visual
textual ~~ textual
speed ~~ speed
"

# 축약형(Mplus의 기본 옵션을 많이 활용)
mycfa_model_marker <- "
visual =~ x1 + x2 + x3
textual =~ x4 + x5 + x6
speed =~ x7 + x8 + x9
"
  • 요인을 구성하는 첫번째 indicator를 1로 지정함
  • 위 두 버전은 결과가 같음.
    축약형으로 작성할 경우 지정하지 않은 parameter들은 lavaan이 기본 옵션대로 추정함.
    lavaan을 잘 모른다면 자동으로 도출해준 모형이 내가 원한 모형이 아닐 수 있음
    그러므로 완전형으로 코드 작성하는 연습을 하자!
    물론 lavaan을 잘 모르는데 완전하게 코드 작성하는게 쉽나… 라는 아이러니도 존재함
mycfa_marker_result <- sem(mycfa_model_marker, data= holzdata, mimic="Mplus")
summary(mycfa_marker_result, standardized=TRUE, fit.measures=TRUE, rsq=TRUE, modindices=FALSE)
## lavaan 0.6-7 ended normally after 36 iterations
## 
##   Estimator                                         ML
##   Optimization method                           NLMINB
##   Number of free parameters                         30
##                                                       
##   Number of observations                           301
##   Number of missing patterns                         1
##                                                       
## Model Test User Model:
##                                                       
##   Test statistic                                85.306
##   Degrees of freedom                                24
##   P-value (Chi-square)                           0.000
## 
## Model Test Baseline Model:
## 
##   Test statistic                               918.852
##   Degrees of freedom                                36
##   P-value                                        0.000
## 
## User Model versus Baseline Model:
## 
##   Comparative Fit Index (CFI)                    0.931
##   Tucker-Lewis Index (TLI)                       0.896
## 
## Loglikelihood and Information Criteria:
## 
##   Loglikelihood user model (H0)              -3737.745
##   Loglikelihood unrestricted model (H1)      -3695.092
##                                                       
##   Akaike (AIC)                                7535.490
##   Bayesian (BIC)                              7646.703
##   Sample-size adjusted Bayesian (BIC)         7551.560
## 
## Root Mean Square Error of Approximation:
## 
##   RMSEA                                          0.092
##   90 Percent confidence interval - lower         0.071
##   90 Percent confidence interval - upper         0.114
##   P-value RMSEA <= 0.05                          0.001
## 
## Standardized Root Mean Square Residual:
## 
##   SRMR                                           0.060
## 
## Parameter Estimates:
## 
##   Standard errors                             Standard
##   Information                                 Observed
##   Observed information based on                Hessian
## 
## Latent Variables:
##                    Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
##   visual =~                                                             
##     x1                1.000                               0.900    0.772
##     x2                0.554    0.109    5.066    0.000    0.498    0.424
##     x3                0.729    0.117    6.220    0.000    0.656    0.581
##   textual =~                                                            
##     x4                1.000                               0.990    0.852
##     x5                1.113    0.065   17.128    0.000    1.102    0.855
##     x6                0.926    0.056   16.481    0.000    0.917    0.838
##   speed =~                                                              
##     x7                1.000                               0.619    0.570
##     x8                1.180    0.150    7.851    0.000    0.731    0.723
##     x9                1.082    0.195    5.543    0.000    0.670    0.665
## 
## Covariances:
##                    Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
##   visual ~~                                                             
##     textual           0.408    0.080    5.124    0.000    0.459    0.459
##     speed             0.262    0.055    4.735    0.000    0.471    0.471
##   textual ~~                                                            
##     speed             0.173    0.049    3.518    0.000    0.283    0.283
## 
## Intercepts:
##                    Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
##    .x1                4.936    0.067   73.473    0.000    4.936    4.235
##    .x2                6.088    0.068   89.855    0.000    6.088    5.179
##    .x3                2.250    0.065   34.579    0.000    2.250    1.993
##    .x4                3.061    0.067   45.694    0.000    3.061    2.634
##    .x5                4.341    0.074   58.452    0.000    4.341    3.369
##    .x6                2.186    0.063   34.667    0.000    2.186    1.998
##    .x7                4.186    0.063   66.766    0.000    4.186    3.848
##    .x8                5.527    0.058   94.854    0.000    5.527    5.467
##    .x9                5.374    0.058   92.546    0.000    5.374    5.334
##     visual            0.000                               0.000    0.000
##     textual           0.000                               0.000    0.000
##     speed             0.000                               0.000    0.000
## 
## Variances:
##                    Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
##    .x1                0.549    0.119    4.612    0.000    0.549    0.404
##    .x2                1.134    0.104   10.875    0.000    1.134    0.821
##    .x3                0.844    0.095    8.881    0.000    0.844    0.662
##    .x4                0.371    0.048    7.739    0.000    0.371    0.275
##    .x5                0.446    0.058    7.703    0.000    0.446    0.269
##    .x6                0.356    0.043    8.200    0.000    0.356    0.298
##    .x7                0.799    0.088    9.130    0.000    0.799    0.676
##    .x8                0.488    0.092    5.321    0.000    0.488    0.477
##    .x9                0.566    0.091    6.250    0.000    0.566    0.558
##     visual            0.809    0.150    5.404    0.000    1.000    1.000
##     textual           0.979    0.112    8.729    0.000    1.000    1.000
##     speed             0.384    0.092    4.168    0.000    1.000    1.000
## 
## R-Square:
##                    Estimate
##     x1                0.596
##     x2                0.179
##     x3                0.338
##     x4                0.725
##     x5                0.731
##     x6                0.702
##     x7                0.324
##     x8                0.523
##     x9                0.442
  • cfa 결과
  • 참고로 mimic="Mplus는 기본적으로 켜주는게 좋음. 그렇지 않으면 SRMR 등을 추정해주지 않는다구.
  • modindices는 우리는 모르는 걸로 하자. 이거 독이든 성배임

분산을 1로 고정하는 방법

# 분산을 1로 고정한 CFA 모형
mycfa_model_lvvr1 <- "
visual =~ NA*x1 + x2 + x3
textual =~ NA*x4 + x5 + x6
speed =~ NA*x7 + x8 + x9
visual ~~ 1*visual
textual ~~ 1*textual
speed ~~ 1*speed
"
mycfa_lvvr1_result <- sem(mycfa_model_lvvr1, data= holzdata)
# 분산을 1로 고정한 CFA 결과
summary(mycfa_lvvr1_result, standardized=TRUE, fit.measures=TRUE, rsq=TRUE, modindices=FALSE)
## lavaan 0.6-7 ended normally after 20 iterations
## 
##   Estimator                                         ML
##   Optimization method                           NLMINB
##   Number of free parameters                         21
##                                                       
##   Number of observations                           301
##                                                       
## Model Test User Model:
##                                                       
##   Test statistic                                85.306
##   Degrees of freedom                                24
##   P-value (Chi-square)                           0.000
## 
## Model Test Baseline Model:
## 
##   Test statistic                               918.852
##   Degrees of freedom                                36
##   P-value                                        0.000
## 
## User Model versus Baseline Model:
## 
##   Comparative Fit Index (CFI)                    0.931
##   Tucker-Lewis Index (TLI)                       0.896
## 
## Loglikelihood and Information Criteria:
## 
##   Loglikelihood user model (H0)              -3737.745
##   Loglikelihood unrestricted model (H1)      -3695.092
##                                                       
##   Akaike (AIC)                                7517.490
##   Bayesian (BIC)                              7595.339
##   Sample-size adjusted Bayesian (BIC)         7528.739
## 
## Root Mean Square Error of Approximation:
## 
##   RMSEA                                          0.092
##   90 Percent confidence interval - lower         0.071
##   90 Percent confidence interval - upper         0.114
##   P-value RMSEA <= 0.05                          0.001
## 
## Standardized Root Mean Square Residual:
## 
##   SRMR                                           0.065
## 
## Parameter Estimates:
## 
##   Standard errors                             Standard
##   Information                                 Expected
##   Information saturated (h1) model          Structured
## 
## Latent Variables:
##                    Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
##   visual =~                                                             
##     x1                0.900    0.081   11.128    0.000    0.900    0.772
##     x2                0.498    0.077    6.429    0.000    0.498    0.424
##     x3                0.656    0.074    8.817    0.000    0.656    0.581
##   textual =~                                                            
##     x4                0.990    0.057   17.474    0.000    0.990    0.852
##     x5                1.102    0.063   17.576    0.000    1.102    0.855
##     x6                0.917    0.054   17.082    0.000    0.917    0.838
##   speed =~                                                              
##     x7                0.619    0.070    8.903    0.000    0.619    0.570
##     x8                0.731    0.066   11.090    0.000    0.731    0.723
##     x9                0.670    0.065   10.305    0.000    0.670    0.665
## 
## Covariances:
##                    Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
##   visual ~~                                                             
##     textual           0.459    0.064    7.189    0.000    0.459    0.459
##     speed             0.471    0.073    6.461    0.000    0.471    0.471
##   textual ~~                                                            
##     speed             0.283    0.069    4.117    0.000    0.283    0.283
## 
## Variances:
##                    Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
##     visual            1.000                               1.000    1.000
##     textual           1.000                               1.000    1.000
##     speed             1.000                               1.000    1.000
##    .x1                0.549    0.114    4.833    0.000    0.549    0.404
##    .x2                1.134    0.102   11.146    0.000    1.134    0.821
##    .x3                0.844    0.091    9.317    0.000    0.844    0.662
##    .x4                0.371    0.048    7.779    0.000    0.371    0.275
##    .x5                0.446    0.058    7.642    0.000    0.446    0.269
##    .x6                0.356    0.043    8.277    0.000    0.356    0.298
##    .x7                0.799    0.081    9.823    0.000    0.799    0.676
##    .x8                0.488    0.074    6.573    0.000    0.488    0.477
##    .x9                0.566    0.071    8.003    0.000    0.566    0.558
## 
## R-Square:
##                    Estimate
##     x1                0.596
##     x2                0.179
##     x3                0.338
##     x4                0.725
##     x5                0.731
##     x6                0.702
##     x7                0.324
##     x8                0.523
##     x9                0.442
  • lavaan은 첫번째 indicator을 1로 고정하는게 default이므로, NA*로 풀어서 자유모수로 추정케 해야함.
    그리고 나서 요인의 분산을 1로 고정
  • marker indicator를 활용한 방법과 분산을 1로 고정한 방법을 비교해보자
    • model fit index는 정확히 동일하다 두 방법 모두.
      즉, 모형의 결과는 같음. 단지 세부 indicator의 해석만 달라질 뿐.
  • 암튼 여기까지 왔다면, 이제 model fit을 확인해보면 됨.
    내가 만든 모형이 얼마나 data(real world)를 잘 설명하는지 확인하는 과정
    다양한 종류의 model fit indices를 활용함

GOODNESS-OF-FIT INDICES

Part1. Concept and TOOLS

1. Coming of Age

DEFINITION OF SEM

  • 하나의 방법이기 보다는 관련 절차의 종합이라고 보는게 더 타당.
  • structural equation modeling(SEM) = covariance structure analysis, covariance structure modeling …
  • Pearl(2012)은 SEM을 3개의 Input과 3개의 output을 갖는 인과 추론 방법이라고 정의함
    • Input
      1. A set of qualitative causal hypotheses based on theory or results of empirical studies that are represented in a structural equation mode
      2. A set of queries or questions about causal relations among variables of interest (X -> Y ..)
      3. Most applications of SEM are in nonexperimental designs, but data from experimental or quasi-experimental designs can be analyzed
    • Output
      1. Numeric estimates of model parameters
      2. A set of logical implications of the model
      3. testable implications of the model

IMPORTANCE OF THEORY

  • SEM은 이론을 정량화하는 방법. Data에 맞는 Model을 찾는게 아님.

A PRIORI, BUT NOT EXCLUSIVELY CONFIRMATORY

  1. strictly confirmatory
  • 이론에 근거한 모형 하나를 만들고 SEM 적합해보기
  1. alternative models
  • 모형 두어개 만들어서 가장 적합한 것 탐색
  1. model generation
  • 계속 모형을 수정해나가서 가장 좋은 모형 만드는 방법

PROBABILISTIC CAUSATION

  • deterministic causality가 아님
    probabilistic causality임.
  • 확률적 추론일 뿐.

OBSERVED VARIABLES AND LATENT VARIABLES

  • SEM에서 중요한 것 중 하나는 observed(manifest) 변수와 latent 변수의 구별임.
  • observed variable은 연속형 범주형 다 됨.
  • Latent variable은 hypothetical construct 또는 직접 관찰이 불가능한 연속체를 반영함.
    (말이 어려운데 암튼 Latent variable은 연속형만 된다는 의미. 물론 categorical latent variable도 존재함. 보편적인 구조방정식에선 없다는 의미.)
  • observed variable은 construct를 간접적으로 측정하는 indicator로 활용됨.
    이러한 indicator를 통해 만들어진 construct의 통계적 실체는 factor임.
  • 회귀분석에서 모든 측정치는 그 자체로 참값임을 가정하지?
    하지만 실제로는 그렇지 않잖아. 구조 방정식은 측정치의 error term을 허용한단다.
    이는 달리 말해 회귀분석 등의 이런 strict한 가정을 벗어나는 좋은 방법이라는 것.

DATA ANALYZED IN SEM

  • SEM은 기본적으로 공분산(covariance)을 분석함.
    1. 관찰 변수 간에 나타나는 공분산 패턴을 이해하는 것
    2. 연구자의 모형에 따라 분산을 얼마나 잘 설명하는지.
  • 이런게 covariance structure 관련임.
  • 그런데 mean structure도 분석 가능! 하지만 많은 연구에서는 이거 안다뤄.
    필요 없는 경우도 있고 그런데 일단 어렵고 있는지조차 모르는 사람들이 태반

SEM REQUIRES LARGE SAMPLES

  • 물론 적은 샘플로 어케어케 할라고 노력은 하고 있음
  • 숫자가 작으면 추정이 정확하지 않을 가능성이 커
  • 그래서 도대체 얼마면 large enough 하냐?
    1. 모형이 복잡할 수록 샘플은 더 많이 필요
    2. 변수가 연속형이고 정규분포이고 효과가 선형이고 상호작용 없으면 샘플수는 상대적으로 적어도됨
    3. score reliability가 낮으면 larger sample 필요.
    4. 몇몇 경우에는 샘플 사이즈에 대한 고려를 더 잘 해야해
    • factor 당 indicator의 수가 적은 경우
    • factor 수가 많은 경우
    • factor 간 공분산이 작은 경우 …
  • 결론, 샘플 수 몇명이 필요하다는 rule of thumb는 없다.
  • 문항당 20명 정도? 20*q=N, 15문항 -> 300명

LESS EMPHASIS ON SIGNIFICANCE TESTING

  • 회귀분석은 별뜨는거에 집착하지만 SEM에서는 별루,,,
  • SEM은 전체의 그림을 그리는게 중요한거라서 그런 작은 것이 중요한게 아냐
  • 또한, 샘플이 크기 때문에 유의한 경우가 많음.
  • p-value 0.49 0.51 차이가 크니? 댓츠 노노. (걍 통계의 문제)

SEM AND OTHER STATISTICAL TECHNIQUES

  • 그래서 General linear model(GLM) 또는 다변량 기법(multivariate~)이랑 차이가 모야?
  • 단순하게 말해서 SEM의 특수한 형태를 GLM 또는 multvaria~ 라고 볼 수 있엉
    (OLS로 추정하는 regression을 ML 추정하는 SEM으로도 동일하게 추정 가능) SEM은 felxible하고 짱짱맨이라구!
  • 앞에서 연속형이라고 말했던 latent variable은 범주형이 될 수도 있어
    LCA, LTA같은…
  • 시기 생각:
    암튼 SEM은 다른 방법론과 결합하여 아주 다양한 형태로 발전하고 있음.
    여기서 ★! 이라고 중요성 표시해야함. 왜냐!
    방법론의 발전은 다른 형태의 research question 해결과 맞닿아 있으니까

MYTHS ABOUT SEM

  • SEM이 공분산만 분석한다는 것
  • SEM의 인과관계 추론 능력 쩔어?별로?
    그런게 어딨엉. 걍 방법론일 뿐. 리서치 디자인, 이론, 데이터 부터 손봐라. 방법론은 잘못이 없다.

WIDESPREAD ENTHUSIASM, BUT WITH A CAUTIONARY TALE

  • equivalent models
  • confirmation bias
  • SEM의 궁극적 목표 : statistical beauty를 도출하는 것
    1. 이론적 근거
    2. 알고 있는 것과 모르는 것을 구별하고 모형의 장단점 한계 등을 찾기
    3. 이를 통한 새로운 연구 문제 도출

FAMILY HISTORY

  • 1904년 스피어만에서 시작된 EFA에서~~~ 완죤 오래됨.
    즉, 이제 충분히 성숙해진 방법론임.

결론

  • The SEM family of techniques has its origins in regression analyses of observed variables and in factor analyses of latent variables. Essential features include its a priori nature, the potential to explicitly distinguish between observed and latent variables, and the capacity to analyze covariances or means in experimental or nonexperimental designs.


기본 요인 모형

기본 요인 모형

UTUAT

UTUAT-2

Wang & Wang 출처

2. Regression Fundamentals