Double ML: Residual on Residual Regression + Cross-Fitting
- 통제 변수를 조정하여 잔차 회귀(Residual on Residual Regression)와 교차 적합(Cross-Fitting)을 결합하여 사용합니다.
- 장점
- 편향 감소: 잔차 회귀를 통해 통제 변수의 영향을 제거하여 인과 효과 추정의 편향을 줄입니다.
- 일관성 보장: 교차 적합을 통해 과적합을 방지하고 추정의 일관성을 보장합니다.
- 유연성: 다양한 기계 학습 모델과 함께 사용할 수 있어 다양한 데이터에 적용 가능합니다.
- 단점
- 복잡성 증가: 두 단계의 모델 학습과 교차 적합 과정으로 인해 복잡성이 증가합니다.
- 계산 비용: 많은 데이터와 복잡한 모델을 사용할 경우 계산 비용이 높아질 수 있습니다.
- 대안
- DR Learner: 이중 견고 회귀(Doubly-Robust Regression)와 교차 적합을 결합하여 보다 강력한 추정을 제공합니다.
- IV (Instrumental Variables): 도구 변수를 사용하여 내생성을 해결하는 방법입니다.
DR Learner: Doubly-Robust Regression + Cross-Fitting
- 이중 견고 회귀(Doubly-Robust Regression)와 교차 적합(Cross-Fitting)을 결합하여 인과 효과를 추정하는 방법입니다.
- 장점
- 견고성: 두 가지 모델을 사용하여 하나의 모델이 잘못되어도 추정의 편향을 줄일 수 있습니다
- 일관성 보장: 교차 적합을 통해 과적합을 방지하고 추정의 일관성을 보장합니다
- 강력한 추정: 복잡한 데이터 구조에서도 인과 효과를 정확하게 추정할 수 있습니다.
- 단점
- 복잡성 증가: 두 가지 모델을 학습하고 교차 적합을 수행하는 과정이 복잡합니다.
- 계산 비용: 많은 데이터와 복잡한 모델을 사용할 경우 계산 비용이 높아질 수 있습니다.
- 대안
- Double Machine Learning: 잔차 회귀와 교차 적합을 결합하여 편향을 줄이고 일관성을 보장합니다.
- IPW (Inverse Probability Weighting): 처치 확률의 역수를 가중치로 사용하여 추정하는 방법입니다.
Sample
import numpy as np
import pandas as pd
from sklearn.linear_model import LinearRegression
from sklearn.model_selection import KFold
# 데이터 생성
np.random.seed(42)
n = 1000
X = np.random.normal(size=(n, 5))
T = np.random.binomial(1, 0.5, size=n)
Y = 2 * T + X[:, 0] + np.random.normal(size=n)
# Double ML 구현
kf = KFold(n_splits=5)
treatment_effects = []
for train_index, test_index in kf.split(X):
X_train, X_test = X[train_index], X[test_index]
T_train, T_test = T[train_index], T[test_index]
Y_train, Y_test = Y[train_index], Y[test_index]
# 잔차 회귀
model_y = LinearRegression().fit(X_train, Y_train)
model_t = LinearRegression().fit(X_train, T_train)
Y_residual = Y_train - model_y.predict(X_train)
T_residual = T_train - model_t.predict(X_train)
# 잔차 회귀 모델 적합
treatment_effect_model = LinearRegression().fit(T_residual.reshape(-1, 1), Y_residual)
treatment_effect = treatment_effect_model.coef_[0]
treatment_effects.append(treatment_effect)
print(f"Double ML Treatment effect: {np.mean(treatment_effects)}")
# DR Learner 구현
treatment_effects = []
for train_index, test_index in kf.split(X):
X_train, X_test = X[train_index], X[test_index]
T_train, T_test = T[train_index], T[test_index]
Y_train, Y_test = Y[train_index], Y[test_index]
# 결과 모델 및 처치 모델 학습
model_y = LinearRegression().fit(X_train, Y_train)
model_t = LinearRegression().fit(X_train, T_train)
# 예측
Y_hat = model_y.predict(X_test)
T_hat = model_t.predict(X_test)
# 이중 견고 회귀
dr_model = LinearRegression().fit(T_test.reshape(-1, 1), Y_test - Y_hat + (T_test - T_hat) * treatment_effect)
treatment_effect = dr_model.coef_[0]
treatment_effects.append(treatment_effect)
print(f"DR Learner Treatment effect: {np.mean(treatment_effects)}")
Double ML Treatment effect: 2.1014653090054765
DR Learner Treatment effect: 8.318565053747836