Einführung in die Überprüfung der Wirksamkeit Kapitel 3 in Python geschrieben

Einführung

Einführung in die Überprüfung der Wirksamkeit - kausales Denken für einen korrekten Vergleich / Grundlagen der quantitativen Ökonomie Reproduzieren Sie den Quellcode in Python Machen.

Ich habe bereits ein Beispiel für die Implementierung eines großartigen Vorfahren, aber ich werde es als Memo für meine Studie hinterlassen.

Dieser Artikel behandelt Kapitel 3. Der Code wird auch auf github veröffentlicht. Darüber hinaus sind Variablennamen und Verarbeitungsinhalte grundsätzlich im Buch implementiert.

Logistische Rückgabe

Sie können die logistische Regression entweder mit Scicit-Learn- oder Statistikmodellen implementieren.

scikit-learn

scikit-learn muss dumm sein.

Logistische Rückkehr von sklearn


from sklearn.linear_model import LogisticRegression

X = pd.get_dummies(biased_data[['recency', 'history', 'channel']])  #Machen Sie den Kanal zu einer Dummy-Variablen
treatment = biased_data['treatment'] 

model = LogisticRegression().fit(X, treatment)

statsmodels

Verwenden Sie die Klassen glm oder logit.

statsmodels muss kein Dummy sein, aber es scheint, dass einige Kategoriewerte im Modell möglicherweise nicht verwendet werden. (Channel = Multichannel wird im folgenden Beispiel nicht verwendet. Die Ursache ist nicht klar.) Wenn Sie sich darüber Sorgen machen, können Sie daraus einen Dummy machen, der dem Ergebnis von sklearn entspricht.

Regressionsanalyse von Statistikmodellen


from statsmodels.formula.api import glm, logit

model = glm('treatment ~ history + recency + channel', data=biased_data, family=sm.families.Binomial()).fit()
# model = logit('treatment ~ history + recency + channel', data=biased_data).fit()  #Gleiches Ergebnis wie oben

Schätzen Sie anhand des Neigungswerts

"Propensity Score Matching" und "IPW", die als Schätzmethoden unter Verwendung von Propensity Scores verwendet werden, können in DoWhy implementiert werden.

Definieren Sie vor jeder Analyse eine Instanz für die allgemeine kausale Inferenz. Beachten Sie zu diesem Zeitpunkt, dass die Interventionsvariable booled werden muss.

Vorbereitung


from dowhy import CausalModel

biased_data = biased_data.astype({"treatment":'bool'}, copy=False)  #Bool-Behandlung

model=CausalModel(
    data = biased_data,
    treatment='treatment',
    outcome='spend',
    common_causes=['recency', 'history', 'channel']
)

Propensity Score Matching

Nächste Übereinstimmung

Die nächste Übereinstimmung ist eine Methode zum 1: 1-Abgleich zwischen Proben mit Intervention und Proben ohne Intervention, die im Buch erläutert werden, mit ähnlichen Neigungswerten. In diesem Buch wird nur ATT geschätzt, DoWhy kann jedoch auch ATE schätzen. Beachten Sie, dass der Standard ATE ist. Da beide von der internen Implementierung berechnet werden, wäre es schön, wenn Sie beide erhalten könnten.

Darüber hinaus scheint diese ATE aus ATT und ATC (erwarteter Wert des Interventionseffekts auf eine Nicht-Interventionsstichprobe) berechnet zu werden.

Nächste Übereinstimmung


nearest_ate = model.estimate_effect(
    identified_estimand, 
    method_name="backdoor.propensity_score_matching",
    target_units='ate',
)
nearest_att = model.estimate_effect(
    identified_estimand, 
    method_name="backdoor.propensity_score_matching",
    target_units='att', 
)

print(f'ATE: {nearest_ate.value}')
print(f'ATT: {nearest_att.value}')

Geschichtetes Matching

Obwohl in diesem Buch nicht erwähnt, wird auch das geschichtete Matching implementiert.

Betrachtet man den Quellcode, so scheint es, dass die Daten durch dieselbe Anzahl in die Schicht "num_strata" unterteilt und geschätzt werden. clipping_threshold vergleicht die Anzahl der Fälle mit und ohne Intervention in jeder Ebene und schließt Ebenen unterhalb dieses Werts aus. (Wahrscheinlich, um die Ebene mit extrem wenigen Interventionsdaten auszuschließen)

Geschichtetes Matching


stratification_ate = model.estimate_effect(
    identified_estimand,
    method_name="backdoor.propensity_score_stratification",
    target_units='ate',
    method_params={'num_strata':50, 'clipping_threshold':5},
)
stratification_att = model.estimate_effect(
    identified_estimand,
    method_name="backdoor.propensity_score_stratification",
    target_units='att',
    method_params={'num_strata':50, 'clipping_threshold':5},
)

