Replies: 7 comments 7 replies
-
Damn, that's very cool! I can also see how time-varying parameters could easily fit into this framework. |
Beta Was this translation helpful? Give feedback.
-
I really like this modular, OOP proposal! Could go a long way towards making the MMM model more flexible & customizable. |
Beta Was this translation helpful? Give feedback.
-
@thipokKub Seems like feedback to your proposal is quite positive, want to do a PR? |
Beta Was this translation helpful? Give feedback.
-
Do anyone know if this is moving forward? Seems like an excellent idea. Or if there is some other plans to make it a bit easier to customize than today. |
Beta Was this translation helpful? Give feedback.
-
I'd be really interested in seeing this! and would be willing to help out here I think that this should fit into the current classes but might be a good start to break down the workload. For instance, refactoring and extracting the different contributions def get_fourier_contributions(X_fourier: np.ndarray, gamma_fourier: Dict[str, Any]) -> pt.TensorVariable:
"""Seasonal contribution. Must be defined within a model"""
fourier_data_ = pm.MutableData(
name="fourier_data",
value=X_fourier,
dims=("date", "fourier_mode"),
)
gamma_fourier = pm.Laplace(
name="gamma_fourier",
mu=gamma_fourier["mu"],
b=gamma_fourier["b"],
dims=gamma_fourier["dims"],
)
fourier_contribution = pm.Deterministic(
name="fourier_contributions",
var=fourier_data_ * gamma_fourier,
dims=("date", "fourier_mode"),
)
def get_channel_contributions(
X_channels: np.ndarray, adstock_max_lag, beta_channel_config, alpha_config, lam_config
) -> pt.TensorVariable:
"""Also extracted out as well."""
...
# Hopefully making the model definition block
coords = {"date": ..., "fourier_mode": ..., "channel": ...}
with pm.Model(coords=coords) as custom_mmm:
periods: npt.NDArray[np.float_] = date_data.dt.dayofyear.to_numpy() / 365.25
X_fourier = generate_fourier_modes(
periods=periods,
n_order=yearly_seasonality,
)
seasonal_contribution = get_fourier_contribution(X_fourier, gamma_fourier=...)
channel_contribution = get_channel_contribution(X_channel, ...)
mu = seasonal_contribution.sum(axis=1) + channel_contribution.sum(axis=1)
# Freedom to change the likelihood, more transformations, customization
geographical_hierarchical_intercept = ... But rely on these in the current class in order keep an easy API for out of the box |
Beta Was this translation helpful? Give feedback.
-
Hi, on a high level, it is beneficial to use ideas from https://arxiv.org/abs/2208.07132 to compose the building blocks that maintain a good prior predictive for the organic component. Organic consists of Seasonal terms, Regression, Trend, and HSGP or HSTP to model outliers and trend violations. In my particular scenario, this is still WIP, but for this simpler case I imagine the model should take form of
Where organic has multiplicative effect, marketing has additive effect, but the total likelihood is on the log scale. The more complicated model is what I'm working on right now (the causal graph can be found in the very bottom of this blogpost). Unfortunately, no manual specification is possible anymore, so the clear separation of the components was essential. This simple model only has
But the larger model also has more than this and includes transitive effects, e.g., "invest into brand awareness, attract more leads to the lower funnel". It would look like this:
or
Given the discoveries, I believe pymc-mareting can focus on the simple case with only the lowest funnel observations (sales) and the model is the basic one
The only issue is with the geo effect. One difficulty I found, it felt to me that restricting all geos to have the same number of observations might be too demanding. What do you think of it? So far I'm more towars to model geos separately:
However, some direct investments into channels might cover all geos, so there are basically two types of marketing effects: "geo specific" and "world". Global effect marketing spend should still somehow have geo specific effects, but the functional form is different.
|
Beta Was this translation helpful? Give feedback.
-
Related to #274 |
Beta Was this translation helpful? Give feedback.
-
Hello, I really like this repo. It helped me a lot in a past few months. Currently all the MMM model development seems to focus on BaseDelayedSaturatedMMM class. Because MMM model is a GLM model, it can be decomposed into multiple components such as trend, seasonality, media, and control variables
However, the current model class fixed the method for trend to always be linear, media, and control variables must always have the same prior and such. This is somewhat limiting. I proposed the idea of implementing MMM as a component based model such that it can be customize more easily
The idea stem from #274
For example this is my proof of concept idea
Setup Code
Utils code
Trend Components
Seasonality Components
Construct model
It is now a lot easier to swap trend, and seasonality component. For uniformity, each specific component type should have the same output rv name such as trend component must have
self._trend
, and seasonality component must haveself._seasonality
. However this probably going to affect MMM diagnosis graph ploting in a major way. So I think it this require some discussion such as a standard interface, or data structureBeta Was this translation helpful? Give feedback.
All reactions