-
Looking at the example notebook - https://www.pymc-marketing.io/en/stable/notebooks/mmm/mmm_example.html#model-diagnostics In In some cases, I can see an option to revert results back to "original_scale". However, I believe that the provided
|
Beta Was this translation helpful? Give feedback.
Replies: 4 comments 3 replies
-
Attempting to solve my own question. Since there was a "LogNormal" transformation applied to betas, the code below is meant to convert beta coefficients back to their original scale. # "az.summary" provided by pymc, then converted to dataframe
summary_table = pd.DataFrame(az.summary(
data=mmm.fit_result,
var_names=[
"intercept",
"likelihood_sigma",
"beta_channel",
"alpha", # Carryover
"lam", # Saturation
"gamma_control",
"gamma_fourier",
],)).reset_index()
# Only updating betas
beta_channel_rows = summary_table[summary_table['index'].str.startswith('beta_channel')]
# Inverse of "LogNormal" transformation applied to betas, also accounting for "prior_sigma" defined earlier
def back_transform_dataframe(df, mu_column_name, sd_column_name):
def original_scale_params(row):
mu_estimate = row[mu_column_name]
sigma = row[sd_column_name]
original_mean = np.exp(mu_estimate + sigma**2 / 2)
original_var = (np.exp(sigma**2) - 1) * np.exp(2 * mu_estimate + sigma**2)
original_sd = np.sqrt(original_var)
return pd.Series([original_mean, original_sd], index=['original_mean', 'original_sd'])
# Creates 2 new columns (1) original mean and (2) original standard deviation
df[['mean_original_units', 'sd_original_units']] = df.apply(original_scale_params, axis=1)
return df
back_transform_dataframe(df = beta_channel_rows, mu_column_name = 'mean', sd_column_name = 'sd') |
Beta Was this translation helpful? Give feedback.
-
Hi @smusch2 The use of LogNormal prior shouldn't impact the transformation that is being used back to original units as the prior just reflects the likely values of the parameters. The transformations are described here. In summary:
The As for the Hope this gives some context. Let me know if you have any other follow ups |
Beta Was this translation helpful? Give feedback.
-
@wd60622 - Still using the example provided by pymc, can you confirm that this is correct? Values
Equation to undo "MinMax" scaling
Translation: All else equal, a marginal $1 spend in |
Beta Was this translation helpful? Give feedback.
-
Hi @wd60622 - I think I figured it out, but it'd be great if you could confirm. mmm = DelayedSaturatedMMM(
model_config = my_model_config,
sampler_config = my_sampler_config,
date_column="date_week",
channel_columns=["x1", "x2"],
control_columns=[
"event_1",
"event_2",
"t",
],
adstock_max_lag=8,
yearly_seasonality=2,
)
with pm.Model() as model:
mmm.fit(X=X, y=y, target_accept=0.95, chains=4, random_seed=rng)
idata_1 = pm.sample(
target_accept=0.95,
draws=2000,
chains=4,
nuts_sampler="numpyro",
random_seed=rng
)
# Inverse of MinMax
beta_channel = np.array([idata_1["posterior"]["beta_channel"].values]) # Beta in scaled form
target_scale = np.array([data['y'].max()]) # Max value of target variable
channel_scale = np.array([data[["x1", "x2"]].max(axis=0)]) # Max values of media variables
beta_original = beta_channel * (target_scale / channel_scale) |
Beta Was this translation helpful? Give feedback.
Hi @wd60622 - I think I figured it out, but it'd be great if you could confirm.