print(f'ATE: {stratification_ate.value}')
print(f'ATT: {stratification_att.value}')

IPW

IPW


ipw_estimate = model.estimate_effect(
    identified_estimand,
    method_name="backdoor.propensity_score_weighting",
    target_units='ate',
)

print(f'ATE: {ipw_estimate.value}')

(Bonus-) Regressionsanalyse

Die in Kapitel 2 durchgeführte Regressionsanalyse ist ebenfalls möglich.

python


estimate = model.estimate_effect(
    identified_estimand,
    method_name="backdoor.linear_regression", #test_significance=True
)

print('Causal Estimate is ' + str(estimate.value))

Visualisierung der standardisierten Durchschnittsdifferenz

Die Visualisierung standardisierter mittlerer Unterschiede zur Bestätigung des Gleichgewichts der Kovariaten wird nicht unterstützt. Daher ist es mühsam, aber es wird von Ihnen selbst berechnet.

Propensity Score Matching

Es scheint, dass Sie sich nicht auf die Entsprechung des Neigungs-Score-Matchings beziehen können. Implementieren Sie das Matching also selbst. Die Implementierung basiert auf Around here.

Ich weiß nicht, wie ich "Entfernung" finden und entsprechend berechnen kann, also benutze sie nicht als Referenz.

Standarddurchschnittliche Differenz der Neigungsbewertung


from sklearn.neighbors import NearestNeighbors

#Berechnung von ASAM
def calculate_asam(data, treatment_column, columns):
  treated_index = data[treatment_column]
  data = pd.get_dummies(data[columns])

  asam = data.apply(lambda c: abs(c[treated_index].mean() - c[~treated_index].mean()) / c.std())
  asam['distance'] = np.sqrt(np.sum(asam**2))  #Ich verstehe die Definition nicht
  return asam

#Propensity Score Matching
def get_matching_data(data, treatment_column, propensity_score):
  data['ps'] = propensity_score
  treated = data[data[treatment_column] == 1]
  control = data[data[treatment_column] == 0]

  #Proben mit Intervention abgleichen
  control_neighbors = NearestNeighbors(n_neighbors=1, algorithm='ball_tree').fit(control['ps'].values.reshape(-1, 1))
  distances, indices = control_neighbors.kneighbors(treated['ps'].values.reshape(-1, 1))
  #Sie können den Übereinstimmungsschwellenwert mit Entfernungen festlegen(Nicht kompatibel)

  matching_data = pd.concat([treated, control.iloc[indices.flatten()]])
  return matching_data

matching_data = get_matching_data(biased_data[['treatment', 'recency', 'channel', 'history']], 'treatment', nearest_ate.propensity_scores)
unadjusted_asam = calculate_asam(biased_data, 'treatment', ['recency', 'history', 'channel'])
matching_adjusted_asam = calculate_asam(matching_data, 'treatment', ['recency', 'history', 'channel'])

IPW

Mit DescrStatsW können Sie leicht gewichtete Statistiken berechnen. Unterscheidet sich der Wert, wenn er nicht gewichtet wird, geringfügig vom Ergebnis von numpy? Seien Sie also vorsichtig beim Umgang damit.

IPW standardisierte durchschnittliche Differenz


from statsmodels.stats.weightstats import DescrStatsW

def calculate_asam_weighted(data, treatment_column, columns, propensity_score):
  data = pd.get_dummies(data[[treatment_column] + columns])
  data['ps'] = propensity_score
  data['weight'] = data[[treatment_column, 'ps']].apply(lambda x: 1 / x['ps'] if x[treatment_column] else 1 / (1 - x['ps']), axis=1)

  asam_dict = dict()
  for column_name, column_value in data.drop([treatment_column, 'ps', 'weight'], axis=1).iteritems():
    treated_stats = DescrStatsW(column_value[data[treatment_column]], weights=data[data[treatment_column]]['weight'])
    control_stats = DescrStatsW(column_value[~data[treatment_column]], weights=data[~data[treatment_column]]['weight'])
    asam_dict[column_name] = abs(treated_stats.mean - control_stats.mean) / treated_stats.std

  asam = pd.Series(asam_dict)
  asam['distance'] = np.sqrt(np.sum(asam**2))  #Ich verstehe die Definition nicht
  return asam

ipw_adjusted_asam = calculate_asam_weighted(biased_data, 'treatment', ['recency', 'history', 'channel'], ipw_estimate.propensity_scores)

Visualisierung

Visualisierung


