Depuis le 7 mars 2024, Google a publié une nouvelle version officielle du MMM bayésien appelée Meridian . Meridian est actuellement en disponibilité limitée pour certains annonceurs. Veuillez visiter ce site ou contacter votre représentant Google pour plus d'informations. La version LMMM cessera une fois que Meridian aura atteint la disponibilité générale.
Documents • Introduction • Théorie • Mise en route • Références • Pleins feux sur la communauté
La modélisation du mix marketing (MMM) est utilisée par les annonceurs pour mesurer l'efficacité de la publicité et éclairer les décisions d'allocation budgétaire sur tous les canaux médiatiques. Les mesures basées sur des données agrégées permettent une comparaison entre les canaux en ligne et hors ligne et ne sont pas affectées par les récents changements de l'écosystème (certains liés à la confidentialité) qui peuvent affecter la modélisation d'attribution. MMM vous permet de :
Adopter une approche bayésienne du MMM permet à un annonceur d'intégrer des informations préalables dans la modélisation, ce qui vous permet de :
Le package LightweightMMM (construit à l'aide de Numpyro et JAX) aide les annonceurs à créer facilement des modèles bayésiens MMM en fournissant la fonctionnalité permettant de mettre à l'échelle les données de manière appropriée, d'évaluer les modèles, d'optimiser les allocations budgétaires et de tracer les graphiques courants utilisés sur le terrain.
Un MMM quantifie la relation entre l'activité des canaux médiatiques et les ventes, tout en contrôlant d'autres facteurs. Un aperçu simplifié du modèle est présenté ci-dessous et le modèle complet est présenté dans la documentation du modèle. Un MMM est généralement exécuté à l'aide d'observations hebdomadaires (par exemple, le KPI peut être les ventes hebdomadaires), mais il peut également être exécuté au niveau quotidien.
Où KPI est généralement le volume ou la valeur des ventes par période,
Le LightweightMMM peut être exécuté soit en utilisant des données agrégées au niveau national (approche standard), soit en utilisant des données agrégées au niveau géographique (approche hiérarchique infranationale).
Niveau national (approche standard). Cette approche est appropriée si les données disponibles sont uniquement agrégées au niveau national (par exemple, le KPI pourrait être les ventes nationales par période). Il s'agit du format le plus couramment utilisé dans les MMM.
Niveau géographique (approche hiérarchique sous-nationale). Cette approche est appropriée si les données peuvent être agrégées à un niveau sous-national (par exemple, le KPI pourrait être les ventes par période pour chaque État d'un pays). Cette approche peut donner des résultats plus précis par rapport à l'approche standard, car elle utilise plus de points de données pour ajuster le modèle. Nous recommandons d'utiliser si possible un modèle au niveau sous-national pour les grands pays tels que les États-Unis.
Il est probable que l’effet d’un canal médiatique sur les ventes puisse avoir un effet décalé qui s’atténuera lentement avec le temps. Notre puissante architecture de modèle bayésien MMM est conçue pour capturer cet effet et propose trois approches différentes. Nous recommandons aux utilisateurs de comparer les trois approches et d'utiliser l'approche qui fonctionne le mieux. L’approche qui fonctionne le mieux sera généralement celle qui présente le meilleur ajustement hors échantillon (qui est l’un des résultats générés). Les formes fonctionnelles de ces trois approches sont brièvement décrites ci-dessous et sont pleinement exprimées dans notre documentation modèle.
La méthode recommandée pour installer Lightweight_mmm consiste à utiliser PyPi :
pip install --upgrade pip
pip install lightweight_mmm
Si vous souhaitez utiliser la version la plus récente et légèrement moins stable, vous pouvez l'installer depuis github :
pip install --upgrade git+https://github.com/google/lightweight_mmm.git
Si vous utilisez Google Colab, assurez-vous de redémarrer le runtime après l'installation.
Ici, nous utilisons des données simulées, mais nous supposons que vos données ont été nettoyées à ce stade. Les données nécessaires seront :
# Let's assume we have the following datasets with the following shapes (we use
the `simulate_dummy_data` function in utils for this example ):
media_data , extra_features , target , costs = utils . simulate_dummy_data (
data_size = 160 ,
n_media_channels = 3 ,
n_extra_features = 2 ,
geos = 5 ) # Or geos=1 for national model
La mise à l'échelle est un peu un art, les techniques bayésiennes fonctionnent bien si les données d'entrée sont à petite échelle. Nous ne devons pas centrer les variables sur 0. Les ventes et les médias doivent avoir une limite inférieure de 0.
y
peut être mis à l'échelle comme y / jnp.mean(y)
.media
peuvent être mis à l'échelle comme X_m / jnp.mean(X_m, axis=0)
, ce qui signifie que la nouvelle moyenne de la colonne sera de 1. Nous fournissons un CustomScaler
qui peut appliquer des multiplications et des divisions au cas où les scalers les plus utilisés ne correspondraient pas à votre cas d'utilisation. Mettez à l'échelle vos données en conséquence avant d'ajuster le modèle. Ci-dessous un exemple d'utilisation de ce CustomScaler
:
# Simple split of the data based on time.
split_point = data_size - data_size // 10
media_data_train = media_data [: split_point , :]
target_train = target [: split_point ]
extra_features_train = extra_features [: split_point , :]
extra_features_test = extra_features [ split_point :, :]
# Scale data
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 )
# scale cost up by N since fit() will divide it by number of time periods
cost_scaler = preprocessing . CustomScaler ( divide_operation = jnp . mean )
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 ( unscaled_costs )
Si vous avez une variable qui contient beaucoup de 0, vous pouvez également la mettre à l'échelle au moyen de valeurs non nulles. Par exemple, vous pouvez utiliser une fonction lambda pour faire ceci : lambda x: jnp.mean(x[x > 0])
. Il en va de même pour l’échelle des coûts.
Le modèle nécessite les données multimédias, les fonctionnalités supplémentaires, les coûts de chaque unité multimédia par canal et la cible. Vous pouvez également indiquer le nombre d'échantillons que vous souhaitez utiliser ainsi que le nombre de chaînes.
Pour exécuter plusieurs chaînes en parallèle, l'utilisateur devra définir numpyro.set_host_device_count
soit sur le nombre de chaînes, soit sur le nombre de processeurs disponibles.
Voir un exemple ci-dessous :
# Fit model.
mmm = lightweight_mmm . LightweightMMM ()
mmm . fit ( media = media_data ,
extra_features = extra_features ,
media_prior = costs ,
target = target ,
number_warmup = 1000 ,
number_samples = 1000 ,
number_chains = 2 )
Si vous souhaitez modifier un a priori dans le modèle (en plus du media prior que vous spécifiez déjà toujours), vous pouvez le faire avec custom_priors
:
# See detailed explanation on custom priors in our documentation.
custom_priors = { "intercept" : numpyro . distributions . Uniform ( 1 , 5 )}
# Fit model.
mmm = lightweight_mmm . LightweightMMM ()
mmm . fit ( media = media_data ,
extra_features = extra_features ,
media_prior = costs ,
target = target ,
number_warmup = 1000 ,
number_samples = 1000 ,
number_chains = 2 ,
custom_priors = custom_priors )
Veuillez vous référer à notre documentation sur custom_priors pour plus de détails.
Vous pouvez basculer entre les données quotidiennes et hebdomadaires en activant weekday_seasonality=True
et seasonality_frequency=365
ou weekday_seasonality=False
et seasonality_frequency=52
(par défaut). Dans le cas de données quotidiennes, nous avons deux types de saisonnalité : un jour de semaine discret et un annuel lisse.
Les utilisateurs peuvent vérifier les métriques de convergence des paramètres comme suit :
mmm . print_summary ()
La règle générale est que les valeurs r_hat
pour tous les paramètres sont inférieures à 1,1.
Les utilisateurs peuvent vérifier l’adéquation entre le vrai KPI et le KPI prédit en :
plot . plot_model_fit ( media_mix_model = mmm , target_scaler = target_scaler )
Si target_scaler
utilisé pour preprocessing.CustomScaler()
est donné, la cible ne sera pas mise à l'échelle. Le R-carré bayésien et le MAPE sont indiqués dans le graphique.
Les utilisateurs peuvent obtenir la prédiction des données de test en :
prediction = mmm . predict (
media = media_data_test ,
extra_features = extra_data_test ,
target_scaler = target_scaler
)
Les prédictions renvoyées sont des distributions ; si des estimations ponctuelles sont souhaitées, les utilisateurs peuvent les calculer en fonction de la distribution donnée. Par exemple, si data_size
des données de test est 20, number_samples
est 1 000 et number_of_chains
est 2, mmm.predict
renvoie 2 000 ensembles de prédictions avec 20 points de données. Les utilisateurs peuvent comparer les distributions avec la vraie valeur des données de test et calculer les mesures telles que la moyenne et la médiane.
Les utilisateurs peuvent obtenir des détails sur l'estimation des paramètres en :
mmm . print_summary ()
Ce qui précède renvoie la moyenne, l'écart type, la médiane et l'intervalle de crédibilité pour chaque paramètre. Les tableaux de répartition sont fournis par :
plot . plot_media_channel_posteriors ( media_mix_model = mmm , channel_names = media_names )
channel_names
spécifie les noms de médias dans chaque graphique.
Les courbes de réponse sont fournies comme suit :
plot . plot_response_curves ( media_mix_model = mmm , media_scaler = media_scaler , target_scaler = target_scaler )
Si media_scaler
et target_scaler
utilisés pour preprocessing.CustomScaler()
sont donnés, les valeurs du média et de la cible ne seront pas mises à l'échelle.
Pour extraire l'efficacité des médias et l'estimation du retour sur investissement, les utilisateurs peuvent effectuer les opérations suivantes :
media_effect_hat , roi_hat = mmm . get_posterior_metrics ()
media_effect_hat
est l'estimation de l'efficacité des médias et roi_hat
est l'estimation du retour sur investissement. Les utilisateurs peuvent alors visualiser la distribution de l’estimation comme suit :
plot . plot_bars_media_metrics ( metric = media_effect_hat , channel_names = media_names )
plot . plot_bars_media_metrics ( metric = roi_hat , channel_names = media_names )
Pour l'optimisation, nous maximiserons les ventes en modifiant les entrées multimédias de telle sorte que le coût total des médias soit constant. Nous pouvons également autoriser des limites raisonnables sur chaque entrée multimédia (par exemple +- x%). Nous optimisons uniquement sur tous les canaux et non au fil du temps. Pour exécuter l'optimisation, vous avez besoin des paramètres principaux suivants :
n_time_periods
: Le nombre de périodes de temps que vous souhaitez simuler (par exemple, optimiser pour les 10 prochaines semaines si vous avez entraîné un modèle sur des données hebdomadaires).budget
que vous souhaitez allouer pour les prochaines n_time_periods
.n_time_periods
suivantes.media_gap
fait référence à l'écart de données multimédias entre la fin des données d'entraînement et le début du média hors échantillon fourni. Par exemple. si 100 semaines de données ont été utilisées pour l'entraînement et que la prédiction commence 2 mois après la fin des données d'entraînement, nous devons fournir les 8 semaines manquantes entre les données d'entraînement et les données de prédiction afin que les transformations de données (adstock, report, ...) puissent s'effectuer correctement. .Voir ci-dessous et exemple d'optimisation :
# Run media optimization.
budget = 40 # your budget here
prices = np . array ([ 0.1 , 0.11 , 0.12 ])
extra_features_test = extra_features_scaler . transform ( extra_features_test )
solution = optimize_media . find_optimal_budgets (
n_time_periods = extra_features_test . shape [ 0 ],
media_mix_model = mmm ,
budget = budget ,
extra_features = extra_features_test ,
prices = prices )
Les utilisateurs peuvent enregistrer et charger le modèle comme suit :
utils . save_model ( mmm , file_path = 'file_path' )
Les utilisateurs peuvent spécifier file_path
pour enregistrer le modèle. Pour charger un modèle MMM enregistré :
utils . load_model ( file_path : 'file_path' )
Pour citer ce référentiel :
@software{lightweight_mmmgithub,
author = {Pablo Duque and Dirk Nachbar and Yuka Abe and Christiane Ahlheim and Mike Anderson and Yan Sun and Omri Goldstein and Tim Eck},
title = {LightweightMMM: Lightweight (Bayesian) Marketing Mix Modeling},
url = {https://github.com/google/lightweight_mmm},
version = {0.1.6},
year = {2022},
}
Jin, Y., Wang, Y., Sun, Y., Chan, D. et Koehler, J. (2017). Méthodes bayésiennes pour la modélisation du mix média avec effets de transfert et de forme. Google Inc.
Chan, D. et Perry, M. (2017). Défis et opportunités dans la modélisation du mix média.
Sun, Y., Wang, Y., Jin, Y., Chan, D. et Koehler, J. (2017). Modélisation du mix média hiérarchique bayésien au niveau géographique.
Comme LMMM n'est pas un produit Google officiel, l'équipe LMMM ne peut offrir qu'une assistance limitée.
Pour des questions sur la méthodologie , veuillez vous référer à la section Références ou à la page FAQ.
Pour les problèmes d'installation ou d'utilisation de LMMM , n'hésitez pas à les publier dans les onglets Discussions ou Problèmes du référentiel Github. L'équipe LMMM répond à ces questions pendant notre temps libre, nous ne pouvons donc malheureusement pas garantir une réponse dans les délais. Nous encourageons également la communauté à partager des astuces et des conseils ici !
Pour les demandes de fonctionnalités , veuillez les publier dans l'onglet Discussions du référentiel Github. Nous avons une feuille de route interne pour le développement de LMMM, mais prêtons attention aux demandes de fonctionnalités et les apprécions !
Pour les rapports de bogues , veuillez les publier dans l'onglet Problèmes du référentiel Github. Si/quand nous serons en mesure de les résoudre, nous vous le ferons savoir dans les commentaires sur votre problème.
Les demandes d'extraction sont appréciées mais sont très difficiles à fusionner pour nous car le code de ce référentiel est lié aux systèmes internes de Google et doit passer un examen interne. Si vous soumettez une pull request et que nous disposons de ressources pour vous aider à la fusionner, nous vous contacterons à ce sujet !
Comment créer un modèle de mix marketing avec LightweightMMM par Mario Filho.
Fonctionnement de Google LightweightMMM et présentation pas à pas de LightweightMMM de Google par Mike Taylor.