pymc-labs / pymc-marketing

Bayesian marketing toolbox in PyMC. Media Mix (MMM), customer lifetime value (CLV), buy-till-you-die (BTYD) models and more.
https://www.pymc-marketing.io/
Apache License 2.0
702 stars 194 forks source link

`prior_linearized` no longer has `Xs` kwarg #786

Closed shuvayan closed 4 months ago

shuvayan commented 4 months ago

Hello ,

I am trying to use the time varying intercept feature while defining the model config , but it leads to an error (which was not there yesterday). Below are the model definitions and configurations:

best_params = {'prior_sigma': 4.453374020135536, 
 'mu_A_S': 0.5254728909760423, 
 'mu_B_S': 4.858094986582797,
 'mu_C_S': 0.20741840049133997,
 'mu_D_S': 1.3932538309035063,
 'mu_E_S': 4.349563730296513,
 'mu_F_S': 2.9837827690151446,
 'alpha': 3.5721111826244427, 
 'lam_alpha': 3.159080650860037, 
 'lam_beta': 6.057818770627395, 
 'likelihood_sigma': 4.768963099225516,
 'gamma_control_mu': 3.6755851428916966, 
 'gamma_control_sigma': 3.99927540072232, 
 'gamma_fourier_mu': -4.815992857627947,
 'gamma_fourier_b': 1.6883991281354374,
 'intercept_tvp_m': 42, 
 'intercept_tvp_ls_mu': 56.28947569502999,
 'intercept_tvp_ls_sigma': 3.489056734555973,
 'intercept_tvp_eta_lam': 0.4855496517028385}

custom_best_channel_prior = {
        'intercept': {'dist': 'HalfNormal', 'kwargs': {'sigma': 0.05}},
        'beta_channel': {'dist': 'Normal', 'kwargs': {'mu': [best_params[f'mu_{ch}'] for ch in channels], 'sigma': best_params['prior_sigma']}},
        'alpha': {'dist': 'Beta', 'kwargs': {'alpha': best_params['alpha'], 'beta': 3}},
        'lam': {'dist': 'Gamma', 'kwargs': {'alpha': best_params['lam_alpha'], 'beta': best_params['lam_beta']}},
        'likelihood': {'dist': 'Normal', 'kwargs': {'sigma': {'dist': 'HalfNormal', 'kwargs': {'sigma': best_params['likelihood_sigma']}}}},
        'gamma_control': {'dist': 'Normal', 'kwargs': {'mu': best_params['gamma_control_mu'], 'sigma': best_params['gamma_control_sigma']}},
        'gamma_fourier': {'dist': 'Laplace', 'kwargs': {'mu': best_params['gamma_fourier_mu'], 'b': best_params['gamma_fourier_b']}},
        'intercept_tvp_kwargs': {
            'm': best_params['intercept_tvp_m'],
            'L': None,
            'eta_lam': best_params['intercept_tvp_eta_lam'],
            'ls_mu': best_params['intercept_tvp_ls_mu'],
            'ls_sigma': best_params['intercept_tvp_ls_sigma'],
            'cov_func': None
        }
    }

test_mmm = DelayedSaturatedMMM(
    model_config = custom_best_channel_prior,
    target_column='R',
    date_column='Dates',
    validate_data = True,
    channel_columns=spend_cols,
    control_columns = ['holiday'],
    adstock_max_lag = 8, 
    yearly_seasonality = 2,
    time_varying_intercept = True
)
test_mmm.model_config

idata = test_mmm.fit(X_new,y, target_accept=0.98, chains=4, random_seed=43)

However, it throws up the below error:

