WillianFuks / tfcausalimpact

Python Causal Impact Implementation Based on Google's R Package. Built using TensorFlow Probability.
Apache License 2.0
600 stars 72 forks source link

Get weights of each covariate used #43

Closed ocesp98 closed 2 years ago

ocesp98 commented 2 years ago

Is there any way to see the weights assigned to each of the covariates? I tried the ci.model_samples[2].numpy().mean(axis=0), but it only gives back one value. I would like to know the importance of each control country (country = column in dataframe) to get an estimate of the target country. It would be interesting to see for instance that target country X was reconstructed by a large part of control country A and a smaller part of control country B.

WillianFuks commented 2 years ago

Hi @ocesp98 ,

Fun fact before I answer, I thought I had already answered your question. Twice 😅

Just now I realized that, as it seems, I actually didn't. Twice. (I looked for closed issues lol). Sorry for the delay!

So I decided to update the getting_started.ipynb notebook in section 2.5 Understanding Results with some examples.

Here's a summary of how you can do that:

ci = CausalImpact(dated_data, pre_period, post_period, model_args={'standardize': False})
tf.reduce_mean(ci.model.components_by_name['SparseLinearRegression/'].params_to_weights(
    ci.model_samples['SparseLinearRegression/_global_scale_variance'],
    ci.model_samples['SparseLinearRegression/_global_scale_noncentered'],
    ci.model_samples['SparseLinearRegression/_local_scale_variances'],
    ci.model_samples['SparseLinearRegression/_local_scales_noncentered'],
    ci.model_samples['SparseLinearRegression/_weights_noncentered'],
), axis=0)

Please refer to the notebook itself to see further developments and discussion on this topic.

Let me know if this helps you.

Best,

Will

ocesp98 commented 2 years ago

Hey yes thanks! I am using the hmc method though so I work with the indices instead of the names!

WillianFuks commented 2 years ago

In the notebook there's an example on how to handle that as well. A helper function is needed:

def get_param_index(model, name):
    for i, v in enumerate(model.parameters):
        if v.name == name:
            return i

tf.reduce_mean(ci.model.components_by_name['SparseLinearRegression/'].params_to_weights(
    ci.model_samples[get_param_index(ci.model, 'SparseLinearRegression/_global_scale_variance')],
    ci.model_samples[get_param_index(ci.model, 'SparseLinearRegression/_global_scale_noncentered')],
    ci.model_samples[get_param_index(ci.model, 'SparseLinearRegression/_local_scale_variances')],
    ci.model_samples[get_param_index(ci.model, 'SparseLinearRegression/_local_scales_noncentered')],
    ci.model_samples[get_param_index(ci.model, 'SparseLinearRegression/_weights_noncentered')],
), axis=0)
WillianFuks commented 2 years ago

Hi @ocesp98 ,

Just to confirm, did it all work for you? Not sure if the newer notebook examples are good enough, please let me know what you think.

ocesp98 commented 2 years ago

Hi sorry for the late reply but indeed it worked! Thank you very much :)