Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Vectorize adstock transformations #15

Merged
merged 8 commits into from Apr 7, 2022

Conversation

juanitorduz
Copy link
Collaborator

@juanitorduz juanitorduz commented Mar 30, 2022

In this PR we add a vectorized version of the adstoc transformations to avoid writing for loops when going over channels transformations. For example, for 3 channels and 169 observation we can write:

coords = {"channels": ["ch1", "ch2", "ch3"]}


with pm.Model(coords=coords) as model:
    # --- Priors ---
    intercept = pm.Normal(name="intercept", mu=0, sd=2)
    beta = pm.HalfNormal(name="beta", sigma=2, dims="channels")
    alpha = pm.Beta(name="alpha", alpha=1, beta=1, dims="channels")
    lam = pm.HalfNormal("lam", sigma=2, dims="channels")
    sigma = pm.HalfNormal(name="sigma", sd=2)

    # --- Model Parametrization ---
    channels_adstock = geometric_adstock_vectorized(
        x=scaled_channels_df, alpha=alpha, normalize=True
    )
    channels_adstock_saturated = logistic_saturation(x=channels_adstock, lam=lam)
    mu = intercept + pm.math.dot(channels_adstock_saturated, beta)

    # --- Likelihood ---
    likelihood = pm.Normal("likelihood", mu=mu, sigma=sigma, observed=scaled_y)

pm.model_to_graphviz(model)

image

@juanitorduz juanitorduz self-assigned this Mar 30, 2022
@juanitorduz
Copy link
Collaborator Author

juanitorduz commented Apr 2, 2022

In 9257d0b I added an experimental implementation of the geometric adstock function using aesara.scan to try to omit for loops. Note that this one works for both scalars and vectors (see tests). Feedback is welcome!

@juanitorduz
Copy link
Collaborator Author

juanitorduz commented Apr 2, 2022

Well ... I really tried my best to write a geometric adstock function which was able to handle scalar and vector values, could accept the l_max argument and to support normalisation.... the geometric_adstock_scan does all of it BUT is super slow and not really usable in practice.

In my current project I have used the geometric_adstock_vectorized and it works super nice! The only drawback is that does not work for scalars but I guess that is ok as we have the initial implementation.

Hence, we could simply remove geometric_adstock_scan or put it in an experimental phase to see if we can make it work. After this decision I will simple hope to merge this PR so that we can test and use geometric_adstock_vectorized.

I am sorry about the d-tour with the scan approach but I just wanted to try it out.

@juanitorduz
Copy link
Collaborator Author

In 462b69d I removed the implementation using scan.

@juanitorduz
Copy link
Collaborator Author

In 9db1d14 and 434a18d I organised the test of the transformers module better. This is ready for review! 🚀

Copy link
Contributor

@ricardoV94 ricardoV94 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good. Just left two small comments regarding the tests

@juanitorduz juanitorduz merged commit 6cfc143 into main Apr 7, 2022
@juanitorduz juanitorduz deleted the feature/vectorize_adstock_transformations branch April 7, 2022 15:40
@juanitorduz juanitorduz mentioned this pull request Apr 8, 2022
@ricardoV94 ricardoV94 added enhancement New feature or request MMM labels Feb 8, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request MMM
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants