-
Notifications
You must be signed in to change notification settings - Fork 241
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 baselined saturation #498
Conversation
for more information, see https://pre-commit.ci
Codecov ReportAll modified and coverable lines are covered by tests ✅
Additional details and impacted files@@ Coverage Diff @@
## main #498 +/- ##
==========================================
+ Coverage 90.87% 91.24% +0.37%
==========================================
Files 21 21
Lines 1983 2044 +61
==========================================
+ Hits 1802 1865 +63
+ Misses 181 179 -2 ☔ View full report in Codecov by Sentry. |
thanks for the writeup!!! Should be sure to mention that the reference point x0 has to be set within the range of the actual spends. As in, you buy ads three times and spend 5, 6 and 7 dollars, x0 has to be set within [5, 7], so not 4 not 8. Otherwise the posterior of r and gain becomes a skinny diagonal line. I got stuck on that one, and it could be very relevant if there is very little spend observations for a particular channel. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@ferrine this is amazing! Thanks! I think once you add @bwengals 's suggestion we are ready to merge!
More of a general question: Where would the adstock transformation come in? I guess before applying this one right?
Also, maybe for a next PR we can create another MMM model subclass to make sure users can use the API :)
Why not just do: def tanh_saturation_baseline(x, x0, gain, r):
saturation = (gain * x0) / r
cac0 = r / (gain * pt.arctanh(r))
return tanh_saturation(x, cac0, saturation) Only 4 lines! What functionality is the dataclass for the params and baseline and debaseline adding? Also: I don't understand the name "baseline", or how this is "baselined". Maybe something else would be a clearer name (sorry to critique without suggestions, I can't think of anything though!) |
for more information, see https://pre-commit.ci
for more information, see https://pre-commit.ci
The dataclasses are the helpers in case you need to visualize not just |
The adstock will be in just the same order
Why not a boolean parameter? |
I could imagine in the future, we would have many different models with different plotting functions, optimizations, depending on the functional forms ... just thinking ahead :) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM! Thanks!
As a side comment, personally (so not necessarily true ;) ) I like the NamedTuple
structure. It has crossed my mind to even use pydantic
for parameter and data validation.
Pydantic is great and I appreciate anyone taking effort to refactor everything to Pydantic, just not now. WDYT? |
I created a discussion issue #502 . I will be happy to work on this :) |
* current status as method * format * Update version.txt * Implement different convolution modes (#454) * Add PR template * Update pull_request_template.md * Fix issues in index example * Update .pre-commit-config.yaml * Update .pre-commit-config.yaml * move from other PR * put legend on side * Optimisation in customer_lifetime_value when discount_rate == 0 (#468) * Optimisation in customer_lifetime_value when discount_rate == 0 cf #467 * Update utils.py * Update README.md * add support for pre-commit-ci * add isort * modify autosummary templates * Rename `clv_summary` to `rfm_summary` and extend functionality (#479) * clv_summary adapted into rfm_summary * added clv_summary with warning * moved dataset from testing folder * Update version.txt * improve ruff * [pre-commit.ci] pre-commit autoupdate updates: - [github.com/astral-sh/ruff-pre-commit: v0.1.11 → v0.1.14](astral-sh/ruff-pre-commit@v0.1.11...v0.1.14) - [github.com/pre-commit/pre-commit-hooks: v3.2.0 → v4.5.0](pre-commit/pre-commit-hooks@v3.2.0...v4.5.0) * resolve conflict * Add baselined saturation (#498) * add baselined saturation with test and plots * refactor docs * add the reparam * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * verify parametrization is equivalent under change of baseline * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * add a note for setting x0 * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * make it clear how r_ref is calculated * fix typo * fix docstrings * improve test by making sure transform is gives identical saturation and cac0 * add comment in the docstring * add blank line in the code-block --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> * Swap Before and After convolution modes as per #489 (#501) * Add support for string mode args * Swap before and after and make mode explicit * Use Union due Python 3.9 * Style * resolve conflict * add dim_name arg * add seed to tests and test methods * add slice as type hint * use slice in docstring * defaults to mean for each channel * add non-negative check * ax as last arg * change weeks -> time * parameterize quantiles * separate out and add to docs * rerun the baseline images * mock the prior * add new images from latest env * migrate to toml instead of ci/cd * test only is axes * remove the images --------- Co-authored-by: Juan Orduz <juan.orduz@wolt.com> Co-authored-by: Abdalaziz Rashid <abdalaziz.rashid@outlook.com> Co-authored-by: Ricardo Vieira <ricardo.vieira1994@gmail.com> Co-authored-by: Ricardo Vieira <28983449+ricardoV94@users.noreply.github.com> Co-authored-by: vincent-grosbois <vincent.grosbois@gmail.com> Co-authored-by: juanitorduz <juanitorduz@gmail.com> Co-authored-by: Oriol (ProDesk) <oriol.abril.pla@gmail.com> Co-authored-by: Colt Allen <10178857+ColtAllen@users.noreply.github.com> Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: Maxim Kochurov <max.kochurov@pymc-labs.com>
* current status as method * format * Update version.txt * Implement different convolution modes (#454) * Add PR template * Update pull_request_template.md * Fix issues in index example * Update .pre-commit-config.yaml * Update .pre-commit-config.yaml * move from other PR * put legend on side * Optimisation in customer_lifetime_value when discount_rate == 0 (#468) * Optimisation in customer_lifetime_value when discount_rate == 0 cf #467 * Update utils.py * Update README.md * add support for pre-commit-ci * add isort * modify autosummary templates * Rename `clv_summary` to `rfm_summary` and extend functionality (#479) * clv_summary adapted into rfm_summary * added clv_summary with warning * moved dataset from testing folder * Update version.txt * improve ruff * [pre-commit.ci] pre-commit autoupdate updates: - [github.com/astral-sh/ruff-pre-commit: v0.1.11 → v0.1.14](astral-sh/ruff-pre-commit@v0.1.11...v0.1.14) - [github.com/pre-commit/pre-commit-hooks: v3.2.0 → v4.5.0](pre-commit/pre-commit-hooks@v3.2.0...v4.5.0) * resolve conflict * Add baselined saturation (#498) * add baselined saturation with test and plots * refactor docs * add the reparam * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * verify parametrization is equivalent under change of baseline * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * add a note for setting x0 * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * make it clear how r_ref is calculated * fix typo * fix docstrings * improve test by making sure transform is gives identical saturation and cac0 * add comment in the docstring * add blank line in the code-block --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> * Swap Before and After convolution modes as per #489 (#501) * Add support for string mode args * Swap before and after and make mode explicit * Use Union due Python 3.9 * Style * resolve conflict * add dim_name arg * add seed to tests and test methods * add slice as type hint * use slice in docstring * defaults to mean for each channel * add non-negative check * ax as last arg * change weeks -> time * parameterize quantiles * separate out and add to docs * rerun the baseline images * mock the prior * add new images from latest env * migrate to toml instead of ci/cd * test only is axes * remove the images --------- Co-authored-by: Juan Orduz <juan.orduz@wolt.com> Co-authored-by: Abdalaziz Rashid <abdalaziz.rashid@outlook.com> Co-authored-by: Ricardo Vieira <ricardo.vieira1994@gmail.com> Co-authored-by: Ricardo Vieira <28983449+ricardoV94@users.noreply.github.com> Co-authored-by: vincent-grosbois <vincent.grosbois@gmail.com> Co-authored-by: juanitorduz <juanitorduz@gmail.com> Co-authored-by: Oriol (ProDesk) <oriol.abril.pla@gmail.com> Co-authored-by: Colt Allen <10178857+ColtAllen@users.noreply.github.com> Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: Maxim Kochurov <max.kochurov@pymc-labs.com>
Baselined Tanh Saturation.
An alternative parameterization of the reach function is given by:
where:
by the user (not given a prior) where they expect most of their data to lie (median recommended).
For example, if you're spending between 50 and 150 dollars on a particular channel,
you might choose
You have to set a prior on what you think the CAC is when you spend
Imagine you have four advertising channels, and you acquired 1000 new users.
If each channel performed equally well, and advertising drove all sales, you might expect
that you gained 250 users from each channel. Here, your "gain" would be
the deminishing returns are not visible yet.
and additional dollar spend will not lead to any new users.
you get in the reference point by increasing the budget.
Key benefits
Origins
The original reach or saturation function used in an MMM is formulated as
where:
of new users obtained when an infinite number of dollars are spent on that channel.
users we might expect after spending our first dollar.
Description
The PR adds novel parameterization that is easier to use for industry applications where domain knowledge is an essence
Code example
Related Issue
Checklist
Modules affected
Type of change
📚 Documentation preview 📚: https://pymc-marketing--498.org.readthedocs.build/en/498/