py-why / EconML

ALICE (Automated Learning and Intelligence for Causation and Economics) is a Microsoft Research project aimed at applying Artificial Intelligence concepts to economic decision making. One of its goals is to build a toolkit that combines state-of-the-art machine learning techniques with econometrics in order to bring automation to complex causal inference problems. To date, the ALICE Python SDK (econml) implements orthogonal machine learning algorithms such as the double machine learning work of Chernozhukov et al. This toolkit is designed to measure the causal effect of some treatment variable(s) t on an outcome variable y, controlling for a set of features x.
https://www.microsoft.com/en-us/research/project/alice/
Other
3.82k stars 714 forks source link

Individual Treatment Effects #869

Open PrannoyLFC opened 7 months ago

PrannoyLFC commented 7 months ago

Hi @kbattocchi ,

I used the following code to calculate the ATE for my panel data (around ~$18).

dml = DynamicDML(model_y=outcome_model, model_t=treatment_model, cv=2, discrete_treatment=True)

dml.fit(Y=Y, T=T, X=None, W=X, groups=groups)

Is it possible to get individual treatment effects too? Ie how much causal impact the treatment would gave in the outcome variable for each row of my data?

ellpri commented 7 months ago

@PrannoyLFC I think, in order to get the effect for each row, you need to use dml.effect(x_test)Reference

TimCosemans commented 2 months ago

Hi!

I was wondering the same thing. The '.effect' method does not seem to be doing what I want. As a consequence, I have come up with this piece of code

`

def calculate_tau(df, model, X_names, T_names):

    m = len(T_names)

    coefficients = [model.coef_[i::m] for i in range(0, m)]
    # coeffcients for each treatment in shape (m, t, P)
    coefficients = np.stack(coefficients, axis=0)

    intercept = [model.intercept_[i::m] for i in range(0, m)]
    # intercept for each treatment in shape (m, t, 1)
    intercept = np.stack(intercept, axis=0)[:, :, np.newaxis]

    # only the first row for heterogeneity
    X = df.loc[:, X_names].head(1).to_numpy()

    # DML estimators assume that the treatment effect is linear in T (assuming there is no treatment featurizer)
    # marginal effect is constant regardless of what values of T you provide
    # If either argument is N-D, N > 2, it is treated as a stack of matrices
    # residing in the last two indexes and broadcast accordingly
    effects = np.add(np.matmul(coefficients, X.T), intercept)
    effects = np.squeeze(effects, axis=2)  # shape (m, t)

    T = df.loc[:, T_names].to_numpy()

    df["tau"] = np.sum(np.multiply(effects.T, T), axis=1)  # shape (t)

    return df

data = data.sort_values(["ID", "time"]).groupby("ID").apply(
    calculate_tau, model=est, X_names=X.columns, T_names=T.columns).reset_index(drop=True)

`