๐ ์ธ๊ณผ์ถ๋ก ๊ฐ์ธ ๊ณต๋ถ์ฉ ํฌ์คํธ ๊ธ์ ๋๋ค. ์ถ์ฒ๋ ์ฒจ๋ถํ ๋งํฌ๋ฅผ ์ฐธ๊ณ ํด์ฃผ์ธ์!
๐ ์ ๋ฆฌ
• Doubly robust estimator = ์ ํํ๊ท + ๊ฒฝํฅ์ ์
• ๋ ์ค ํ๋๊ฐ ๋ถ์์ ํด๋ ์ ๋นํ ์ถ์ ์น๋ฅผ ์ป์ ์ ์๋ค.
โ Introduction
โฏ Doubly Robust Estimation
• E[Y|T=1] - E[Y|T=0] | X ๋ฅผ ์ถ์ ํ๊ธฐ ์ํด ์ ํํ๊ท, Propensity score weighting ๋ฐฉ๋ฒ์ ๋ฐฐ์ ๋ค.
• ์ด ๋์ ๊ฒฐํฉํด์ ์ฌ์ฉํ๋ ๋ฐฉ๋ฒ์ด Doubly Robust Estimation ์ด๋ค.
โฏ ์์
• chapter 11 ์์ ์ ๋์ผ
• ๋ถ์ํ๊ธฐ ์ ์ ๋ฒ์ฃผํ ๋ณ์๋ค์ dummy ์ฒ๋ฆฌํ๋ค.
categ = ["ethnicity", "gender", "school_urbanicity"]
cont = ["school_mindset", "school_achievement", "school_ethnic_minority", "school_poverty", "school_size"]
data_with_categ = pd.concat([
data.drop(columns=categ), # dataset without the categorical features
pd.get_dummies(data[categ], columns=categ, drop_first=False) # categorical features converted to dummies
], axis=1)
โก Doubly robust estimation
โฏ ATE
• ์ถ์ ์ฝ๋ โญ
def doubly_robust(df, X, T, Y):
ps = LogisticRegression(C=1e6, max_iter=1000).fit(df[X], df[T]).predict_proba(df[X])[:, 1]
mu0 = LinearRegression().fit(df.query(f"{T}==0")[X], df.query(f"{T}==0")[Y]).predict(df[X])
mu1 = LinearRegression().fit(df.query(f"{T}==1")[X], df.query(f"{T}==1")[Y]).predict(df[X])
return (
np.mean(df[T]*(df[Y] - mu1)/ps + mu1) -
np.mean((1-df[T])*(df[Y] - mu0)/(1-ps) + mu0)
)
T = 'intervention'
Y = 'achievement_score'
X = data_with_categ.columns.drop(['schoolid', T, Y])
doubly_robust(data_with_categ, X, T, Y)
## 0.38822197203025405
โช Doubly robust estimator ๋ ์ธ๋ฏธ๋์ ์ฐธ์ํ ํ์๋ค์ด ์ฐธ์ํ์ง ๋ชปํ ํ์๋ค์ ๋นํด ์ฑ์ทจ ์ ์๊ฐ 0.388 ๋๋ค๊ณ ๊ธฐ๋ํ๋ค. ์ ๋ขฐ๊ตฌ๊ฐ์ ์ํด bootstrap ๋ฐฉ๋ฒ์ ์ ์ฉํด ๋ณผ ์ ์๋ค.
from joblib import Parallel, delayed # for parallel processing
np.random.seed(88)
# run 1000 bootstrap samples
bootstrap_sample = 1000
ates = Parallel(n_jobs=4)(delayed(doubly_robust)(data_with_categ.sample(frac=1, replace=True), X, T, Y)
for _ in range(bootstrap_sample))
ates = np.array(ates)
print(f"ATE 95% CI:", (np.percentile(ates, 2.5), np.percentile(ates, 97.5)))
## ATE 95% CI: (0.35365379802081925, 0.41978432347111305)
โฏ Doubly robust estimator ๊ฐ ์ข์ ์ด์
• Propensity score ์ถ์ ์น P^(x) ํน์ ์ ํํ๊ท ์ถ์ ์น μ^(x) ์ค ํ๋๋ง ์ ์ถ์ ํ๋ฉด ์ ์๋ํ๊ธฐ ๋๋ฌธ์ doubly robust ํ๋ค๊ณ ๋ถ๋ฅธ๋ค.
• μ1^(x) ์ด ์ ํํ๊ฒ ์ถ์ ๋์๋ค๋ฉด ์์ฐจ Yi - μ1^(x) ์ ํฉ์ 0์ด ๋๋ค.
• ์๋ ์ฝ๋์ ๊ฐ์ด ๊ฒฝํฅ ์ ์๋ฅผ ์ถ์ ํ๋ ๋ก์ง์คํฑ ํ๊ท๋ถ์์ 0.1 ~ 0.9 ์ฌ์ด์ ๊ฐ์ ๊ฐ๋ ๋ฌด์์ ๊ท ์ผ๋ถํฌ์ ๋์๋ก ๋์ฒดํ์ฌ ๊ฒฝํฅ ์ ์ ๋ชจ๋ธ์ ์ ๋ขฐ๋๋ฅผ ๋จ์ดํธ๋ ค๋ด๋, doubly robust estimator ๋ ์ฌ์ ํ ์ ์ฌํ ์ถ์ ์น๋ฅผ ๊ฐ๋๋ค. Bootstrap ์ผ๋ก ์ถ์ ์น์ ๋ถ์ฐ์ ํ์ธํด๋ณด๋ฉด ๋ถ์ฐ์ ์ฝ๊ฐ ํผ์ ํ์ธํด ๋ณผ ์ ์๋ค.
from sklearn.linear_model import LogisticRegression, LinearRegression
def doubly_robust_wrong_ps(df, X, T, Y):
# wrong PS model
np.random.seed(654)
ps = np.random.uniform(0.1, 0.9, df.shape[0]) # ๐ก
mu0 = LinearRegression().fit(df.query(f"{T}==0")[X], df.query(f"{T}==0")[Y]).predict(df[X])
mu1 = LinearRegression().fit(df.query(f"{T}==1")[X], df.query(f"{T}==1")[Y]).predict(df[X])
return (
np.mean(df[T]*(df[Y] - mu1)/ps + mu1) -
np.mean((1-df[T])*(df[Y] - mu0)/(1-ps) + mu0)
)
doubly_robust_wrong_ps(data_with_categ, X, T, Y) # 0.3796984428841887
• μ1^(x) ์ ํ๋ฆฌ๊ฒ ์ค์ ํด๋ (์๋ ์ฝ๋์์ ํ๊ท๋ถ์ ๋ชจ๋ธ์ ์ ๊ท๋ถํฌ๋์๋ก ๋์ฒดํจ) ์ฌ์ ํ doubly robust estimation ์ 0.38๋ก ๋์ผํ๋ค. ๋ถ์ฐ์ ์ฝ๊ฐ ๋๋ค. (by bootstrap)
from sklearn.linear_model import LogisticRegression, LinearRegression
def doubly_robust_wrong_model(df, X, T, Y):
np.random.seed(654)
ps = LogisticRegression(C=1e6, max_iter=1000).fit(df[X], df[T]).predict_proba(df[X])[:, 1]
# wrong mu(x) model
mu0 = np.random.normal(0, 1, df.shape[0])
mu1 = np.random.normal(0, 1, df.shape[0])
return (
np.mean(df[T]*(df[Y] - mu1)/ps + mu1) -
np.mean((1-df[T])*(df[Y] - mu0)/(1-ps) + mu0)
)
doubly_robust_wrong_model(data_with_categ, X, T, Y) # 0.3981405305433191
'1๏ธโฃ AIโขDS > ๐ฅ Casual inference' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[The Brave and True] 14. Panel data and fixed effects (0) | 2023.07.26 |
---|---|
[The Brave and True] 13. Difference-in-Differences (0) | 2023.07.20 |
[The Brave and True] 11. Propensity score (0) | 2023.07.13 |
[The Brave and True] 10. Matching (0) | 2023.07.11 |
[The Brave and True] 9. Non Compliance and LATE (0) | 2023.07.04 |
๋๊ธ