Data Analysis & ML/인과추론

[인과 추론] 선형회귀와 인과추론 (1) - 프리슈-워-로벨 정리(Frisch-Waugh-Lovell)(FWL)

YSY^ 2025. 2. 16. 18:56

선형회귀와 인과추론

  • 차원의 저주(curse of eimensionality) : 특성이 너무 많을 때 생기는 현상. 각 셀에서 ATE를 추정하고 결과의 평균값을 구하려면 엄청난 양의 데이터가 있어야함
  • 데이터 희소성(data sparsity) : 차원의 저주로 인해 공변량이 많을 때 보정 공식을 그대로 적용할때 겪는 문제
  • 차원의 저주에서 벗어나는 방법은 잠재적 결과를 선형회귀방식으로 모델링할 수 있다고 가정한 후 X로 정의된 각각의 셀을 내삽 및 외삽하는 것. -> 즉, 선형회귀분석은 차원축소 알고리즘과 유사하게됨.

CF) 인과추론과 머신러닝 용어 비교

  • 특성 : 공변량 or 독립변수
  • 가중치 : 매개변수 or 계수
  • 목표 : 결과 or 종속변수

이 포스팅에서는 OLS회귀분석이 주로 쓰이며 해당 회귀분석에 대한 내용은 아래 포스팅 참고바랍니다.

https://ysyblog.tistory.com/119

 

[회귀분석] 회귀분석 실습(1) - OLS 회귀분석 결과 해석 및 범주형 변수 처리 (Statsmodel)

Statsmodel을 활용한 회귀분석statsmodels 패키지에서는 OLS 클래스를 사용하여 선형 회귀분석을 실시한다독립변수와 종속변수가 모두 포함된 데이터프레임이 생성되며, 상수항 결합은 하지 않아도

ysyblog.tistory.com

 

A/B Test와 회귀분석

EX) 추천시스템의 효과를 측정, 1/3만 무작위로 골라 새 추천 시스템을 적용하고 1달 후 하루 평균 시청시간 수집

  • 무작위로 배정되었기 때문에 평균 시청 시간의 단순 비교만으로도 ATE를 알 수 있음. 하지만 통계적 유의성을 확인하는 절차를 거쳐야함
  • A/B Test 결과를 회귀분석으로 해석 하면 필요한 모든 추론 통계량(inference statistcs)를 바로 얻을 수 있음

Challenger는 새로운 추천시스템이 적용되면 1 아니면 0

import statsmodels.formula.api as smf
result = smf.ols('watch_time ~ C(recommender)',
data=data).fit()
result.summary().tables[1]

  • 여기서 절편(intercept)는 모델의 다른 변수가 0일 때 결과의 기대값을 알려줌. 즉 기존 버전의 추천 시스템을 사용했을 때 고객이 하루 평균 2.04시간동안 스트리밍 콘텐츠를 시청한다는 의미
  • 매개변수 추정값(C)위 추정값(coef)는 0.14로 새 추천시스템이 평균적으로 하루 시청시간을 0.14시간을 늘렸다는 의미. 하지만 p값을 봤을 때 이 수치는 통계적으로 유의하지 않음

 

회귀분석을 통한 보정

EX) 신용 한도가 채무 불이행률에 미치는 영향 추정 

CF) 데이터 예시.  신용한도(Credit_limit)가 처치이고 default가 채무 불이행률임.

Wage educ exper married credit_score1 credit_score2 credit_limit default
95 011 16 1 500 518 3200 0
  • 신용한도가 1달러 증가했을 때 채무불이향률이 얼마나 변할지에 대한 기댓값을 나타냄

관련수식

model = smf.ols('default ~ credit_limit',data=risk_data).fit()
model.summary().tables[1]

  • 하지만 은행은 위험이 적은 고객에게 더 높은 한도를 주는 경향이 있기 때문에(교란 발생) 베타(coef)는 음의 추정값을 가지게 됨.

  • 이 편향을 보정하려면, 모든 교란요인에 따라 데이터를 나누고, 나눈 각 가룹내에서 채무불이향률을 신용한도에 회귀하고 기울기 매개변수 추출을 통해 결과의 평균을 구해야함
  • 하지만 차원의 저주로 인해 교란요인이 여러개가 되면 데이터 희소성 문제가 발생.
  • 따라서 교란요인 보정대신 OLS로 추정할 모델에 단순히 교란 요인을 추정하면 됨.

  • X는 교란요인의 백터이고 θ는 교란요인과 관련된 매개변수의 백터. 다르게 표현한 이유는 편향되지 않은 β1의 추정값을 얻는데 도움이 되는 매개변수. 이를 장애모수(nuisance parameter)로 부름
  • 이에따라 신용점수와 임금을 교란요인으로 모델에 추가할 수 있음

  • 이제 여기서 β1은 모델의 다른 변수가 고정된 상태에서 신용 한도를 조금 늘렸을 때 채무불이향률이 얼마나 변할지에 대한 기댓값임.
formula = 'default ~ credit_limit + wage+credit_score1+credit_score2'
model = smf.ols(formula, data=risk_data).fit()
model.summary().tables[1]

  • 여기서 신용한도 1달러를 늘렸을 때 채무불이행률이 증가하는 수치는 굉장히 작다. 하지만 보통 신용한도를 1000달러 이상의 단위로 올리므로, 단위를 바꾼다면 채무불이행률의 증가폭은 좀더 클 것이다.

 

프리슈-워-로벨 정리(Frisch-Waugh-Lovell)(FWL)와 직교화 

  • FWL 스타일의 직교화는 가장 먼저 사용할 수 있는 편향 제거(debiasing) 방법
  • 이 방법은 비실험(nonexperimental) 데이터를 처치가 무작위로 배정된 것처럼 보이게함.

FWL정리에 따른 추정과정

  1. 편향 제거 단계 : 처치 T를 교란요인 X에 회귀하여 처치 잔차를 구함
  2. 잡음 제거 단계 : 결과 Y를 교란 요인 X에 대해 회귀하여 결과잔차를 구함
  3. 결과 모델 단계 : 결과잔차를 처치잔차에 대해 회귀하여 T가 Y에 미치는 인과효과 추정값을 구함

 

편향 제거 단계

  • FWL 정리에 따르면 교란요인으로부터 처치인 신용 한도를 예측하는 회귀 모델을 적합시켜 데이터의 편향 제거 가능
  • 이후 신용한도에 대한 잔차를 구함

  • 필요에 따라 평균 처치를 다시 추가할 수 있음

debiasing_model = smf.ols('credit_limit ~ wage + credit_score1 + credit_score2',data=risk_data).fit()
risk_data_deb = risk_data.assign(
     # for visualization, avg(T) is added to the residuals
    credit_limit_res=(debiasing_model.resid + risk_data["credit_limit"].mean())
)

# 이후 default를 편향제거된 처치인(credit_limit_res)에 회귀
model_w_deb_data = smf.ols('default ~ credit_limit_res', data=risk_data_deb).fit()
model_w_deb_data.summary().tables[1]
  • default를 편향제거 된 처치에 회귀하면 편향 제거 모델에 사용된 교란 요인들을 통제하면서 신용한도가 채무불이향률에 미치는 영향 파악

  • p값이 이전보다 높아졌는데 그 이유는 분산 감소를 담당하는 잡음제거 단계를 거치치 않았기 때문
  • 하지만 이 단계만 적용해도 신용 한도가 채무불이행률에 미치는 인과적 영향에 대해 편향되지 않은 추정값을 얻을 수 있음

편향 제거된 버전의 신용 한도와 채무불이행률의 관계. 두 변수 사이의 관계가 하양선을 그리지 않음

잡음 제거 단계

  • 잡음 제거 단계는 편향 제거단계보다 중요하지 않지만 포함하면 좋음
  • 처치효과의 추정값이 바뀌지는 않지만 분산을 줄일 수 있기 때문
  • 결과를 처치가 아닌 공변량에 대해 회귀를 하며 그 결과 처치가 아닌 공변량에 대해 회귀함.

  • 시각화 목적으로 잡음이 제거된 채무불이행률에 평균 채무불이행률을 더할 수 있음

denoising_model = smf.ols('default ~ wage + credit_score1 + credit_score2',data=risk_data_deb).fit()
risk_data_denoise = risk_data_deb.assign(default_res=denoising_model.resid +risk_data_deb["default"].mean())

 

회귀 추정량의 표준오차

  • 회귀 표준오차의 계산법

model_se = smf.ols( 'default ~ wage + credit_score1 + credit_score2', data=risk_data ).fit()
print("SE regression:", model_se.bse["wage"])

model_wage_aux = smf.ols('wage ~ credit_score1 + credit_score2',data=risk_data ).fit()

# subtract the degrees of freedom - 4 model parameters - from N.
se_formula = (np.std(model_se.resid) /(np.std(model_wage_aux.resid)*np.sqrt(len(risk_data)-4)))
print("SE formula: ", se_formula)

  • 분자에서 결과를 잘 예측할 수록 잔차가 작아지므로 추정값의 분산이 낮아짐. 이부분이 잡음제거 단계의 핵심임.
  • 처치가 결과를 많이 설명하면 매개변수 추정값의 표준오차도 작아짐
  • 오차는 잔차회된 처치의 분산에 반비례. 즉 처치가 많이 바뀌면 그 영향을 측정하기 쉬워짐.

최종 결과 모델

  • 결과모델은 결과잔차를 처치잔차에 대해 회귀하여 T가 Y에 미치는 인과효과 추정값을 구하면 된다.
 model_w_orthogonal = smf.ols('default_res ~credit_limit_res',data=risk_data_denoise).fit()
 model_w_orthogonal.summary().tables[1]

  • 편향 제거 단계에서 얻은 매개변수 추정값은 신용 한도와 다른 모든 공변량을 사용하여 회귀했을 때와 완전히 동일. 표준오차와 p값도 모든 변수를 포함하여 처음모델을 실행했을 때와 같음.

편향 제거된 신용 한도에 따른 잡음 제거된 채무불이행률

FWL 정리

  • 처치 T와 결과 Y 사이의 관계를 추정하고 싶지만 교란 요인 X가 있는 경우 사용
  • 처음에는 처치와 결과는 음의 기울기지만, 도메인 지식에서 비롯된 확실한 근거로 볼 때 이 관계는 본래 양의 관계여야하기에 데이터 편향을 제거해야함
    • 이를 위해 선형회귀분석을 사용하여 E[T|X]를 추정
    • 이후 편향이 제거된 처치 T - E[T|X]를 구함

  • 이후 회귀 모델을 사용하여 E[Y|X]를 추정하고 잡음 제거된 결과 Y - E[Y|X]를 만듬 (이 잡음 제거된 결과를 X에 의해 설명된 모든 분산을 고려한 결과로 볼 수 있음)

직교화로 잡음 제거

  • 마지막으로 편향과 잡음을 제거한 후 T와 Y의 양의 관계를 명확히 볼 수 있음.

마지막 회귀식은 Y를 T와 X에 동시 회귀했을 때의 기울기와 정확히 같음.

 

해당 포스팅은 [Causal Inference in Python / 실무로 통하는 인과추론]을 참고하여 작성하였습니다

728x90
반응형