Understanding on Discrete Treatment (p>2) Inference with CausalForestDML
Nobody has claimed this yet.
- Dominant language
- Jupyter Notebook
- Stars
- 4.8k
- Forks
- 827
- PR merge metrics
- No merged PRs in 30d
Description
Hello!
I didn't see any examples where there existed a discrete treatment with multiple values (>2) and a binary outcome. I am hopeful someone can confirm my understanding.
This data set is from a marketing campaign where customers received one of three treatments (https://blog.minethatdata.com/2008/03/minethatdata-e-mail-analytics-and-data.html):
- No Email
- Email about Womans category products
- Email about Male category products
The outcome I chose here is if the customer visited after the campaign, or not.
Lets say the research question was if the treatment effect depended on the customers prior purchase categories (of which Mens and Womens are binary values in the data)
Here I am setting the treatment to a numeric (1,2,3) for the three categories and using a regression wrapper function to overcome the fact that econml doesnt natively support non-numeric outcomes.
import econml
import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
from econml.dml import CausalForestDML
from sklearn.model_selection import train_test_split
import xgboost
import warnings
warnings.filterwarnings("ignore")
from sklearn.base import BaseEstimator, clone
class RegressionWrapper(BaseEstimator):
def __init__(self, clf):
self.clf = clf
def fit(self, X, y, **kwargs):
self.clf_ = clone(self.clf)
self.clf_.fit(X, y, **kwargs)
return self
def predict(self, X):
return self.clf_.predict_proba(X)[:, 1]
# read data and create indicator variables
dat = pd.read_csv('http://www.minethatdata.com/Kevin_Hillstrom_MineThatData_E-MailAnalytics_DataMiningChallenge_2008.03.20.csv')
dat['phone'] = np.where(dat.channel == 'Phone',1,0)
dat['web'] = np.where(dat.channel == 'Web',1,0)
dat['multi'] = np.where(dat.channel == 'Multichannel',1,0)
dat['suburban'] = np.where(dat.zip_code == 'Suburban',1,0)
dat['rural'] = np.where(dat.zip_code == 'Rural',1,0)
dat['urban'] = np.where(dat.zip_code == 'Urban',1,0)
# treatment
dat['test_numeric'] = 3 # womens
dat['test_numeric'] = np.where(dat.segment == 'No E-Mail',1,dat['test_numeric'].values) # control
dat['test_numeric'] = np.where(dat.segment == 'Mens E-Mail',2,dat['test_numeric'].values) # mens
# train / test split
X_train, X_test, y_train, y_test = train_test_split(dat.drop('visit',axis=1), dat[['visit']], test_size=0.50, random_state=42)
# treatment, confounders / nusiance and two variables of interest
T = X_train['test_numeric']
W = X_train[['phone','web','multi','history','recency']]
X = X_train[['mens','womens']]
# outcome
Y = y_train
#model for the treatments
xgb_model_mc = xgboost.XGBClassifier(objective="multi:softmax", num_class =3, random_state=42)
# model for the outcome
xgb_model = xgboost.XGBClassifier(objective="binary:logistic", random_state=42)
causal_forest = CausalForestDML(criterion='het',
n_estimators=5000,
min_samples_leaf=10,
max_depth=5,
max_samples=0.5,
discrete_treatment=True, # discrete treatments
honest=True,
inference=True,
cv=10,
model_t=xgb_model_mc, # model to use for treatments
model_y=RegressionWrapper(xgb_model), # model for y
)
# fit train data to causal forest model
causal_forest.fit(Y = Y.values , T = T.values, X = X.values, W = W.values)
The inference for the treatment effect of Womans email versus no email is here (Mens would be simiiar)
#treatment effect (womens email - no email) when the customers purchased......
# 1) only from womens and not mens
# 2) both womens and mens
# 3) only mens
# 4) neither
X = np.array([[0,1],[1,1],[1,0],[0,0]])
infer_result = causal_forest.effect_inference(X =X,T0 =1 , T1 =3 )
result_pd = infer_result.summary_frame()
result_pd.index=['Only Womens', 'Both Mens and Womens', 'Only Mens', 'Neither']
result_pd
and the result:


Is this the proper way to conduct this analysis using Casual Forest?
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the CausalForestDML entry point and the treatment and outcome configuration shown in the issue. Review the existing documentation and examples for discrete multi-valued treatments and binary outcomes, then define what guidance or example would answer whether this analysis is supported and how the effects should be interpreted.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- jupyter-notebook, machine-learning, python
- Domain
- machine-learning
- Issue type
- Documentation
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Needs clarification
- Newbie friendliness
- 18/100