%matplotlib inline
import matplotlib.pyplot as plt

plt.scatter(unadjusted_asam, unadjusted_asam.index, label='unadjusted')
plt.scatter(matching_adjusted_asam, matching_adjusted_asam.index, label='adjusted(matching)')
plt.scatter(ipw_adjusted_asam, ipw_adjusted_asam.index, label='adjusted(ipw)')
plt.vlines(0.1, 0, len(unadjusted_asam)-1, linestyles='dashed')
plt.legend()
plt.show()

image.png

Irgendwie ist IPW besser, aber wahrscheinlich, weil der Propensity Score Matching das Duplizieren von Matching Samples beim Matching des nächsten Nachbarn ermöglicht und auf einige Samples ausgerichtet ist.

Beziehung

Recommended Posts

Einführung in die Überprüfung der Wirksamkeit Kapitel 3 in Python geschrieben
Einführung in die Überprüfung der Wirksamkeit Kapitel 2 in Python geschrieben
Einführung in die Überprüfung der Wirksamkeit Kapitel 1 in Python geschrieben
Einführung in die Effektüberprüfung Schreiben der Kapitel 4 und 5 in Python
Geschrieben "Einführung in die Effektüberprüfung" in Python
[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 Python3 Tag 21] Kapitel 10 System (10.1 bis 10.5)
"Einführung in die Effektüberprüfung Kapitel 3 Analyse mit dem Neigungswert" + α wird in Python versucht
In Python geschriebener Fourier-Serien-Verifizierungscode
[Einführung in Python] Wie verwende ich eine Klasse in Python?
[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)
[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)
Einführung in Vektoren: Lineare Algebra in Python <1>
[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 die Python-Sprache
[Einführung in Python3, Tag 22] Kapitel 11 Parallele Verarbeitung und Vernetzung (11.1 bis 11.3)
Einführung in OpenCV (Python) - (2)
[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)
[Einführung in Python3 Tag 20] Kapitel 9 Enträtseln des Webs (9.1-9.4)
[Einführung in Python3 Tag 8] Kapitel 4 Py Skin: Codestruktur (4.1-4.13)
Analysieren Sie eine JSON-Zeichenfolge, die in eine Datei in Python geschrieben wurde
[Kapitel 5] Einführung in Python mit 100 Klopfen Sprachverarbeitung
[Kapitel 3] Einführung in Python mit 100 Klopfen Sprachverarbeitung
[Kapitel 2] Einführung in Python mit 100 Klopfen Sprachverarbeitung
Einführung in die lineare Algebra mit Python: A = LU-Zerlegung
[Technisches Buch] Einführung in die Datenanalyse mit Python -1 Kapitel Einführung-
[Kapitel 4] Einführung in Python mit 100 Klopfen Sprachverarbeitung
Einführung in Python Django (2) Win
Melden Sie sich auf der Website in Python an
Einführung in die serielle Kommunikation [Python]
Entwurfsmuster in Python: Einführung
Sprechen mit Python [Text zu Sprache]
[Einführung in Python] <Liste> [Bearbeiten: 22.02.2020]
Einführung in Python (Python-Version APG4b)
Gacha geschrieben in Python -BOX Gacha-
Eine Einführung in die Python-Programmierung
Wie man in Python entwickelt
Einführung in Python For, While
Post an Slack in Python
[Einführung in die Udemy Python3 + -Anwendung] 36. Verwendung von In und Not
[Einführung in Python3 Tag 3] Kapitel 2 Py-Komponenten: Numerische Werte, Zeichenfolgen, Variablen (2.2 bis 2.3.6)
[Einführung in Python3 Tag 2] Kapitel 2 Py-Komponenten: Numerische Werte, Zeichenfolgen, Variablen (2.1)
[Einführung in Python3 Tag 4] Kapitel 2 Py-Komponenten: Numerische Werte, Zeichenfolgen, Variablen (2.3.7 bis 2.4)
Cooles Lisp geschrieben in Python: Hy
[Einführung in die Udemy Python3 + -Anwendung] 58. Lambda
[Einführung in die Udemy Python3 + -Anwendung] 31. Kommentar
[Python] Wie man PCA mit Python macht
Einführung in die Python Numerical Calculation Library NumPy
Trainieren! !! Einführung in Python Type (Type Hints)
[Einführung in Python3 Tag 1] Programmierung und Python
Konvertieren Sie Markdown in Python in PDF
So sammeln Sie Bilder in Python
100 Sprachverarbeitung Knock Kapitel 1 in Python
[Einführung in Python] <numpy ndarray> [edit: 2020/02/22]
[Einführung in die Udemy Python3 + -Anwendung] 57. Decorator