Error:
"""
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
Cell In[93], line 1
----> 1 idata = test_mmm.fit(X_new,y, target_accept=0.98, chains=4, random_seed=43)

File ~/.local/lib/python3.12/site-packages/pymc_marketing/model_builder.py:462, in ModelBuilder.fit(self, X, y, progressbar, predictor_names, random_seed, **kwargs)
    459     raise ValueError("X and y must be set before calling build_model!")
    461 if self.model is None:
--> 462     self.build_model(self.X, self.y)
    464 sampler_config = self.sampler_config.copy()
    465 sampler_config["progressbar"] = progressbar

File ~/.local/lib/python3.12/site-packages/pymc_marketing/mmm/delayed_saturated_mmm.py:410, in BaseDelayedSaturatedMMM.build_model(self, X, y, **kwargs)
    404 if self.time_varying_intercept:
    405     time_index = pm.Data(
    406         "time_index",
    407         self._time_index,
    408         dims="date",
    409     )
--> 410     intercept = create_time_varying_intercept(
    411         time_index,
    412         self._time_index_mid,
    413         self._time_resolution,
    414         self.intercept_dist,
    415         self.model_config,
    416     )
    417 else:
    418     intercept = self.intercept_dist(
    419         name="intercept", **self.model_config["intercept"]["kwargs"]
    420     )

File ~/.local/lib/python3.12/site-packages/pymc_marketing/mmm/tvp.py:137, in create_time_varying_intercept(time_index, time_index_mid, time_resolution, intercept_dist, model_config)
    132 if model_config["intercept_tvp_kwargs"]["ls_mu"] is None:
    133     model_config["intercept_tvp_kwargs"]["ls_mu"] = (
    134         DAYS_IN_YEAR / time_resolution * 2
    135     )
--> 137 multiplier = time_varying_prior(
    138     name="intercept_time_varying_multiplier",
    139     X=time_index,
    140     dims="date",
    141     X_mid=time_index_mid,
    142     **model_config["intercept_tvp_kwargs"],
    143 )
    144 intercept_base = intercept_dist(
    145     name="intercept_base", **model_config["intercept"]["kwargs"]
    146 )
    147 return pm.Deterministic(
    148     name="intercept",
    149     var=intercept_base * multiplier,
    150     dims="date",
    151 )

File ~/.local/lib/python3.12/site-packages/pymc_marketing/mmm/tvp.py:99, in time_varying_prior(name, X, dims, X_mid, m, L, eta_lam, ls_mu, ls_sigma, cov_func)
     96     hsgp_dims = (dims[1], "m")
     98 gp = pm.gp.HSGP(m=[m], L=[L], cov_func=cov_func)
---> 99 phi, sqrt_psd = gp.prior_linearized(Xs=X[:, None] - X_mid)
    100 hsgp_coefs = pm.Normal(f"{name}_hsgp_coefs", dims=hsgp_dims)
    101 f = phi @ (hsgp_coefs * sqrt_psd).T

TypeError: HSGP.prior_linearized() got an unexpected keyword argument 'Xs'
"""
What does this error mean and how do I resolve this?
wd60622 commented 4 months ago

Hi @shuvayan Thanks for reporting. That is a bug with a change from two weeks ago: https://github.com/pymc-devs/pymc/commit/7bb5d057bf392865543943656d925de5dcee0e93

Would you be able to make a PR? I'd suggest not using keyword arg so we can support previous versions

If you need a quick fix, I would restrict the PyMC version to the release before this linked commit

shuvayan commented 4 months ago

Hi @wd60622 ,

I don't have any experience in creating PR's./ If you could guide me I will give it a try!

juanitorduz commented 4 months ago

@shuvayan One of the best and most complete guides I have seen is https://www.sktime.net/en/stable/developer_guide/git_workflow.html. They have a step-by-step guide to creating PRs. Let us know if you need some help :)

wd60622 commented 4 months ago

@shuvayan One of the best and most complete guides I have seen is https://www.sktime.net/en/stable/developer_guide/git_workflow.html. They have a step-by-step guide to creating PRs. Let us know if you need some help :)

Very nice walkthrough. If you run into any issues, let us know!

shuvayan commented 4 months ago

Okay, So we need to make changes to the tvp.py file within the mmm folder using the changes in https://github.com/pymc-devs/pymc/commit/7bb5d057bf392865543943656d925de5dcee0e93 Let me know if my understanding is correct.

wd60622 commented 4 months ago

Okay,

So we need to make changes to the tvp.py file within the mmm folder using the changes in

https://github.com/pymc-devs/pymc/commit/7bb5d057bf392865543943656d925de5dcee0e93

Let me know if my understanding is correct.

Yes, sounds right to me. Make some edits, push up and start PR, and we can give some feedback

shuvayan commented 4 months ago

Hello @wd60622 ,

I have made the changes in tvp.py locally and I think it is working fine with the updated pymc version too. Just that I see a lot of divergences during the model training. Can you please take a look at the attached pdf and let me know if I am missing something.

If not, I will push the PR with the changes. pymc_tvp_ipynb.pdf

wd60622 commented 4 months ago

Hello @wd60622 ,

I have made the changes in tvp.py locally and I think it is working fine with the updated pymc version too. Just that I see a lot of divergences during the model training. Can you please take a look at the attached pdf and let me know if I am missing something.

If not, I will push the PR with the changes. pymc_tvp_ipynb.pdf

Hi @shuvayan. Just push up the changes that you have tried out! We can review with a PR

shuvayan commented 4 months ago

Done .

https://github.com/pymc-labs/pymc-marketing/pull/806