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

Add thin wrapper around advi functionality #1365

Open
wants to merge 12 commits into
base: main
Choose a base branch
from

Conversation

PabloRoque
Copy link
Contributor

@PabloRoque PabloRoque commented Jan 13, 2025

Description

Introduces a thin wrapper around pm.fit so that advi can be used in CLV models
Some tests related to advi functionality

Related Issue

Checklist

Modules affected

  • MMM
  • CLV
  • Customer Choice

Type of change

  • New feature / enhancement
  • Bug fix
  • Documentation
  • Maintenance
  • Other (please specify):

📚 Documentation preview 📚: https://pymc-marketing--1365.org.readthedocs.build/en/1365/

Copy link

codecov bot commented Jan 13, 2025

Codecov Report

Attention: Patch coverage is 20.00000% with 16 lines in your changes missing coverage. Please review.

Project coverage is 55.97%. Comparing base (32f44c7) to head (9b70003).

Files with missing lines Patch % Lines
pymc_marketing/clv/models/basic.py 20.00% 16 Missing ⚠️

❗ There is a different number of reports uploaded between BASE (32f44c7) and HEAD (9b70003). Click for more details.

HEAD has 7 uploads less than BASE
Flag BASE (32f44c7) HEAD (9b70003)
11 4
Additional details and impacted files
@@             Coverage Diff             @@
##             main    #1365       +/-   ##
===========================================
- Coverage   93.94%   55.97%   -37.98%     
===========================================
  Files          48       48               
  Lines        5137     5156       +19     
===========================================
- Hits         4826     2886     -1940     
- Misses        311     2270     +1959     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@ColtAllen
Copy link
Collaborator

@wd60622 do you think it's more appropriate for advi support to be added to ModelBuilder instead?

@PabloRoque if your primary motivation is to speed up model fits, have you tried using nutpie? There's example code in this notebook.

@wd60622
Copy link
Contributor

wd60622 commented Jan 13, 2025

@wd60622 do you think it's more appropriate for advi support to be added to ModelBuilder instead?

Maybe long term but implementing now would require changing the fit api for all

@PabloRoque
Copy link
Contributor Author

Thanks for the suggestion @ColtAllen.

The issue is mainly that our customer base has 1E8 order of magnitude. I am afraid I'll hit the wall using mcmc when we put things on PROD, regardless of the sampler (normally I use numpyro), so I'm starting to explore advi.

pymc_marketing/clv/models/basic.py Outdated Show resolved Hide resolved
pymc_marketing/clv/models/basic.py Show resolved Hide resolved
stacklevel=2,
)
with self.model:
mean_field_approx = pm.fit(**{"method": "advi"})
Copy link
Contributor

Choose a reason for hiding this comment

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

Why this syntax? Will you add more kwargs here?
Just use method=advi

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I was planning to add more kwargs.
I added now functionality to parse the params and kwargs for both fit and sample

PabloRoque and others added 3 commits January 13, 2025 15:00
Co-authored-by: Will Dean <57733339+wd60622@users.noreply.github.com>
@ColtAllen
Copy link
Collaborator

Thanks for the suggestion @ColtAllen.

The issue is mainly that our customer base has 1E8 order of magnitude. I am afraid I'll hit the wall using mcmc when we put things on PROD, regardless of the sampler (normally I use numpyro), so I'm starting to explore advi.

I would encourage you to try nutpie before getting any further into this. I was not impressed with the results I got from ADVI fits when I experimented with it several years ago, and I don't think development on the ADVI module in PyMC is highly prioritized either (@ricardoV94)? ADVI is even slower than MCMC when fitting ParetoNBDModel, and is unusable for BetaGeoBetaBinomModel because it's a discrete model instead of a continuous one.

For datasets with millions of customers I usually recommend just using MAP. MAP is generally discouraged in the Bayesian community, but these CLV models are an exception due to the strong population assumptions underlying them. Beyond 30-50k customers, mean values for MAP and MCMC fits are identical. The only downside is that you'll lose the credibility intervals with MAP.

Copy link

Check out this pull request on  ReviewNB

See visual diffs & provide feedback on Jupyter Notebooks.


Powered by ReviewNB

@github-actions github-actions bot added the docs Improvements or additions to documentation label Jan 14, 2025
@PabloRoque
Copy link
Contributor Author

PabloRoque commented Jan 14, 2025

Thanks for the advices @ColtAllen.

I added a gist comparing DEMZ with ADVI and FULLRANK:

  • Fullrank does not match mcmc at all
  • Advi fit does not match for r and alpha, which is quite worrisome

I the light of your advices, and the little evidence I gathered myself, I'll be closing this PR

Thank you all!

@PabloRoque PabloRoque closed this Jan 14, 2025
@ColtAllen
Copy link
Collaborator

@PabloRoque glad to help! Looks like the gist you did for ParetoNBDModel also revealed a new multiprocessing warning to investigate, which is helpful.

@PabloRoque
Copy link
Contributor Author

I am sorry to be the bearer of "bad news", but I may be reopening this PR.

I've been able to improve the fit adjusting obj_n_mc following these advices.

The updated gist shows:

  • Poor fit using fullrank still. Happy to remove this functionality in the light of the results
  • Improved ADVI fit.
    • The mean of the param estimates differ less than 2% in the worst case
    • The sd is much worse, with advi providing narrower distributions

Some considerations, though.

  • Fitting time is considerably longer.
  • Still, ADVI allows for minibatch training

On a side note, I also tried to use pymc_extras.fit(method="pathfinder"). However jax does not support hyp2f1. [I see now why @ColtAllen is suggesting to use nutpie instead of numpyro]

@wd60622
Copy link
Contributor

wd60622 commented Jan 16, 2025

I'm not opposed to getting this through even if it is not "recommended" way of sampling the current models.

Support for minibatching is another beast. What work would be required there?

@PabloRoque PabloRoque reopened this Jan 16, 2025
@PabloRoque PabloRoque marked this pull request as ready for review January 16, 2025 13:58
@ColtAllen
Copy link
Collaborator

ColtAllen commented Jan 16, 2025

On a side note, I also tried to use pymc_extras.fit(method="pathfinder"). However jax does not support hyp2f1. [I see now why @ColtAllen is suggesting to use nutpie instead of numpyro]

Yes, I briefly looked into a jax implementation, but it would be quite challenging and with uncertain benefits. pytensor is already calling scipy.special.hyp2f1 for this function, which is written in C++. The problem is that Hyp2F1 gradients are very complex to calculate, which is why gradient-free samples are so much faster for it. On that note, Hyp2F1 is also only relevant for model fitting ParetoNBDModel.

My preference would be to make this more of a long-term PR for ModelBuilder so that MMMs are also supported. I could see minibatch ADVI being useful for hierarchical models. @wd60622 how "translatable" do you see this PR being for the ModelBuilder fit API? If this is a good starting point we can proceed, but I don't want it to become too proprietary to CLV?

@PabloRoque I've got a lot on my plate at the moment, but will make time to view your other PRs tomorrow & over the weekend. We're pushing to release pymc-marketing v0.11.0 ASAP.

@PabloRoque
Copy link
Contributor Author

@ColtAllen No rush!

I had a bit of bandwidth and attempted a few contributions, but I am not expecting a quick review in any case.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
CLV docs Improvements or additions to documentation tests
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants