Data Analysis & ML/인과추론

[Matching][매칭] PSM(Propensity Score Matching) (PSMPY)

YSY^ 2022. 11. 20. 18:21

매칭 (Matching)

  • 실험집단과 통제집단 간의 특성이 유사하도록 인위적으로 매칭
  • 장점 : 통제변수의 역할과 유사하지만, 관찰가능한 통제 변수를 기반으로 분석 대상을 균일하게 조정함으로써 그 외 관찰되지 않은 요인들도 유사할 것으로 가정
    • 즉 통제변수는 딱 지정하는 변수만 유사하게 만들 수 있지만, 매칭은 지정하는 변수만 유사하게 만드는 것이 아닌 집단 자체를 유사하게 만듬
  • 단점 : 분석대상의 숫자가 작아질 수 있음, 외적 타당성에 더 취약해짐

대표적 매칭 방법론

  • 모든 통제변수에 대해 값이 적당히 유사한 데이터만 매칭 : Coarsened Exact Matching(CEM)
  • 모든 통제변수들에 기반하여 실험집단이 될 경향성을 계산 후, 경향성이 유사한 데이터만 매칭 : Propensity Score Matching(PSM) ⇒ 이것이 더 많이 쓰임

 

Propensity Score Matching(PSM)

PSM : 대상마다 propensity score를 산출하여 실험군과 대조군의 score가 비슷한 대상을 matching 하여 두 군의 imbalancing을 피하는 방법

파이썬 psmpy 패키지의 코드들을 활용하여 설명합니다.

세팅

pip install psmpy

from psmpy import PsmPy
from psmpy.functions import cohenD
from psmpy.plotting import *

psm = PsmPy(df, treatment='treatment', indx='pat_id', exclude = [])

# indx : unique ID number for each case
# exclude : 제외할 컬럼, 리스트 형식이어야함.

 

Propensity Score(PS) 구하기

보통 Logistic regression을 사용하여 Propensity score를 구한다. Logstic regression은 0~1사이의 확률을 나타내는 함수이다.

이 방법은 처치군에 속하는 경우를 1, 대조군에 포함되는 경우를 0으로 하는 이항반응(binary response)형태로 종속변수를 설정하고, 보정하려는 공변량을 독립변수로 지정하여 로지스틱 회귀분석을 시행한다.

⇒ 따라서 먼저 로지스틱 회귀분석을 실시 한 이후에, 영향력 있는 변수만 뽑아서 넣는다.

psm.logistic_ps(balance = True)
  • balance : 로지스틱 회귀가 균형 잡힌 방식으로 실행되는지 여부

CF) balance를 맞추는 방법 (EX ) 남자 100명, 여자 10명이있는 데이터(불균형한 데이터))

⇒ 클래스 가중치를 할당.

클래스 가중치 공식 : w(j)= n_samples / (n_classes * n_samplesj)

  • w(j)는 각 클래스의 가중치(j는 클래스를 나타냄)
  • n_sample은 데이터 세트의 총 샘플 또는 행 수입니다. ⇒ 위의경우 110행
  • n_classes 대상의 총 고유 클래스 수 ⇒ 위의경우 남, 여 2개
  • n_samples(j) 각 클래스의 총 행 수 ⇒ 남자 100, 여자 10
  • 남자 wj : 110 / (2 * 100) = 110 / 200
  • 여자 wj : 110 / (2 * 10) = 110 / 20

 

Psmpy에서 제공하는 PS의 종류는 두가지입니다.

1. propensity_score

# psmpy의 백단 코드에서 발췌
pscore = logistic.predict_proba(df_cleaned)[:, 1]
df_cleaned['propensity_score'] = pscore
  • predict_proba를 활용하여 treatment로 분류될 확률을 구하며 이것이 바로 propensity_score이다.
  • treatment 쪽으로 분류될 확률, 0에서 1사이임.
    • 각 대상들의 추정된 확률 (각 대상이 주어진 공변량(covariate)에 의해 처치군에 포함될 확률)이 propensity score에 해당된다.

2. propensity_logit

# psmpy의 백단 코드에서 발췌
df_cleaned['propensity_logit'] = df_cleaned['propensity_score'].apply(
                        lambda p: np.log(p/(1-p)))
  • Psmpy에서는 propensity_logit 지표를 PS로 사용하기를 권장하는데 propensity score의 경우 범위가 0에서 1밖에 안되기에 특정지점에 값들이 몰려있어 매칭이 제대로 안될 수 있기 때문이다.
  • cf) propensity_score가 1일 경우, 1-p가 0이기에 에러가 발생할 수 있음
  • 오즈 : 특정 요인의 여부에 따른 이벤트 발생 확률을 비교할 때 사용
    • treatment에 들어갈 확률이 그렇지 않을 확률에 비해 몇배인지 나타내는 값.
    • 만약 treatment에 들어갈 확률이 3/4 이면⇒ (3/4) / (1/4) ⇒ 3
    • 즉, treatment에 들어갈 확률이 그렇지 않을 확률에 비해 3배

오즈를 구하는 방법

  • 로짓 : 오즈에 log를 취한것
  • 로짓을 사용하는 이유
    • 확률 p의 범위는 [0,1], Odds(p)의 범위는 [0,∞], log(Odds(p))는 [−∞,∞]가 되어, 다음과 같은 형태로 선형분석이 가능해짐

⇒ 즉, 종속변수의 spread를 넓히기 위해 사용함.

  • propensity_score가 1일 경우, 1-p가 0이기에 에러가 발생할 수 있음
  • 오즈 : 특정 요인의 여부에 따른 이벤트 발생 확률을 비교할 때 사용⇒ 만약 treatment에 들어갈 확률이 3/4 이면
  • =⇒ (3/4) / (1/4) ⇒ 3 ⇒ 즉, treatment에 들어갈 확률이 그렇지 않을 확률에 비해 3배
  • ⇒ treatment에 들어갈 확률이 그렇지 않을 확률에 비해 몇배인지 나타내는 값.
  • 로짓 : 오즈에 log를 취한것
  • 로짓을 사용하는 이유 : 확률 p의 범위는 [0,1], Odds(p)의 범위는 [0,∞], log(Odds(p))는 [−∞,∞][−∞,∞]가 되어, 다음과 같은 형태로 선형분석이 가능해짐

⇒ 즉, 종속변수의 spread를 넓히기 위해 사용함.

 

매칭 알고리즘

1. knn_matched

psm.knn_matched(matcher='propensity_logit', replacement=False, caliper=None)
  • matcher : propensity_logit or propensity_score
  • replacement : False →1대1 매칭
  • caliper : Caliper matching(Radius matching) 방법
    • 1:m 매칭의 문제점을 일부 보완한 방법으로 매칭하는 범위(Caliper)를 적절하게 설정한 후 두 집단 간 성향점수 거리를 그 범위 안으로 제한
    • 실험군 대상자의 PS에 설정한 caliper 안의 PS값을 가진 대조군 대상자를 무작위 추출해서 매칭
    • 당연하겠지만, 자의성 문제가 발생
    • Return : 매칭된 id값

2. knn_matched 12

psm.knn_matched_12n(matcher='propensity_logit', how_many=1)
  • 가장 가까운 n개와 매칭하는 방법
  • how_many : 최대 몇개씩 매칭시킬 것인가

 

CF) 1:n 매칭

처치군이 대조군 일반적인 경우 적을 수 있기 때문에 1:n매칭이 필요한 경우가 있다.(치료를 받은 집단보다 치료를 받지 않은 실험참가자가 많은건(구하기 쉬움) 생각해보면 당연한 사실!)

 

매칭 결과 확인하기

psm.matched_ids

  • 두집단에서 어떤 id 들이 매칭이 되었는지 볼 수 있음

두 집단의 로짓(PS) 분포

psm.plot_match(Title='Side by side matched controls', Ylabel='Number ofpatients', 
Xlabel= 'Propensity logit',names = ['treatment', 'control'],save=True)

# title - 'Side by side matched controls' (default),creates plot title
# Ylabel - 'Number of patients' (default), string, labelfor y-axis
# Xlabel - 'Propensity logit' (default), string, label for x-axis
# names - ['treatment', 'control'] (default), list of strings for legend
# save - False (default), saves the figure generated to current working directory if True
  • 두 집단의 PS 분포를 통해 매칭이 잘 되었는지 시각적으로 확인 할 수 있다.

이 case는 얼핏봐도 뭔가 매칭이 잘 안된 것 같다.

매칭이 잘 되었는지 확인하기

매칭 전 후로 두 집단의 변수별로 Effect Size가 어떻게 되었는지 plot으로 보기

psm.effect_size_plot(save=False)

⇒ 차이가 0에 가까워 질 수록 matching이 잘 되었다는 것.

CF) 효과크기(effect size)는 연구되는 현상이 실제로 모집단에 존재하는 정도(the degree to which the phenomenon being studied exists in the population)을 말한다.

예를 들어, 두 집단 평균차이 검증의 경우 효과크기는 집단간 차이의 표준화 측정치(Cohen's d)로서 집단 평균값들 간의 차이를 표준편차로 나눈 것이다.

분산분석의 경우 η^2, 회귀분석의 경우 R^2 등은 각각의 경우 효과크기를 나타낸다.

psm.effect_size

CF) Effect Size 판단방법

두 그룹의 평균 차이가 0.2 표준편차 미만(SMALL)이면 통계적으로 유의하더라도 그 차이가 무시할 수 있다고 간주

모든 변수들의 effect size를 0.2이하로 맞추기는 힘들기에, 중요하다고 생각하는 변수들을 우선적으로 맞춰보는것도 방법이다.

참고자료

728x90
반응형