Marketing Mix Models (MMM) are powerful tools for understanding the impact of various marketing channels on business outcomes. In this guide, we’ll walk through the process of creating a Marketing Mix Model using LightweightMMM, a Python library developed by Google. This guide assumes you have a basic understanding of marketing analytics and Python.
Step 1: Installation and Importing Libraries
To get started, install the LightweightMMM library:
Next, import the necessary libraries:
!pip install --upgrade git+https://github.com/google/lightweight_mmm.git
import jax.numpy as jnp
from lightweight_mmm import lightweight_mmm, optimize_media, plot, preprocessing, utils
Step 2: Organizing Data for Modeling
Generate or import your data for modeling. In this example, we simulate dummy data:
SEED = 105
data_size = 104 + 13
n_media_channels = 3
n_extra_features = 1
media_data, extra_features, target, costs = utils.simulate_dummy_data(
data_size=data_size,
n_media_channels=n_media_channels,
n_extra_features=n_extra_features)
Split the dataset into training and testing sets:
split_point = data_size - 13
media_data_train = media_data[:split_point, ...]
media_data_test = media_data[split_point:, ...]
extra_features_train = extra_features[:split_point, ...]
extra_features_test = extra_features[split_point:, ...]
target_train = target[:split_point]
Step 3: Scaling the Data
Scaling is crucial for modeling. Use the CustomScaler
class provided by LightweightMMM:
media_scaler = preprocessing.CustomScaler(divide_operation=jnp.mean)
extra_features_scaler = preprocessing.CustomScaler(divide_operation=jnp.mean)
target_scaler = preprocessing.CustomScaler(divide_operation=jnp.mean)
cost_scaler = preprocessing.CustomScaler(divide_operation=jnp.mean, multiply_by=0.15)
media_data_train = media_scaler.fit_transform(media_data_train)
extra_features_train = extra_features_scaler.fit_transform(extra_features_train)
target_train = target_scaler.fit_transform(target_train)
costs = cost_scaler.fit_transform(costs)
Step 4: Training the Model
Choose a model type (e.g., “carryover”) and train the model:
mmm = lightweight_mmm.LightweightMMM(model_name="carryover")
number_warmup = 1000
number_samples = 1000
mmm.fit(
media=media_data_train,
media_prior=costs,
target=target_train,
extra_features=extra_features_train,
number_warmup=number_warmup,
number_samples=number_samples,
seed=SEED
)
Print a summary of the trace:
mmm.print_summary()
Visualize posterior distributions of media effects:
plot.plot_media_channel_posteriors(media_mix_model=mmm)
![Christos Visvardis image-1 Creating a Marketing Mix Model with LightweightMMM: A Step-by-Step Guide](https://i0.wp.com/visvardis.com/wp-content/uploads/2023/11/image-1.png?resize=490%2C890&ssl=1)
Step 5: Model Evaluation and Prediction
Check the model’s fit to the training data:
plot.plot_model_fit(mmm, target_scaler=target_scaler)
![Christos Visvardis image-2 Creating a Marketing Mix Model with LightweightMMM: A Step-by-Step Guide](https://i0.wp.com/visvardis.com/wp-content/uploads/2023/11/image-2.png?resize=543%2C435&ssl=1)
Make predictions on unseen data:
new_predictions = mmm.predict(
media=media_scaler.transform(media_data_test),
extra_features=extra_features_scaler.transform(extra_features_test),
seed=SEED
)
plot.plot_out_of_sample_model_fit(out_of_sample_predictions=new_predictions,
out_of_sample_target=target_scaler.transform(target[split_point:]))
![Christos Visvardis image-3 Creating a Marketing Mix Model with LightweightMMM: A Step-by-Step Guide](https://i0.wp.com/visvardis.com/wp-content/uploads/2023/11/image-3.png?resize=556%2C433&ssl=1)
Step 6: Media Insights
Extract media contribution and ROI estimates:
media_contribution, roi_hat = mmm.get_posterior_metrics(target_scaler=target_scaler, cost_scaler=cost_scaler)
Visualize media contributions over time:
plot.plot_media_baseline_contribution_area_plot(media_mix_model=mmm, target_scaler=target_scaler, fig_size=(30,10))
![Christos Visvardis image-4-1024x370 Creating a Marketing Mix Model with LightweightMMM: A Step-by-Step Guide](https://i0.wp.com/visvardis.com/wp-content/uploads/2023/11/image-4.png?resize=1024%2C370&ssl=1)
Visualize media contributions with credibility intervals:
plot.plot_bars_media_metrics(metric=media_contribution, metric_name="Media Contribution Percentage")
plot.plot_bars_media_metrics(metric=roi_hat, metric_name="ROI hat")
![Christos Visvardis image-5 Creating a Marketing Mix Model with LightweightMMM: A Step-by-Step Guide](https://i0.wp.com/visvardis.com/wp-content/uploads/2023/11/image-5.png?resize=565%2C463&ssl=1)
Step 7: Optimization
Optimize budget allocation based on the model:
n_time_periods = 10
budget = jnp.sum(jnp.dot(prices, media_data.mean(axis=0))) * n_time_periods
solution, kpi_without_optim, previous_media_allocation = optimize_media.find_optimal_budgets(
n_time_periods=n_time_periods,
media_mix_model=mmm,
extra_features=extra_features_scaler.transform(extra_features_test)[:n_time_periods],
budget=budget,
prices=prices,
media_scaler=media_scaler,
target_scaler=target_scaler,
seed=SEED
)
Check budget constraint and visualize results:
plot.plot_pre_post_budget_allocation_comparison(
media_mix_model=mmm,
kpi_with_optim=solution['fun'],
kpi_without_optim=kpi_without_optim,
optimal_buget_allocation=optimal_buget_allocation,
previous_budget_allocation=previous_budget_allocation,
figure_size=(10,10)
)
![Christos Visvardis image-6 Creating a Marketing Mix Model with LightweightMMM: A Step-by-Step Guide](https://i0.wp.com/visvardis.com/wp-content/uploads/2023/11/image-6.png?resize=989%2C989&ssl=1)
Step 8: Saving and Loading the Model
Save the trained model to disk:
file_path = "media_mix_model.pkl"
utils.save_model(media_mix_model=mmm, file_path=file_path)
Load the saved model:
loaded_mmm = utils.load_model(file_path=file_path)
loaded_mmm.trace["coef_media"].shape # Example of accessing any of the model values.
Congratulations! You’ve successfully created a Marketing Mix Model using LightweightMMM. Feel free to customize and iterate on this framework based on your specific business needs.