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

BudgetOptimizer does not seem to support time-varying intercept #757

Open
AlfredoJF opened this issue Jun 18, 2024 · 11 comments
Open

BudgetOptimizer does not seem to support time-varying intercept #757

AlfredoJF opened this issue Jun 18, 2024 · 11 comments
Labels
bug Something isn't working MMM

Comments

@AlfredoJF
Copy link

Not quite sure if this will be fixed in the upcoming 0.7.0 release but noticed the re-written BudgetOptimizer does not work with time-varying intercept or there's a conflict with PyTensor.

I followed the mmm_budget_allocation_example.ipynb and in this cell was when I got the error.

response = mmm.allocate_budget_to_maximize_response(
    budget=total_budget,
    num_days=8,
    time_granularity="weekly",
    budget_bounds=budget_bounds
)

Here is the error I got using an MMM with tvp that did not come up with another MMM without time-varying intercept:

NotImplementedError                       Traceback (most recent call last)
[/usr/local/lib/python3.10/dist-packages/pytensor/link/basic.py](https://localhost:8080/#) in __set__(self, value)
    101                 # Use in-place filtering when/if possible
--> 102                 self.storage[0] = self.type.filter_inplace(
    103                     value, self.storage[0], **kwargs

10 frames
[/usr/local/lib/python3.10/dist-packages/pytensor/graph/type.py](https://localhost:8080/#) in filter_inplace(self, value, storage, strict, allow_downcast)
    127         """
--> 128         raise NotImplementedError()
    129 

NotImplementedError: 

During handling of the above exception, another exception occurred:

TypeError                                 Traceback (most recent call last)
[<ipython-input-49-329a8396104b>](https://localhost:8080/#) in <cell line: 1>()
----> 1 response = mmm.allocate_budget_to_maximize_response(
      2     budget=total_budget,
      3     num_days=8,
      4     time_granularity="weekly",
      5     budget_bounds=budget_bounds

[/usr/local/lib/python3.10/dist-packages/pymc_marketing/mmm/delayed_saturated_mmm.py](https://localhost:8080/#) in allocate_budget_to_maximize_response(self, budget, time_granularity, num_days, budget_bounds, custom_constraints, quantile)
   1977         )
   1978 
-> 1979         return self.sample_posterior_predictive(
   1980             X_pred=synth_dataset,
   1981             extend_idata=False,

[/usr/local/lib/python3.10/dist-packages/pymc_marketing/mmm/delayed_saturated_mmm.py](https://localhost:8080/#) in sample_posterior_predictive(self, X_pred, extend_idata, combined, include_last_observations, original_scale, **sample_posterior_predictive_kwargs)
   1644 
   1645         with self.model:  # sample with new input data
-> 1646             post_pred = pm.sample_posterior_predictive(
   1647                 self.idata, **sample_posterior_predictive_kwargs
   1648             )

[/usr/local/lib/python3.10/dist-packages/pymc/sampling/forward.py](https://localhost:8080/#) in sample_posterior_predictive(trace, model, var_names, sample_dims, random_seed, progressbar, progressbar_theme, return_inferencedata, extend_inferencedata, predictions, idata_kwargs, compile_kwargs)
    859                     param = _trace[idx % len_trace]
    860 
--> 861                 values = sampler_fn(**param)
    862 
    863                 for k, v in zip(vars_, values):

[/usr/local/lib/python3.10/dist-packages/pymc/util.py](https://localhost:8080/#) in wrapped(**kwargs)
    393     def wrapped(**kwargs):
    394         input_point = {k: v for k, v in kwargs.items() if k in ins}
--> 395         return core_function(**input_point)
    396 
    397     return wrapped

[/usr/local/lib/python3.10/dist-packages/pytensor/compile/function/types.py](https://localhost:8080/#) in __call__(self, *args, **kwargs)
    895         if kwargs:  # for speed, skip the items for empty kwargs
    896             for k, arg in kwargs.items():
--> 897                 self[k] = arg
    898 
    899         if (

[/usr/local/lib/python3.10/dist-packages/pytensor/compile/function/types.py](https://localhost:8080/#) in __setitem__(self, item, value)
    547 
    548     def __setitem__(self, item, value):
--> 549         self.value[item] = value
    550 
    551     def __copy__(self):

[/usr/local/lib/python3.10/dist-packages/pytensor/compile/function/types.py](https://localhost:8080/#) in __setitem__(self, item, value)
    503                     )
    504                 if isinstance(s, Container):
--> 505                     s.value = value
    506                     s.provided += 1
    507                 else:

[/usr/local/lib/python3.10/dist-packages/pytensor/link/basic.py](https://localhost:8080/#) in __set__(self, value)
    104                 )
    105             except NotImplementedError:
--> 106                 self.storage[0] = self.type.filter(value, **kwargs)
    107 
    108         except Exception as e:

[/usr/local/lib/python3.10/dist-packages/pytensor/tensor/type.py](https://localhost:8080/#) in filter(self, data, strict, allow_downcast)
    240 
    241         if self.ndim != data.ndim:
--> 242             raise TypeError(
    243                 f"Wrong number of dimensions: expected {self.ndim},"
    244                 f" got {data.ndim} with shape {data.shape}."

TypeError: ('Wrong number of dimensions: expected 0, got 1 with shape (118,).', 'Container name "intercept"')
@AlfredoJF AlfredoJF changed the title BudgetOptimizer does not seem to support time-varying intercept BudgetOptimizer does not seem to support time-varying intercept Jun 18, 2024
@wd60622 wd60622 added the MMM label Jun 18, 2024
@wd60622
Copy link
Contributor

wd60622 commented Jun 18, 2024

Hi @AlfredoJF,
thank you for bringing this up. Are you having issues with the out of sample prediction as well? Would you be able to give that method as well.

CC: @cetagostini

@juanitorduz juanitorduz added the bug Something isn't working label Jun 18, 2024
@juanitorduz
Copy link
Collaborator

It seems like a broadcasting issue right @wd60622 ?

@AlfredoJF
Copy link
Author

Hi @wd60622, no issues with the Out-of-sample posterior only with the BudgetOptimizer

y_test_pred = mmm.sample_posterior_predictive(X_pred=X_test, extend_idata=False, include_last_observations=True)

@wd60622
Copy link
Contributor

wd60622 commented Jun 19, 2024

Hi @AlfredoJF,
Thanks for checking that. If you have found the culprit, feel free to open a PR!
If not, we can do some investigation. Would you be able to post a small reproducible example (including the initialization of the class)?

@AlfredoJF
Copy link
Author

Hi @wd60622,

Yes, I'll post a reproducible example and leave the investigation to the experts for now. :)

@wd60622
Copy link
Contributor

wd60622 commented Jun 20, 2024

Yes, I'll post a reproducible example and leave the investigation to the experts for now. :)

Great, sounds good. We a reproducible example, we can dig into it a bit better.
We should be able to get to it soon

@AlfredoJF
Copy link
Author

Hi @wd60622

I used the mmm and tvp example data to see if I could create a reproducible example for further investigation but I did not get the same error as in my model. I cannot share my dataset as it contains client's data but will try to create another dataset for this purpose.

Thanks for the patience!

@AlfredoJF
Copy link
Author

I just tested the first workaround in #814, and it fixed this issue. So I assume #815 also fixes this one for the next release.

@wd60622
Copy link
Contributor

wd60622 commented Jul 9, 2024

I just tested the first workaround in #814, and it fixed this issue. So I assume #815 also fixes this one for the next release.

Mmm interesting that that workaround helped out this one as well. Not obvious why that would be the case.
Are you using 0.7.0 then? or installed from main branch?

@AlfredoJF
Copy link
Author

@wd60622 Yes, I'm using 0.7.0 and have overwritten the MMM class for now as I'm closer to the delivery date of my project. I'll upgrade to 0.8.0 once it's released in a future iteration of my model

@wd60622
Copy link
Contributor

wd60622 commented Jul 9, 2024

@wd60622 Yes, I'm using 0.7.0 and have overwritten the MMM class for now as I'm closer to the delivery date of my project. I'll upgrade to 0.8.0 once it's released in a future iteration of my model

Sounds good. Well glad that it sorted itself out.
If you run into any more issues, feel free to raise an issue.

I will leave this issue open for now

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working MMM
Projects
None yet
Development

No branches or pull requests

3 participants