"Einführung in die Effektüberprüfung Kapitel 3 Analyse mit dem Neigungswert" + α wird in Python versucht

Dieser Artikel basiert auf "Einführung in die Überprüfung der Wirksamkeit - kausales Denken für einen korrekten Vergleich / Grundlagen der quantitativen Ökonomie" Dies ist eine Zusammenfassung dessen, was ich durch das Lesen von "Kapitel 3 Analyse mit Propensity Scores" gelernt und gefühlt habe.

Grundlagen

Was ist ein Neigungswert?

[^ px]: In diesem Buch wird der Neigungswert als $ P (X) $ geschrieben, der Einfachheit halber wird er jedoch als $ e (X) $ festgelegt.

Regressive Analyse gegen Propensity Score [^ ra-vs-ps]

[^ ra-vs-ps]: Ein etwas seltsamer Vergleich, aber aus diesem Buch kann man es so lesen

CIA gegen stark vernachlässigbare Zuordnung

--CIA wird in diesem Buch verwendet, aber genau genommen ist ** stark vernachlässigbare Zuordnung ** korrekt [^ rosenbaum_1983]

Schätzung der Neigungsbewertung

--Logistische Regression wird häufig verwendet, um Neigungswerte zu schätzen, aber maschinelles Lernen ist auch in Ordnung

Schätzung des Interventionseffekts anhand des Neigungsscores

ATT v.s. ATE

Matching gegen IPW [^ Matching-vs-IPw]

[^ Matching-vs-IPW]: Es gibt andere Methoden zur Abschätzung des Interventionseffekts unter Verwendung anderer Neigungswerte als Matching und IPW, aber dieses Buch befasst sich mit diesen beiden.

image.png

ATT im Matching

image.png

ATE im Matching

image.png

ATT in IPW

\frac{\sum_{i=1}^{N}Z_{i}Y_{i}}{\sum_{i=1}^{N}Z_{i}}
-\frac{\sum_{i=1}^{N}\frac{(1-Z_{i})\hat{e}(X_{i})}{1-\hat{e}(X_{i})}Y_{i}}{\sum_{i=1}^{N}\frac{(1-Z_{i})\hat{e}(X_{i})}{1-\hat{e}(X_{i})}}

ATE in IPW

\frac{\sum_{i=1}^{N}\frac{Z_{i}}{\hat{e}(X_{i})}Y_{i}}{\sum_{i=1}^{N}\frac{Z_{i}}{\hat{e}(X_{i})}}
-\frac{\sum_{i=1}^{N}\frac{1-Z_{i}}{1-\hat{e}(X_{i})}Y_{i}}{\sum_{i=1}^{N}\frac{1-Z_{i}}{1-\hat{e}(X_{i})}}

Über gemeinsame Unterstützung

Bewertung der Neigungsbewertung

――Es ist wichtig, ob die Verteilung der Kovariaten zwischen der Interventionsgruppe und der Nicht-Interventionsgruppe zwischen den beiden Gruppen durch den Neigungswert ausgeglichen wird. -Machen Sie also Annahmen\\{Y^{(1)}, Y^{(0)}\\}\perp Z|e(X)Von\\{Y^{(1)}, Y^{(0)}\\}\perp Z|XIch denke, es bedeutet, zurückzukehren

Praktische Ausgabe

MineThatData E-Mail Analytics And Data Mining Challenge dataset[1]

LaLonde(1986)

Daten gelesen

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import warnings
warnings.filterwarnings('ignore')
df_cps1 = pd.read_stata('https://users.nber.org/~rdehejia/data/cps_controls.dta')
df_cps3 = pd.read_stata('https://users.nber.org/~rdehejia/data/cps_controls3.dta')
df_nsw = pd.read_stata('https://users.nber.org/~rdehejia/data/nsw_dw.dta')

Datensatzerstellung

--NSW: RCT-Datensatz --CPS1 + NSW: Datensatz mit NSW-Nichtinterventionsgruppe durch CPS1 ersetzt --CPS3 + NSW: Datensatz mit NSW-Nichtinterventionsgruppe durch CPS3 ersetzt

treat_label = {0: 'untreat', 1: 'treat'}
X_columns = ['age', 'education', 'black', 'hispanic', 'married', 'nodegree', 're74', 're75']
y_column = 're78'
z_column = 'treat'

CPS1+NSW

df_cps1_nsw = pd.concat([df_nsw[df_nsw[z_column] == 1], df_cps1], ignore_index=True)

CPS3+NSW

df_cps3_nsw = pd.concat([df_nsw[df_nsw[z_column] == 1], df_cps3], ignore_index=True)

Bestätigen Sie die Verteilung der Interventionsgruppe und der Nicht-Interventionsgruppe

NSW

df_nsw[z_column].map(treat_label).value_counts().plot.bar(title='# of treatment in NSW')

image.png

_, ax = plt.subplots(3, 3, figsize=(16, 12))
for i, c in enumerate(X_columns + [y_column]):
    (df_nsw[c].groupby(df_nsw[z_column].map(treat_label))
     .plot.hist(density=True, alpha=0.5, title=f'{c} densities', legend=True, ax=ax[i // 3, i % 3]))

image.png

CPS1+NSW

――Es handelt sich um ziemlich unausgeglichene Daten

df_cps1_nsw[z_column].map(treat_label).value_counts().plot.bar(title='# of treatment in CPS1+NSW')

image.png

_, ax = plt.subplots(3, 3, figsize=(16, 12))
for i, c in enumerate(X_columns + [y_column]):
    (df_cps1_nsw[c].groupby(df_cps1_nsw[z_column].map(treat_label))
     .plot.hist(density=True, alpha=0.5, title=f'{c} densities', legend=True, ax=ax[i // 3, i % 3]))

image.png

CPS3+NSW

df_cps3_nsw[z_column].map(treat_label).value_counts().plot.bar(title='# of treatment in CPS3+NSW')

image.png

_, ax = plt.subplots(3, 3, figsize=(16, 12))
for i, c in enumerate(X_columns + [y_column]):
    (df_cps3_nsw[c].groupby(df_cps3_nsw[z_column].map(treat_label))
     .plot.hist(density=True, alpha=0.5, title=f'{c} densities', legend=True, ax=ax[i // 3, i % 3]))

image.png

Regressionsanalyse

import statsmodels.api as sm

NSW

results = sm.OLS(df_nsw[y_column], sm.add_constant(df_nsw[[z_column] + X_columns])).fit()
results.summary().tables[1]

image.png

CPS1+NSW

results = sm.OLS(df_cps1_nsw[y_column], sm.add_constant(df_cps1_nsw[[z_column] + X_columns])).fit()
results.summary().tables[1]

image.png

CPS3+NSW

results = sm.OLS(df_cps3_nsw[y_column], sm.add_constant(df_cps3_nsw[[z_column] + X_columns])).fit()
results.summary().tables[1]

image.png

Ergebnis

Datensatz Interventionseffekt[$]
NSW 1676.3
CPS1+NSW 699.1
CPS3+NSW 1548.2

Spielbeginn

Schätzung der Neigungsbewertung

CPS1+NSW

ps_model = sm.Logit(df_cps1_nsw[z_column], sm.add_constant(df_cps1_nsw[X_columns])).fit()
ps_model.summary().tables[1]

image.png

df_cps1_nsw['ps'] = 1 / (1 + np.exp(-ps_model.fittedvalues))

--Überprüfen Sie die Verteilung der Neigungswerte

(df_cps1_nsw.groupby(df_cps1_nsw[z_column].map(treat_label))['ps']
 .plot.hist(density=True, alpha=0.5, title=f'propensity score densities', legend=True))

image.png

from sklearn.metrics import roc_auc_score
roc_auc_score(df_cps1_nsw[z_column], df_cps1_nsw['ps'])
0.9708918648513447

CPS3+NSW

ps_model = sm.Logit(df_cps3_nsw[z_column], sm.add_constant(df_cps3_nsw[X_columns])).fit()
ps_model.summary().tables[1]

image.png

df_cps3_nsw['ps'] = 1 / (1 + np.exp(-ps_model.fittedvalues))

--Überprüfen Sie die Verteilung der Neigungswerte

(df_cps3_nsw.groupby(df_cps3_nsw[z_column].map(treat_label))['ps']
 .plot.hist(density=True, alpha=0.5, title=f'propensity score densities', legend=True))

image.png

from sklearn.metrics import roc_auc_score
roc_auc_score(df_cps3_nsw[z_column], df_cps3_nsw['ps'])
0.8742266742266742

ATT-Schätzung

CPS1+NSW

passend
from sklearn.neighbors import NearestNeighbors
def pairs_generator(s0: pd.Series, s1: pd.Series, threshold: np.float) -> pd.DataFrame:
    """
Ein rekursiver Generator, der Paare mit der K-Nachbarschaftsmethode erstellt.
    
    Parameters
    ----------
    s0, s1 : pd.Series
    threshold : np.float
Die Schwelle der Entfernung, um ein Paar zu bilden. Wenn der nächste Nachbarpunkt ebenfalls den Schwellenwert überschreitet, wird er nicht gepaart.
    
    Returns
    -------
    pairs : pd.DataFrame
Index eines Paares bestehend aus der s0-Probe und der nächsten s1-Probe.
Spalte l ist der Index von s0 und Spalte r ist der Index von s1.
    
    Notes
    -----
Dieselbe Stichprobe wird niemals für mehrere Paare verwendet.
    
    Examples
    --------
    s0 = df[df[z_column] == 0]['ps']
    s1 = df[df[z_column] == 1]['ps']
    threshold = df['ps'].std() * 0.1
    pairs = pd.concat(pairs_generator(s1, s0, threshold), ignore_index=True)
    """
    neigh_dist, neigh_ind = NearestNeighbors(1).fit(s0.values.reshape(-1, 1)).kneighbors(s1.values.reshape(-1, 1))
    pairs = pd.DataFrame(
        {'d': neigh_dist[:, 0], 'l': s0.iloc[neigh_ind[:, 0]].index},
        index=s1.index,
    ).query(f'd < {threshold}').groupby('l')['d'].idxmin().rename('r').reset_index()
    if len(pairs) > 0:
        yield pairs
        yield from pairs_generator(s0.drop(pairs['l']), s1.drop(pairs['r']), threshold)
s1 = df_cps1_nsw[df_cps1_nsw[z_column] == 1]['ps']
s0 = df_cps1_nsw[df_cps1_nsw[z_column] == 0]['ps']
threshold = df_cps1_nsw['ps'].std() * 0.1
pairs1_cps1_nsw = pd.concat(pairs_generator(s1, s0, threshold), ignore_index=True)
pairs0_cps1_nsw = pd.concat(pairs_generator(s0, s1, threshold), ignore_index=True) #Wird bei der ATE-Berechnung verwendet
ax = df_cps1_nsw.loc[pairs1_cps1_nsw.unstack()].plot.scatter(x='ps', y=z_column, label='matched', alpha=0.3, figsize=(16, 4), title='pairs on treated')
df_cps1_nsw.loc[~df_cps1_nsw.index.isin(pairs1_cps1_nsw.unstack())].plot.scatter(x='ps', y=z_column, label='unmatched', alpha=0.3, c='tab:orange', ax=ax)
for x in zip(df_cps1_nsw['ps'].iloc[pairs1_cps1_nsw['l']].values, df_cps1_nsw['ps'].iloc[pairs1_cps1_nsw['r']].values):
    plt.plot(x, [1, 0], c='tab:blue', alpha=0.3)

image.png

(pairs1_cps1_nsw['l'].map(df_cps1_nsw[y_column]) - pairs1_cps1_nsw['r'].map(df_cps1_nsw[y_column])).agg(['mean', 'std'])
mean    1929.083008
std     9618.346680
dtype: float64

IPW

df_cps1_nsw['w'] = df_cps1_nsw[z_column] / df_cps1_nsw['ps'] + (1 - df_cps1_nsw[z_column]) / (1 - df_cps1_nsw['ps'])
att_model = sm.WLS(df_cps1_nsw[y_column], df_cps1_nsw[[z_column]].assign(untreat=1-df_cps1_nsw[z_column]), weights=df_cps1_nsw['w'] * df_cps1_nsw['ps']).fit()
att_model.summary().tables[1]

image.png

att_model.params['treat'] - att_model.params['untreat']
1180.4078220960955
IPW (gemeinsame Unterstützung)
df_cps1_nsw_cs = df_cps1_nsw[df_cps1_nsw['ps'].between(*df_cps1_nsw.groupby(z_column)['ps'].agg(['min', 'max']).agg({'min': 'max', 'max': 'min'}))].copy()
att_model = sm.WLS(df_cps1_nsw_cs[y_column], df_cps1_nsw_cs[[z_column]].assign(untreat=1-df_cps1_nsw_cs[z_column]), weights=df_cps1_nsw_cs['w'] * df_cps1_nsw_cs['ps']).fit()
att_model.summary().tables[1]

image.png

att_model.params['treat'] - att_model.params['untreat']
1243.8640545001808
pd.DataFrame([{
    'unadjusted': np.subtract(*df_cps1_nsw.groupby(z_column)[c].mean()) / df_cps1_nsw[c].std(),
    'adjusted(matching)': np.subtract(*df_cps1_nsw.loc[pairs1_cps1_nsw.unstack()].groupby(z_column)[c].mean()) / df_cps1_nsw[c].std(),
    'adjusted(weighting)': np.subtract(*df_cps1_nsw.groupby(z_column).apply(lambda x: np.average(x[c], weights=x['w'] * x['ps']))) / df_cps1_nsw[c].std(),
    'adjusted(weighting in common support)': np.subtract(*df_cps1_nsw_cs.groupby(z_column).apply(lambda x: np.average(x[c], weights=x['w'] * x['ps']))) / df_cps1_nsw_cs[c].std(),
} for c in X_columns], index=X_columns).abs().plot(marker='o', alpha=0.5, grid=True, ylim=(0, 100), logy=True, title='covariates balance')
plt.axhline(y=0.1, linestyle='--', c='r')

image.png

_, ax = plt.subplots(3, 3, figsize=(16, 12))
for i, c in enumerate(X_columns + [y_column]):
    (df_cps1_nsw.loc[pairs1_cps1_nsw.unstack()][c].groupby(df_cps1_nsw[z_column].map(treat_label))
     .plot.hist(density=True, alpha=0.5, title=f'{c} densities', legend=True, ax=ax[i // 3, i % 3]))

image.png

_, ax = plt.subplots(3, 3, figsize=(16, 12))
df = df_cps1_nsw.sample(1000000, replace=True, weights=df_cps1_nsw['w'] * df_cps1_nsw['ps'], random_state=2020)
for i, c in enumerate(X_columns + [y_column]):
    (df[c].groupby(df_cps1_nsw[z_column].map(treat_label))
     .plot.hist(density=True, alpha=0.5, title=f'{c} densities', legend=True, ax=ax[i // 3, i % 3]))

image.png

--Bestätigen Sie die Verteilung der Kovariaten in IPW (gemeinsame Unterstützung) ――Der Ausgleich erfolgt ordnungsgemäß im Vergleich zur ursprünglichen Verteilung

_, ax = plt.subplots(3, 3, figsize=(16, 12))
df = df_cps1_nsw_cs.sample(1000000, replace=True, weights=df_cps1_nsw_cs['w'] * df_cps1_nsw_cs['ps'], random_state=2020)
for i, c in enumerate(X_columns + [y_column]):
    (df[c].groupby(df_cps1_nsw_cs[z_column].map(treat_label))
     .plot.hist(density=True, alpha=0.5, title=f'{c} densities', legend=True, ax=ax[i // 3, i % 3]))

image.png

CPS3+NSW

passend
s1 = df_cps3_nsw[df_cps3_nsw[z_column] == 1]['ps']
s0 = df_cps3_nsw[df_cps3_nsw[z_column] == 0]['ps']
threshold = df_cps3_nsw['ps'].std() * 0.1
pairs1_cps3_nsw = pd.concat(pairs_generator(s1, s0, threshold), ignore_index=True)
pairs0_cps3_nsw = pd.concat(pairs_generator(s0, s1, threshold), ignore_index=True) #Wird bei der ATE-Berechnung verwendet
ax = df_cps3_nsw.loc[pairs1_cps3_nsw.unstack()].plot.scatter(x='ps', y=z_column, label='matched', alpha=0.3, figsize=(16, 4), title='pairs on treated')
df_cps3_nsw.loc[~df_cps3_nsw.index.isin(pairs1_cps3_nsw.unstack())].plot.scatter(x='ps', y=z_column, label='unmatched', alpha=0.3, c='tab:orange', ax=ax)
for x in zip(df_cps3_nsw['ps'].iloc[pairs1_cps3_nsw['l']].values, df_cps3_nsw['ps'].iloc[pairs1_cps3_nsw['r']].values):
    plt.plot(x, [1, 0], c='tab:blue', alpha=0.3)

image.png

(pairs1_cps3_nsw['l'].map(df_cps3_nsw[y_column]) - pairs1_cps3_nsw['r'].map(df_cps3_nsw[y_column])).agg(['mean', 'std'])
mean    1463.115845
std     8779.598633
dtype: float64

IPW

df_cps3_nsw['w'] = df_cps3_nsw[z_column] / df_cps3_nsw['ps'] + (1 - df_cps3_nsw[z_column]) / (1 - df_cps3_nsw['ps'])
att_model = sm.WLS(df_cps3_nsw[y_column], df_cps3_nsw[[z_column]].assign(untreat=1-df_cps3_nsw[z_column]), weights=df_cps3_nsw['w'] * df_cps3_nsw['ps']).fit()
att_model.summary().tables[1]

image.png

att_model.params['treat'] - att_model.params['untreat']
1214.0711733143507
IPW (gemeinsame Unterstützung)
df_cps3_nsw_cs = df_cps3_nsw[df_cps3_nsw['ps'].between(*df_cps3_nsw.groupby(z_column)['ps'].agg(['min', 'max']).agg({'min': 'max', 'max': 'min'}))].copy()
att_model = sm.WLS(df_cps3_nsw_cs[y_column], df_cps3_nsw_cs[[z_column]].assign(untreat=1-df_cps3_nsw_cs[z_column]), weights=df_cps3_nsw_cs['w'] * df_cps3_nsw_cs['ps']).fit()
att_model.summary().tables[1]

image.png

att_model.params['treat'] - att_model.params['untreat']
988.8657151185471
pd.DataFrame([{
    'unadjusted': np.subtract(*df_cps3_nsw.groupby(z_column)[c].mean()) / df_cps3_nsw[c].std(),
    'adjusted(matching)': np.subtract(*df_cps3_nsw.loc[pairs1_cps3_nsw.unstack()].groupby(z_column)[c].mean()) / df_cps3_nsw[c].std(),
    'adjusted(weighting)': np.subtract(*df_cps3_nsw.groupby(z_column).apply(lambda x: np.average(x[c], weights=x['w'] * x['ps']))) / df_cps3_nsw[c].std(),
    'adjusted(weighting in common support)': np.subtract(*df_cps3_nsw_cs.groupby(z_column).apply(lambda x: np.average(x[c], weights=x['w'] * x['ps']))) / df_cps3_nsw_cs[c].std(),
} for c in X_columns], index=X_columns).abs().plot(marker='o', alpha=0.5, grid=True, ylim=(0, 100), logy=True, title='covariates balance')
plt.axhline(y=0.1, linestyle='--', c='r')

image.png

_, ax = plt.subplots(3, 3, figsize=(16, 12))
for i, c in enumerate(X_columns + [y_column]):
    (df_cps3_nsw.loc[pairs1_cps3_nsw.unstack()][c].groupby(df_cps3_nsw[z_column].map(treat_label))
     .plot.hist(density=True, alpha=0.5, title=f'{c} densities', legend=True, ax=ax[i // 3, i % 3]))

image.png

_, ax = plt.subplots(3, 3, figsize=(16, 12))
df = df_cps3_nsw.sample(1000000, replace=True, weights=df_cps3_nsw['w'] * df_cps3_nsw['ps'], random_state=2020)
for i, c in enumerate(X_columns + [y_column]):
    (df[c].groupby(df_cps3_nsw[z_column].map(treat_label))
     .plot.hist(density=True, alpha=0.5, title=f'{c} densities', legend=True, ax=ax[i // 3, i % 3]))

image.png

--Bestätigen Sie die Verteilung der Kovariaten in IPW (gemeinsame Unterstützung)

_, ax = plt.subplots(3, 3, figsize=(16, 12))
df = df_cps3_nsw_cs.sample(1000000, replace=True, weights=df_cps3_nsw_cs['w'] * df_cps3_nsw_cs['ps'], random_state=2020)
for i, c in enumerate(X_columns + [y_column]):
    (df[c].groupby(df_cps3_nsw_cs[z_column].map(treat_label))
     .plot.hist(density=True, alpha=0.5, title=f'{c} densities', legend=True, ax=ax[i // 3, i % 3]))

image.png

Ergebnis

――Die Kovariaten sind ausgeglichen, aber der geschätzte Wert des Interventionseffekts scheint sich deutlich von 1600 USD zu unterscheiden.

Datensatz passend IPW IPW(Gemeinsame Unterstützung)
CPS1+NSW 1929.1 1180.4 1243.9
CPS3+NSW 1463.1 1214.1 988.9

ATE-Schätzung

CPS1+NSW

passend

--Überprüfen Sie das Paar

pairs_cps1_nsw = pd.concat([pairs1_cps1_nsw, pairs0_cps1_nsw.rename({'l': 'r', 'r': 'l'}, axis=1)], ignore_index=True)
ax = df_cps1_nsw.loc[pairs_cps1_nsw.unstack()].plot.scatter(x='ps', y=z_column, label='matched', alpha=0.3, figsize=(16, 4), title='pairs')
df_cps1_nsw.loc[~df_cps1_nsw.index.isin(pairs_cps1_nsw.unstack())].plot.scatter(x='ps', y=z_column, label='unmatched', alpha=0.3, c='tab:orange', ax=ax)
for x in zip(df_cps1_nsw['ps'].iloc[pairs_cps1_nsw['l']].values, df_cps1_nsw['ps'].iloc[pairs_cps1_nsw['r']].values):
    plt.plot(x, [1, 0], c='tab:blue', alpha=0.3)

image.png

(pairs_cps1_nsw['l'].map(df_cps1_nsw[y_column]) - pairs_cps1_nsw['r'].map(df_cps1_nsw[y_column])).agg(['mean', 'std'])
mean    1836.516968
std     9634.636719
dtype: float64

IPW

ate_model = sm.WLS(df_cps1_nsw[y_column], df_cps1_nsw[[z_column]].assign(untreat=1-df_cps1_nsw[z_column]), weights=df_cps1_nsw['w']).fit()
ate_model.summary().tables[1]

image.png

ate_model.params['treat'] - ate_model.params['untreat']
-6456.300804768925
IPW (gemeinsame Unterstützung)
ate_model = sm.WLS(df_cps1_nsw_cs[y_column], df_cps1_nsw_cs[[z_column]].assign(untreat=1-df_cps1_nsw_cs[z_column]), weights=df_cps1_nsw_cs['w']).fit()
ate_model.summary().tables[1]

image.png

ate_model.params['treat'] - ate_model.params['untreat']
545.3149727568589
pd.DataFrame([{
    'unadjusted': np.subtract(*df_cps1_nsw.groupby(z_column)[c].mean()) / df_cps1_nsw[c].std(),
    'adjusted(matching)': np.subtract(*df_cps1_nsw.loc[pairs_cps1_nsw.unstack()].groupby(z_column)[c].mean()) / df_cps1_nsw[c].std(),
    'adjusted(weighting)': np.subtract(*df_cps1_nsw.groupby(z_column).apply(lambda x: np.average(x[c], weights=x['w']))) / df_cps1_nsw[c].std(),
    'adjusted(weighting in common support)': np.subtract(*df_cps1_nsw_cs.groupby(z_column).apply(lambda x: np.average(x[c], weights=x['w']))) / df_cps1_nsw_cs[c].std(),
} for c in X_columns], index=X_columns).abs().plot(marker='o', alpha=0.5, grid=True, ylim=(0, 100), logy=True, title='covariates balance')
plt.axhline(y=0.1, linestyle='--', c='r')

image.png

_, ax = plt.subplots(3, 3, figsize=(16, 12))
for i, c in enumerate(X_columns + [y_column]):
    (df_cps1_nsw.loc[pairs_cps1_nsw.unstack()][c].groupby(df_cps1_nsw[z_column].map(treat_label))
     .plot.hist(density=True, alpha=0.5, title=f'{c} densities', legend=True, ax=ax[i // 3, i % 3]))

image.png

_, ax = plt.subplots(3, 3, figsize=(16, 12))
df = df_cps1_nsw.sample(1000000, replace=True, weights=df_cps1_nsw['w'], random_state=2020)
for i, c in enumerate(X_columns + [y_column]):
    (df[c].groupby(df_cps1_nsw[z_column].map(treat_label))
     .plot.hist(density=True, alpha=0.5, title=f'{c} densities', legend=True, ax=ax[i // 3, i % 3]))

image.png

--Bestätigen Sie die Verteilung der Kovariaten in IPW (gemeinsame Unterstützung)

_, ax = plt.subplots(3, 3, figsize=(16, 12))
df = df_cps1_nsw_cs.sample(1000000, replace=True, weights=df_cps1_nsw_cs['w'], random_state=2020)
for i, c in enumerate(X_columns + [y_column]):
    (df[c].groupby(df_cps1_nsw_cs[z_column].map(treat_label))
     .plot.hist(density=True, alpha=0.5, title=f'{c} densities', legend=True, ax=ax[i // 3, i % 3]))

image.png

CPS3+NSW

passend

--Überprüfen Sie das Paar

pairs_cps3_nsw = pd.concat([pairs1_cps3_nsw, pairs0_cps3_nsw.rename({'l': 'r', 'r': 'l'}, axis=1)], ignore_index=True)
ax = df_cps3_nsw.loc[pairs_cps3_nsw.unstack()].plot.scatter(x='ps', y=z_column, label='matched', alpha=0.3, figsize=(16, 4), title='pairs')
df_cps3_nsw.loc[~df_cps3_nsw.index.isin(pairs_cps3_nsw.unstack())].plot.scatter(x='ps', y=z_column, label='unmatched', alpha=0.3, c='tab:orange', ax=ax)
for x in zip(df_cps3_nsw['ps'].iloc[pairs_cps3_nsw['l']].values, df_cps3_nsw['ps'].iloc[pairs_cps3_nsw['r']].values):
    plt.plot(x, [1, 0], c='tab:blue', alpha=0.3)

image.png

(pairs_cps3_nsw['l'].map(df_cps3_nsw[y_column]) - pairs_cps3_nsw['r'].map(df_cps3_nsw[y_column])).agg(['mean', 'std'])
mean    1486.608276
std     8629.639648
dtype: float64

IPW

ate_model = sm.WLS(df_cps3_nsw[y_column], df_cps3_nsw[[z_column]].assign(untreat=1-df_cps3_nsw[z_column]), weights=df_cps3_nsw['w']).fit()
ate_model.summary().tables[1]

image.png

ate_model.params['treat'] - ate_model.params['untreat']
224.6762634665365
IPW (gemeinsame Unterstützung)
ate_model = sm.WLS(df_cps3_nsw_cs[y_column], df_cps3_nsw_cs[[z_column]].assign(untreat=1-df_cps3_nsw_cs[z_column]), weights=df_cps3_nsw_cs['w']).fit()
ate_model.summary().tables[1]

image.png

ate_model.params['treat'] - ate_model.params['untreat']
801.0736196669177
pd.DataFrame([{
    'unadjusted': np.subtract(*df_cps3_nsw.groupby(z_column)[c].mean()) / df_cps3_nsw[c].std(),
    'adjusted(matching)': np.subtract(*df_cps3_nsw.loc[pairs_cps3_nsw.unstack()].groupby(z_column)[c].mean()) / df_cps3_nsw[c].std(),
    'adjusted(weighting)': np.subtract(*df_cps3_nsw.groupby(z_column).apply(lambda x: np.average(x[c], weights=x['w']))) / df_cps3_nsw[c].std(),
    'adjusted(weighting in common support)': np.subtract(*df_cps3_nsw_cs.groupby(z_column).apply(lambda x: np.average(x[c], weights=x['w']))) / df_cps3_nsw_cs[c].std(),
} for c in X_columns], index=X_columns).abs().plot(marker='o', alpha=0.5, grid=True, ylim=(0, 100), logy=True, title='covariates balance')
plt.axhline(y=0.1, linestyle='--', c='r')

image.png

_, ax = plt.subplots(3, 3, figsize=(16, 12))
for i, c in enumerate(X_columns + [y_column]):
    (df_cps3_nsw.loc[pairs_cps3_nsw.unstack()][c].groupby(df_cps3_nsw[z_column].map(treat_label))
     .plot.hist(density=True, alpha=0.5, title=f'{c} densities', legend=True, ax=ax[i // 3, i % 3]))

image.png

_, ax = plt.subplots(3, 3, figsize=(16, 12))
df = df_cps3_nsw.sample(1000000, replace=True, weights=df_cps3_nsw['w'], random_state=2020)
for i, c in enumerate(X_columns + [y_column]):
    (df[c].groupby(df_cps3_nsw[z_column].map(treat_label))
     .plot.hist(density=True, alpha=0.5, title=f'{c} densities', legend=True, ax=ax[i // 3, i % 3]))

image.png

--Bestätigen Sie die Verteilung der Kovariaten in IPW (gemeinsame Unterstützung)

_, ax = plt.subplots(3, 3, figsize=(16, 12))
df = df_cps3_nsw_cs.sample(1000000, replace=True, weights=df_cps3_nsw_cs['w'], random_state=2020)
for i, c in enumerate(X_columns + [y_column]):
    (df[c].groupby(df_cps3_nsw_cs[z_column].map(treat_label))
     .plot.hist(density=True, alpha=0.5, title=f'{c} densities', legend=True, ax=ax[i // 3, i % 3]))

image.png

Ergebnis

Datensatz passend IPW IPW(Gemeinsame Unterstützung)
CPS1+NSW 1836.5 -6456.3 545.3
CPS3+NSW 1486.6 224.7 801.0

Impressionen


  1. https://blog.minethatdata.com/2008/03/minethatdata-e-mail-analytics-and-data.html ↩︎

Recommended Posts

"Einführung in die Effektüberprüfung Kapitel 3 Analyse mit dem Neigungswert" + α wird in Python versucht
Einführung in die Überprüfung der Wirksamkeit Kapitel 1 in Python geschrieben
Einführung in die Überprüfung der Wirksamkeit Kapitel 3 in Python geschrieben
Geschrieben "Einführung in die Effektüberprüfung" in Python
Einführung in die Überprüfung der Wirksamkeit Kapitel 2 in Python geschrieben
[Technisches Buch] Einführung in die Datenanalyse mit Python -1 Kapitel Einführung-
Einführung in die Effektüberprüfung Schreiben der Kapitel 4 und 5 in Python
Ich habe eine Stoppuhr mit tkinter mit Python gemacht
[Python] PCA-Scratch im Beispiel "Einführung in die multivariate Analysemethode"
[Einführung in Python3 Tag 13] Kapitel 7 Zeichenfolgen (7.1-7.1.1.1)
[Einführung in Python3 Tag 14] Kapitel 7 Zeichenfolgen (7.1.1.1 bis 7.1.1.4)
[Einführung in Python3 Tag 15] Kapitel 7 Zeichenfolgen (7.1.2-7.1.2.2)
Einführung in die Bildanalyse opencv python
[Einführung in Python3 Tag 21] Kapitel 10 System (10.1 bis 10.5)
Ich habe versucht, fMRI-Daten mit Python zu analysieren (Einführung in die Dekodierung von Gehirninformationen)
Ich habe versucht, PLSA in Python zu implementieren
[Einführung in Python] Wie verwende ich eine Klasse in Python?
Ich habe versucht, Permutation in Python zu implementieren
Einführung in die diskrete Ereignissimulation mit Python # 1
[Einführung in Python3, Tag 17] Kapitel 8 Datenziele (8.1-8.2.5)
[Einführung in Python3, Tag 17] Kapitel 8 Datenziele (8.3-8.3.6.1)
Ich habe versucht, PLSA in Python 2 zu implementieren
Ich habe versucht, die Bayes'sche Optimierung von Python zu verwenden
Melden Sie sich mit Anforderungen in Python bei Slack an
[Einführung in Python3 Tag 19] Kapitel 8 Datenziele (8.4-8.5)
[Einführung in Python3 Tag 18] Kapitel 8 Datenziele (8.3.6.2 bis 8.3.6.3)
Ich habe versucht, ADALINE in Python zu implementieren
Ich habe versucht, PPO in Python zu implementieren
Einführung in die diskrete Ereignissimulation mit Python # 2
Verwendung ist und == in Python
Einführung in Vektoren: Lineare Algebra in Python <1>
Einführung in die Zeitreihenanalyse ~ Saisonales Anpassungsmodell ~ In R und Python implementiert
Was ist ein Algorithmus? Einführung in den Suchalgorithmus] ~ Python ~
[Einführung in Python3 Tag 12] Kapitel 6 Objekte und Klassen (6.3-6.15)
tse - Einführung in den Text Stream Editor in Python
[Einführung in Python3, Tag 22] Kapitel 11 Parallele Verarbeitung und Vernetzung (11.1 bis 11.3)
Führen Sie eine Entitätsanalyse mit spaCy / GiNZA in Python durch
[Einführung in Python3 Tag 11] Kapitel 6 Objekte und Klassen (6.1-6.2)
[Einführung in Python3, Tag 23] Kapitel 12 Werden Sie Paisonista (12.1 bis 12.6)
Ich habe versucht, TOPIC MODEL in Python zu implementieren
[Umgebungskonstruktion] Abhängigkeitsanalyse mit CaboCha mit Python 2.7
[Einführung in Python3 Tag 20] Kapitel 9 Enträtseln des Webs (9.1-9.4)
Ich habe versucht, eine selektive Sortierung in Python zu implementieren
[Einführung in die Udemy Python3 + -Anwendung] 54. Was ist Docstrings?
[Einführung in die Elementzerlegung] Lassen Sie uns Zeitreihenanalysemethoden in R und Python arrange anordnen
Python-Übung 100 Schläge Ich habe versucht, den Entscheidungsbaum von Kapitel 5 mit graphviz zu visualisieren
[Impression] [Datenanalyse ab Null] Einführung in die Python-Datenwissenschaft in Geschäftsfällen
[New Corona] Ist der nächste Höhepunkt im Dezember? Ich habe die Trendanalyse mit Python versucht!
[Einführung in Python3 Tag 8] Kapitel 4 Py Skin: Codestruktur (4.1-4.13)
Ich habe versucht, die in Python installierten Pakete grafisch darzustellen
Ich habe versucht, TradeWave zu verwenden (BitCoin-Systemhandel in Python)
[Kapitel 5] Einführung in Python mit 100 Klopfen Sprachverarbeitung
Ich habe versucht, einen Pseudo-Pachislot in Python zu implementieren
Lesehinweis: Einführung in die Datenanalyse mit Python
Ich habe versucht, Drakues Poker in Python zu implementieren
Ich habe versucht, GA (genetischer Algorithmus) in Python zu implementieren
[Kapitel 3] Einführung in Python mit 100 Klopfen Sprachverarbeitung
Beenden bei Verwendung von Python in Terminal (Mac)
[Kapitel 2] Einführung in Python mit 100 Klopfen Sprachverarbeitung
Ich habe versucht zusammenzufassen, wie man Pandas von Python benutzt
Einführung in die lineare Algebra mit Python: A = LU-Zerlegung