PLS-SEM in R: cSEM 패키지 활용 튜토리얼

Data science
Author

Iron Hong

Published

May 5, 2025

1.서론

최근 사화과학 뿐만 아나라 다양한 공학, 자연과학 분야에서도 요인분석에 더불어 구조방정식 모형을 활용한실증적 연구가 급격히 증가하는 양상이 있다. 그동안 많은 연구에서는 공분산 기반(covariance-based) CB-SEM 중심으로 이루져 왔지만, 요즘은 방법론적으로 기존의 CB-SEM에서 나타난 문제점이나 한계를 보완할 수 있다는 하나의 대안으로, 분산 기반(variance-based) VB-SEM(또는 복합 SEM)을 이용한 연구들도 지속적으로 증가하고 있다.

2.VB 기반 구조방정식모형

두가지 접근 방법은 공통적으로 관측변수로 통해 복잡한 요인들의 관계를 통계적으로 파악한다는 점에서 비슷하지만 활용 목적, 분석 데이터 분포, 표본 크기 등 여러 측면에서 차이가 있다. 예컨대, 분산 기반(VB-SEM)은 예측과 복잡한 모형의 탐색에, 공분산 기반(CB-SEM)은 이론 검증과 모형 적합도 확인에 여점을 둔다. 나아가 CB-SEM은 분석 데이터가 정규분포를 따른다고 가정하며 이론 모델과 실제 공분산 행렬의 차이를 최소화하는 반면, VB-SEM은 분포 가정이 없고 내생변수의 분산을 최대화하여 예측력을 높이는 데 집중한다. 그리고 표본 크기에 있어서 CB-SEM은 보통 200개 이상의 관측치가 필요하지만, VB-SEM은 표본 크기의 제약을 덜 받아서 관측치가 적은 소표본에서도 분석이 가능하다.

특히 VB-구조방정식 모형은 외부 모형(outer model)과 내부 모형(inner model)으로 구성되어 있다. 외부모형은 관측변수들(manifest variables)과 잠재변수(latent variables)와의 관계에 관한 모형이다. 내부모형은 잠재변수들 간의 관계에 대한 모형이다. 이 부분에 대해 CB-구조방정식 모형에서는 외부 모형을 측정 모형(measurement model)으로, 외부 모형을 구조 모형(structural model)이라고 한다.

이미 다양한 통계 프로그램이나 도구를 통해 CB-SEM을 다루는 가이드가 많이 존재하므로, 이 튜토리얼(Tutorial)은 주로 최신 R 패키지(cSEM)를 이용하여 VB-SEM 관련해서 실증연구에 유용한 분석방법들을 간단하게 소개하고자 한다.

3.cSEM

cSEM 패키지1는 Rademaker 외(2020)가 VB-SEM을 다루기 위해 개발한 것이다. 그들은 VB-SEM을 복합모형(composite model) 또는 복합 기반 SEM이라고도 한다. 한편, 기존 CB-SEM 분석을 대중적으로 많이 이용한 lavaan 패키지 모형 문법(model syntax)으로 다뤄왔다면 거의 비슷한 문법(또는 코딩법)을 사용한다 점에서cSEM 패키지를 이용하는 데에 큰 어려움이 없을 것이다.

Workflow는 대략 1) 데이터 준비, 2)모형 설정, 3)모형 실행, 4)사후 추정으로 진행:

# R
# 0) (옵션) 패키지 설치
if (!requireNamespace("cSEM", quietly = TRUE)) install.packages("cSEM")

library(cSEM)

# 1) 데이터 준비 (시뮬레이션)
set.seed(123)
N <- 300
ATT <- rnorm(N)
SAT  <- 0.6 * ATT + rnorm(N, sd = 0.8)
LOY  <- 0.5 * SAT + 0.2 * ATT + rnorm(N, sd = 0.7)

att1 <- 0.8 * ATT + rnorm(N, sd = 0.6)
att2 <- 0.85 * ATT + rnorm(N, sd = 0.6)
att3 <- 0.75 * ATT + rnorm(N, sd = 0.6)
sat1 <- 0.8 * SAT + rnorm(N, sd = 0.6)
sat2 <- 0.82 * SAT + rnorm(N, sd = 0.6)
sat3 <- 0.78 * SAT + rnorm(N, sd = 0.6)
loy1 <- 0.8 * LOY + rnorm(N, sd = 0.6)
loy2 <- 0.83 * LOY + rnorm(N, sd = 0.6)
loy3 <- 0.77 * LOY + rnorm(N, sd = 0.6)

df <- data.frame(att1, att2, att3, sat1, sat2, sat3, loy1, loy2, loy3)
head(df)

# 2) 모형 설정 (cSEM 문법: 잠재변수 =~ 지표, 회귀식은 ~)
model_txt <- "
ATT =~ att1 + att2 + att3
SAT =~ sat1 + sat2 + sat3
LOY =~ loy1 + loy2 + loy3
SAT ~ ATT
LOY ~ SAT + ATT
"
model <- parseModel(model_txt)

# 3) 모형 실행 (PLS-PM 기본 가중치 방식)
res <- csem(.data = df, .model = model)

# 4) 사후 추정 (요약, 적합/신뢰도, 부트스트랩 추정 예)
# 요약 출력 (cSEM::summarize 호출 — dplyr 충돌방지)
csem::summarize(res)

# 경로·요인적재 등 추정치 접근
res$Estimates$Path_estimates
res$Estimates$Loading_estimates
res$Estimates$Construct_scores    # 관측된 표본별 구성점수 (행=사례, 열=구성)

# 신뢰도·타당도 지표(예: reliabilities, AVE, R2)
res$Estimates$Reliabilities
res$Estimates$R2

# 적합/타당성 평가
csem::assess(res)

# 부트스트랩을 통한 추정치 신뢰구간 (예: 499 반복)
res_inf <- csem::infer(res, .R = 499)
csem::summarize(res_inf)   # 부트스트랩 결과 요약

# 결과 객체 반환
res

4.마무리

Stata에서도 PLS-SEM 모형을 추정할 수 있는 페키지 plssem가 있다. 향후 추정결과를 비교하면서 함께 연습해보는 것도 나쁘지 않을 것 같다.