데이터

(스터디) 실무로 통하는 인과추론 with 파이썬 - PART 3

Yuniverse. 2024. 11. 22. 19:21

 

[실무로 통하는 인과추론 with 파이썬]을 읽고 내용을 정리한다.

(스터디) 실무로 통하는 인과추론 with 파이썬 - PART 2에서 이어집니다.

 


PART 3. 이질적 효과와 개인화

6장 이질적 처치효과

실험 대상 i마다 처치 효과 Γi가 다를 수 있다. 어떤 대상이 처치에 더 잘 반응하는지 아는 것은 처치 대상을 결정하는 데 중요한 역할을 한다.

ex) 할인에 더 민감한 고객이라면 할인 쿠폰을 주면 유익하지만, 그렇지 않다면 쿠폰의 효과가 없을 수 있다. 

 

평균 처치효과 ATE

이산형일 때

연속형일 때
조건부 평균 처치효과 CATE
: X에 대한 조건부는 각 실험 대상이 공변량 X로 정의된 특성에 따라 처치효과가 다를 수 있음을 의미한다.

 

머신러닝의 목적: 결과(Y) 예측 <> CATE의 목적: 결과에 미치는 처치(X)의 효과 추정

개별 대상 수준의 기울기를 한번에 알아낼 수 없으니, 다양한 처치 조건에서 실험 대상 관측을 통해 추정한다.

 

ATE와 마찬가지로, CATE도 회귀변수를 통해 추정할 수 있다.

→ 처치와 공변량 간의 상호작용을 모델에 포함하여, 해당 공변량에 따라 효과가 어떻게 변하는지 모델이 학습할 수 있게 한다.

  1. 공변량을 정의한다.
  2. 해당 공변량과 처치의 상호작용 항을 포함한다.
  3. 모델을 추정하고, 예측된 기울기를 매개변수 추정값으로부터 추출한다.
  4. 데이터셋을 train과 test로 나누어서 train에서는 회귀모델을, test에서는 예측모델을 수행하여 CATE 예측을 평가한다.

 

랜덤화된 데이터가 없으면 추정할 수 있는 그룹 효과로서의 CATE 개념이 유효하지 않다. (CATE 추정할 때는 랜덤화된 데이터가 무엇보다 중요하다.)

 

7장 메타러너

메타러너(metalearner):

  • 기존 예측 머신러닝 알고리즘을 활용해서 처치효과를 추정하는 방법
  • ATE 추정에 사용할 수 있지만, 일반적으로는 CATE 추정에 주로 사용한다. (고차원 데이터를 잘 처리하기 때문)

 

S 러너: 가장 기본적인 방식으로, 단일 머신러닝 모델을 사용하여 추정한다. 처치효과를 직접 출력하지는 않고, 반사실 예측값을 구한다. → 다양한 처치에서의 예측이 가능하다. (T 러너, X 러너와 달리 연속형 처치에서도 사용 가능) 처치효과를 0으로 편향시키려는 경향이 있다.

from lightgbm import LGBMRegressor

X = ["month", "weekday", "is_holiday", "competitors_price"]
T = "discounts"
y = "sales"

np.random.seed(123)
s_learner = LGBMRegressor()
s_learner.fit(train[X+[T]], train[y]);

 

 

T 러너: 잠재적 결과 Yt를 추정하기 위해 모든 처치에 대해 하나의 결과 모델 μt(x)를 적합시킨다. 단순하여 구현이 쉽다는 장점이 있지만, 상황에 따라 정규화 편향이 발생하기 쉽다.

ㅊμ0(x)=E[Y❘T=0,X], μ1(x)=E[Y❘T=1,X]

from lightgbm import LGBMRegressor

np.random.seed(123)

m0 = LGBMRegressor()
m1 = LGBMRegressor()

m0.fit(train.query(f"{T}==0")[X], train.query(f"{T}==0")[y])
m1.fit(train.query(f"{T}==1")[X], train.query(f"{T}==1")[y]);

t_learner_cate_test = test.assign(
	cate=m1.predict(test[X]) - m0.predict(test[X])
)

 

 

