- 1. 결측치는 왜 신경 써야 하나요? 🤔
- 2. 결측치 처리 방법 정리 ✍️
- (1) 단순 삭제(Dropping)
- (2) 대체(Imputation)
- (3) 결측 가중치 보정 (Inverse Probability Weighting for Missingness)
- 3. 인과추론과 결합할 때 주의사항 🎯
- 4. 결측 구조를 이해하기 위한 Missingness DAG ✏️
- 5. MNAR(Missing Not At Random) 결측과 민감도 분석
- 민감도 분석 방법
- 6. 실전 적용 흐름 🚀
- 1. 데이터 생성 (Simulated Data)
- 2. Multiple Imputation (다중 대체)
- 3. G-Computation 적용
- (1) 결과 모형 학습
- (2) Potential Outcome 계산
- 4. 요약 🚀
- 5. 마무리 🎯
데이터 분석을 할 때 결측치(Missing data)는 흔하게 발생합니다.
하지만 인과추론(Causal Inference)을 목표로 할 때,
결측치를 제대로 다루지 않으면 심각한 오류가 생길 수 있습니다. 🔥
오늘은 결측치 처리 방법과 인과추론을 결합해서,
실제로 실무에 적용 가능한 깊이 있는 방법을 정리합니다. 🚀
1. 결측치는 왜 신경 써야 하나요? 🤔
일반 데이터 분석에서는 결측치가 그저 “귀찮은 것”일 수 있습니다.
하지만 인과추론에서는 결측이 다음과 같은 문제를 일으킵니다.
문제 | 설명 |
Selection Bias | 결측 때문에 특정 집단만 분석되면, 인과추론 결과가 왜곡됩니다. |
Collider Bias | 결측 변수(또는 그 자식)를 조정할 경우 인과구조가 깨질 수 있습니다. |
Confounding Error | 중요한 혼란변수(confounder)에 결측이 생기면 인과추정이 무너질 수 있습니다. |
✅ 결론:
결측치는 인과추론을 근본부터 망가뜨릴 수 있다.
2. 결측치 처리 방법 정리 ✍️
(1) 단순 삭제(Dropping)
- 결측이 완전 무작위(MCAR)일 때만 괜찮습니다.
- 현실에서는 MCAR이 거의 없기 때문에 위험합니다.
✅ 인과추론에서는 최소 권장 방법입니다.
(2) 대체(Imputation)
- 결측값을 예측하여 채우는 방법입니다.
단순 대체 (Simple Imputation)
- 평균, 중앙값 등으로 대체합니다.
- 하지만 변동성 왜곡 가능성 때문에 인과추론에는 권장되지 않습니다.
다중 대체 (Multiple Imputation, MI)
- 결측을 여러 번 다르게 채우고,
- 각 데이터셋을 분석한 후 결과를 결합합니다 (Rubin’s Rule 적용).
✅ 인과추론에서는 Multiple Imputation을 가장 권장합니다.
(3) 결측 가중치 보정 (Inverse Probability Weighting for Missingness)
- 결측이 생길 확률을 모델링합니다.
- 관측된 데이터에 가중치를 부여하여 대표성을 회복합니다.
✅ 특히 IPTW 등 가중치 기반 인과추론과 잘 결합할 수 있습니다.
3. 인과추론과 결합할 때 주의사항 🎯
항목 | 설명 |
Imputation 모델에 인과변수 포함 | Treatment, Outcome, Confounder 모두 포함해야 합니다. |
분석모델과 일관성 유지 | Imputation에 사용한 변수로 인과추론도 진행해야 합니다. |
Rubin’s Rule 적용 | 다중 대체한 결과를 평균내고, 표준오차까지 결합해야 합니다. |
✅ 무심하게 Imputation만 하고 인과추론을 적용하면, 가짜 인과효과가 만들어질 수 있습니다.
4. 결측 구조를 이해하기 위한 Missingness DAG ✏️
결측이 왜 생겼는지 인과적으로 표현하기 위해 Missingness DAG를 그릴 수 있습니다.
예시:
Treatment (A) → Outcome (Y)
↓
Missingness (R)
- A가 R에 영향을 준다면, 결측은 비무작위(MNAR)일 수 있습니다.
- 결측구조를 시각적으로 파악하면, 결측 처리 전략을 정확히 설정할 수 있습니다.
5. MNAR(Missing Not At Random) 결측과 민감도 분석
만약 결측이
- 관측되지 않은 값 자체에 영향을 받는다면 (ex: 죽은 환자 기록 누락)
- → 이것은 MNAR입니다.
✅ MNAR은 일반적인 Imputation만으로 해결되지 않습니다.
✅ 민감도 분석(Sensitivity Analysis)을 반드시 진행해야 합니다.
민감도 분석 방법
방법설명
방법 | 설명 |
Delta Adjustment | Imputed 값에 편향(bias)을 일부러 추가하여 분석합니다. |
Pattern Mixture Model | 결측 패턴별로 다른 모델을 세워 비교합니다. |
Selection Model | 결측과 결과를 함께 모델링합니다. |
6. 실전 적용 흐름 🚀
1. 결측 기전 분석 (MCAR, MAR, MNAR 구분)
2. 적절한 보정 방법 적용 (MI, IPW 등)
3. 인과추론 분석 적용 (PSM, IPTW, G-Computation 등)
4. 필요시 MNAR 민감도 분석 수행
5. 최종 인과추정 결과 도출
📚 G-Computation with Multiple Imputation (MI) 상세 실습
G-Computation은 인과추론(Causal Inference)에서
“만약 모두가 어떤 처치를 받았다면, 결과가 어땠을까?”
를 모형화하여 추정하는 방법입니다. 🚀
하지만 현실 데이터에는 결측(Missing)이 흔합니다.
이때 Multiple Imputation (MI) 를 이용하여 결측을 보정하고,
G-Computation을 적용하면
보다 신뢰성 높은 인과추정을 할 수 있습니다.
이번 글에서는
실제 데이터 시뮬레이션 + MI + G-Computation 적용 과정을 순서대로 보여드립니다.
1. 데이터 생성 (Simulated Data)
import numpy as np
import pandas as pd
np.random.seed(42)
# 가상의 데이터 생성
n = 1000
age = np.random.normal(50, 10, n) # 나이
treatment = np.random.binomial(1, 0.5, n) # 처치 여부 (0 or 1)
baseline_health = np.random.normal(0, 1, n) # 기저 건강상태
# 결과 생성 (처치 효과 존재)
outcome = 3 * treatment + 0.5 * age + 2 * baseline_health + np.random.normal(0, 5, n)
# 일부 변수에 결측 생성
age[np.random.choice(n, 100, replace=False)] = np.nan
baseline_health[np.random.choice(n, 80, replace=False)] = np.nan
# 데이터프레임 구성
df = pd.DataFrame({
'treatment': treatment,
'age': age,
'baseline_health': baseline_health,
'outcome': outcome
})
df.head()
✅ 여기까지 결측이 포함된 데이터를 만들었습니다.
2. Multiple Imputation (다중 대체)
결측값을 여러 번 채워서 불확실성을 반영합니다.
from sklearn.experimental import enable_iterative_imputer
from sklearn.impute import IterativeImputer
# IterativeImputer (MICE 방식) 사용
imputer = IterativeImputer(random_state=42, sample_posterior=True, max_iter=10)
# Imputation 수행
imputed_data = imputer.fit_transform(df)
# Imputed 데이터프레임
df_imputed = pd.DataFrame(imputed_data, columns=df.columns)
df_imputed.head()
✅ sample_posterior=True를 통해 imputation 간 불확실성을 반영했습니다.
3. G-Computation 적용
모형화(Outcome Regression) 기반으로 Potential Outcome을 추정합니다.
(1) 결과 모형 학습
import statsmodels.api as sm
# X, y 분리
X = df_imputed[['treatment', 'age', 'baseline_health']]
X = sm.add_constant(X) # 절편 추가
y = df_imputed['outcome']
# 선형회귀모형 적합
model = sm.OLS(y, X).fit()
# 회귀 결과 요약
print(model.summary())
✅ 여기서 treatment의 회귀계수가 처치의 효과를 나타냅니다.
(2) Potential Outcome 계산
모든 환자가 treatment=1을 받았을 경우,
모든 환자가 treatment=0을 받았을 경우를 가정하여 결과를 예측합니다.
# 모든 환자가 treatment를 1로 가정
X_treated = df_imputed.copy()
X_treated['treatment'] = 1
# 모든 환자가 treatment를 0으로 가정
X_control = df_imputed.copy()
X_control['treatment'] = 0
# 예측값 계산
X_treated_ = sm.add_constant(X_treated[['treatment', 'age', 'baseline_health']])
X_control_ = sm.add_constant(X_control[['treatment', 'age', 'baseline_health']])
y_treated_pred = model.predict(X_treated_)
y_control_pred = model.predict(X_control_)
# 평균 차이
g_computation_ate = y_treated_pred.mean() - y_control_pred.mean()
print(f"G-Computation으로 추정한 ATE: {g_computation_ate:.3f}")
✅ 이 차이가 Average Treatment Effect (ATE), 즉
“처치가 결과에 미친 평균적인 영향”입니다.
4. 요약 🚀
단계 | 설명 |
데이터 생성 | 결측 포함 가상 데이터 구성 |
결측 보정 (MI) | Iterative Imputer로 다중 대체 |
결과 모형 적합 | treatment + covariates로 outcome 예측모형 |
Potential Outcome 예측 | treatment=1 vs treatment=0 모두 시뮬레이션 |
ATE 계산 | 두 집단 예측 결과 평균 차이 |
5. 마무리 🎯
G-Computation은 결측이 있더라도 MI를 통해 보정하고, 인과적 효과를 추정할 수 있는 강력한 방법입니다.
✅ 단, 중요한 조건은
- 결측치 처리(Imputation)를 제대로 해야 하고,
- 모형 설정(Outcome Model)이 잘 되어야 한다는 점입니다.
✨ 최종
결측치는 단순한 데이터 손실이 아닙니다.
인과적 관계를 심각하게 왜곡할 수 있는 요소입니다.
✅ 결측의 기전을 이해하고,
✅ 적절한 방법으로 보정하며,
✅ 인과추론 흐름에 녹여야
진짜 신뢰할 수 있는 결과를 만들 수 있습니다.
🎯 오늘의 핵심 요약
결측을 무시하면 인과추론은 무너진다.
결측을 이해하고 보정하면, 인과추론의 신뢰성이 높아진다.
'데이터분석' 카테고리의 다른 글
📊 의료 논문에서 꼭 나오는 통계 지표 9가지 완전 정복 (0) | 2025.05.20 |
---|---|
[생존분석] RMST vs. AFT 모델 완전 정리 (2) | 2025.05.16 |
[데이터분석] 📊 이상치(Outlier) 처리, 완전 실무형 정리 (2) | 2025.04.26 |
[데이터분석]🧹 결측, 그 빈칸을 채우는 법 (3) | 2025.04.25 |
[메타 분석] (Meta-analysis) 완벽 정리 가이드📚 (0) | 2025.04.21 |