X 러너: T 러너보다 복잡하다. 실험군과 대조군의 표본 크기 차이가 클 경우, X 러너의 성능이 훨씬 좋다.

앞서 적합된 모델을 사용하여 누락된 잠재적 결과를 추정한다.

from sklearn.linear_model import LogisticRegression
from lightgbm import LGBMRegressor

# 성향점수 모델
ps_model = LogisticRegression(penalty='none')
ps_model.fit(train[X], train[T])


# 첫 번째 단계 모델
train_t0 = train.query(f"{T}==0")
train_t1 = train.query(f"{T}==1")
m0 = LGBMRegressor()
m1 = LGBMRegressor()
np.random.seed(123)

m0.fit(train_t0[X], train_t0[y],
	   sample_weight=1/ps_model.predict_proba(train_t0[X])[:, 0])

m1.fit(train_t1[X], train_t1[y],
	   sample_weight=1/ps_model.predict_proba(train_t1[X])[:, 1]);
 

# 두 번째 단계 모델
tau_hat_0 = m1.predict(train_t0[X]) - train_t0[y]
tau_hat_1 = train_t1[y] - m0.predict(train_t1[X])

m_tau_0 = LGBMRegressor()
m_tau_1 = LGBMRegressor()

np.random.seed(123)

m_tau_0.fit(train_t0[X], tau_hat_0)
m_tau_1.fit(train_t1[X], tau_hat_1);


# CATE 추정 단계
ps_test = ps_model.predict_proba(test[X])[:, 1]

x_cate_test = test.assign(
	cate=(ps_test*m_tau_0.predict(test[X]) +
    	(1-ps_test)*m_tau_1.predict(test[X])
        )
)

 

S 러너 T 러너 X 러너


S 러너는 단순히 특성 중의 하나로 처치를 포함하는 머신러닝 모델이다.


T 러너가 각자 T = 1, T = 0에서 머신러닝 모델을 학습한다. 예측 시점에 두 모델을 모두 사용해서 실험군과 대조군의 차이를 추정한다.


X 러너는 두 가지 단계에서 머신러닝 모델과 성향점수 모델을 학습한다. 예측 시, 두 번째 단계의 모델과 성향점수 모델만 활용한다.

 

 

이중/편향 제거 머신러닝 또는 R 러너:

ATE 편향 문제를 해결하기 위해 나온 방법으로, FWL 정리의 정제된 버전으로 볼 수 있다.

결과와 처치의 잔차를 구성할 때 머신러닝 모델을 사용하는 방법

 

관측되지 않은 교란 요인이 없다면, 다음과 같은 직교화 과정으로 ATE를 구할 수 있다.

  1. 머신러닝 회귀 모델 μy를 사용하여 특성 로 결과  추정
  2. 머신러닝 회귀 모델 μt를 사용하여 특성 로 처치  추정
  3. 잔차 Y~=Y−μy(X)와 T~=T−μt(X) 계산
  4. 결과의 잔차를 처치 잔차에 회귀 → Y~=α+τT~에서 는 인과 매개변수 ATE이며, OLS를 사용하여 추정할 수 있다.

 

과적합 문제 발생시 잔차 회귀 결과가 0에 편향될 수 있다. → 교차 예측과 아웃 오브 폴드 잔차

더보기

교차 예측과 아웃 오브 폴드 잔차: 데이터를 K개의 폴드로 분할하고, 그중 K-1개의 폴드에서 모델을 추정한 후 남겨진 폴드에서 잔차를 얻는다. 전체 데이터셋에 대한 잔차를 얻기 위해 동일한 과정을 K번 반복한다. 이러한 방식을 사용하면 모델이 과적합되더라도 잔차를 의도적으로 0으로 만들지 않는다.

 

인과 손실 함수: 손실의 제곱을 최소화하면 CATE 추정이 가능하다. (= R 손실)

y_star = y_res/t_res
w = t_res**2

cate_model = LGBMRegressor().fit(train[X], y_star, sample_weight=w)

test_r_learner_pred = test.assign(cate = cate_model.predict(test[X]))