{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "(mmm_build_from_yml_example)=\n", "# Learning how to create models with yml files\n", "\n", "The following notebook will teach you to create pymc-marketing models from yml files, allowing you to easily recreate your models in production environments without several lines of code.\n", "\n", "## Setup" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "OMP: Info #276: omp_set_nested routine deprecated, please use omp_set_max_active_levels instead.\n", "/Users/carlostrujillo/Documents/GitHub/pymc-marketing/pymc_marketing/mmm/multidimensional.py:216: FutureWarning: This functionality is experimental and subject to change. If you encounter any issues or have suggestions, please raise them at: https://github.com/pymc-labs/pymc-marketing/issues/new\n", " warnings.warn(warning_msg, FutureWarning, stacklevel=1)\n", "/var/folders/f0/rbz8xs8s17n3k3f_ccp31bvh0000gn/T/ipykernel_49626/1583561548.py:7: UserWarning: The pymc_marketing.mmm.builders module is experimental and its API may change without warning.\n", " from pymc_marketing.mmm.builders.yaml import build_mmm_from_yaml\n" ] } ], "source": [ "import warnings\n", "\n", "import arviz as az\n", "import matplotlib.pyplot as plt\n", "import pandas as pd\n", "\n", "from pymc_marketing.mmm.builders.yaml import build_mmm_from_yaml\n", "from pymc_marketing.paths import data_dir\n", "\n", "warnings.filterwarnings(\"ignore\")\n", "\n", "az.style.use(\"arviz-darkgrid\")\n", "plt.rcParams[\"figure.figsize\"] = [12, 7]\n", "plt.rcParams[\"figure.dpi\"] = 100\n", "\n", "%load_ext autoreload\n", "%autoreload 2\n", "%config InlineBackend.figure_format = \"retina\"" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [], "source": [ "X = pd.read_csv(data_dir / \"processed\" / \"X.csv\")\n", "y = pd.read_csv(data_dir / \"processed\" / \"y.csv\")" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
datemarketchannel_1channel_2
02023-01-01US70.17149620.945956
12023-01-02US90.24391845.828916
22023-01-03US9.17871726.322735
\n", "
" ], "text/plain": [ " date market channel_1 channel_2\n", "0 2023-01-01 US 70.171496 20.945956\n", "1 2023-01-02 US 90.243918 45.828916\n", "2 2023-01-03 US 9.178717 26.322735" ] }, "execution_count": 3, "metadata": {}, "output_type": "execute_result" } ], "source": [ "X.head(3)" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
y
045.453806
142.516346
254.250939
\n", "
" ], "text/plain": [ " y\n", "0 45.453806\n", "1 42.516346\n", "2 54.250939" ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ "y.head(3)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Multidimensional model" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [], "source": [ "mmm = build_mmm_from_yaml(\n", " X=X, y=y, config_path=data_dir / \"config_files\" / \"multi_dimensional_model.yml\"\n", ")" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "data": { "image/svg+xml": [ "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "clusterchannel (2)\n", "\n", "channel (2)\n", "\n", "\n", "clusterdate (100) x market (2) x channel (2)\n", "\n", "date (100) x market (2) x channel (2)\n", "\n", "\n", "clusterdate (100) x market (2)\n", "\n", "date (100) x market (2)\n", "\n", "\n", "clustermarket (2)\n", "\n", "market (2)\n", "\n", "\n", "\n", "channel_scale\n", "\n", "channel_scale\n", "~\n", "Data\n", "\n", "\n", "\n", "channel_contribution\n", "\n", "channel_contribution\n", "~\n", "Deterministic\n", "\n", "\n", "\n", "channel_scale->channel_contribution\n", "\n", "\n", "\n", "\n", "\n", "target_scale\n", "\n", "target_scale\n", "~\n", "Data\n", "\n", "\n", "\n", "total_media_contribution_original_scale\n", "\n", "total_media_contribution_original_scale\n", "~\n", "Deterministic\n", "\n", "\n", "\n", "target_scale->total_media_contribution_original_scale\n", "\n", "\n", "\n", "\n", "\n", "saturation_lam\n", "\n", "saturation_lam\n", "~\n", "Halfnormal\n", "\n", "\n", "\n", "saturation_lam->channel_contribution\n", "\n", "\n", "\n", "\n", "\n", "adstock_alpha\n", "\n", "adstock_alpha\n", "~\n", "Beta\n", "\n", "\n", "\n", "adstock_alpha->channel_contribution\n", "\n", "\n", "\n", "\n", "\n", "saturation_alpha\n", "\n", "saturation_alpha\n", "~\n", "Gamma\n", "\n", "\n", "\n", "saturation_alpha->channel_contribution\n", "\n", "\n", "\n", "\n", "\n", "channel_data\n", "\n", "channel_data\n", "~\n", "Data\n", "\n", "\n", "\n", "channel_data->channel_contribution\n", "\n", "\n", "\n", "\n", "\n", "channel_contribution->total_media_contribution_original_scale\n", "\n", "\n", "\n", "\n", "\n", "y\n", "\n", "y\n", "~\n", "Normal\n", "\n", "\n", "\n", "channel_contribution->y\n", "\n", "\n", "\n", "\n", "\n", "target_data\n", "\n", "target_data\n", "~\n", "Data\n", "\n", "\n", "\n", "y->target_scale\n", "\n", "\n", "\n", "\n", "\n", "y->target_data\n", "\n", "\n", "\n", "\n", "\n", "intercept_contribution\n", "\n", "intercept_contribution\n", "~\n", "Normal\n", "\n", "\n", "\n", "intercept_contribution->y\n", "\n", "\n", "\n", "\n", "\n", "y_sigma\n", "\n", "y_sigma\n", "~\n", "Halfnormal\n", "\n", "\n", "\n", "y_sigma->y\n", "\n", "\n", "\n", "\n", "\n" ], "text/plain": [ "" ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "mmm.model.to_graphviz()" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "Sampling: [adstock_alpha, intercept_contribution, saturation_alpha, saturation_lam, y, y_sigma]\n" ] } ], "source": [ "prior_predictive = mmm.sample_prior_predictive(X=X, y=y, samples=1_000)" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "
<xarray.Dataset> Size: 2MB\n",
       "Dimensions:  (date: 100, market: 2, sample: 1000)\n",
       "Coordinates:\n",
       "  * date     (date) datetime64[ns] 800B 2023-01-01 2023-01-02 ... 2023-04-10\n",
       "  * market   (market) <U2 16B 'EU' 'US'\n",
       "  * sample   (sample) object 8kB MultiIndex\n",
       "  * chain    (sample) int64 8kB 0 0 0 0 0 0 0 0 0 0 0 ... 0 0 0 0 0 0 0 0 0 0 0\n",
       "  * draw     (sample) int64 8kB 0 1 2 3 4 5 6 7 ... 993 994 995 996 997 998 999\n",
       "Data variables:\n",
       "    y        (date, market, sample) float64 2MB -0.8231 0.1999 ... -1.278 0.6622\n",
       "Attributes:\n",
       "    created_at:                 2025-10-07T09:24:53.031443+00:00\n",
       "    arviz_version:              0.22.0\n",
       "    inference_library:          pymc\n",
       "    inference_library_version:  5.25.1\n",
       "    pymc_marketing_version:     0.16.0
" ], "text/plain": [ " Size: 2MB\n", "Dimensions: (date: 100, market: 2, sample: 1000)\n", "Coordinates:\n", " * date (date) datetime64[ns] 800B 2023-01-01 2023-01-02 ... 2023-04-10\n", " * market (market) \n" ], "text/plain": [] }, "metadata": {}, "output_type": "display_data" }, { "name": "stderr", "output_type": "stream", "text": [ "Sampling 8 chains for 1_000 tune and 200 draw iterations (8_000 + 1_600 draws total) took 14 seconds.\n", "There were 3 divergences after tuning. Increase `target_accept` or reparameterize.\n", "The rhat statistic is larger than 1.01 for some parameters. This indicates problems during sampling. See https://arxiv.org/abs/1903.08008 for details\n", "The effective sample size per chain is smaller than 100 for some parameters. A higher number is needed for reliable rhat and ess computation. See https://arxiv.org/abs/1903.08008 for details\n" ] }, { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "9d43b1ab5f0a4aa0b881bd7e89c2eb0e", "version_major": 2, "version_minor": 0 }, "text/plain": [ "Output()" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "
\n"
      ],
      "text/plain": []
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Sampling: [y]\n"
     ]
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "e92fe6fdf02443608929100a63b5c426",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "Output()"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/html": [
       "
\n"
      ],
      "text/plain": []
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/html": [
       "
\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "
<xarray.Dataset> Size: 3MB\n",
       "Dimensions:  (date: 100, market: 2, sample: 1600)\n",
       "Coordinates:\n",
       "  * date     (date) datetime64[ns] 800B 2023-01-01 2023-01-02 ... 2023-04-10\n",
       "  * market   (market) <U2 16B 'EU' 'US'\n",
       "  * sample   (sample) object 13kB MultiIndex\n",
       "  * chain    (sample) int64 13kB 0 0 0 0 0 0 0 0 0 0 0 ... 7 7 7 7 7 7 7 7 7 7 7\n",
       "  * draw     (sample) int64 13kB 0 1 2 3 4 5 6 7 ... 193 194 195 196 197 198 199\n",
       "Data variables:\n",
       "    y        (date, market, sample) float64 3MB 0.5852 0.5207 ... 0.595 0.5213\n",
       "Attributes:\n",
       "    created_at:                 2025-10-07T09:25:19.061570+00:00\n",
       "    arviz_version:              0.22.0\n",
       "    inference_library:          pymc\n",
       "    inference_library_version:  5.25.1
" ], "text/plain": [ " Size: 3MB\n", "Dimensions: (date: 100, market: 2, sample: 1600)\n", "Coordinates:\n", " * date (date) datetime64[ns] 800B 2023-01-01 2023-01-02 ... 2023-04-10\n", " * market (market) \n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "clusterchannel (2)\n", "\n", "channel (2)\n", "\n", "\n", "clusterdate (100) x channel (2)\n", "\n", "date (100) x channel (2)\n", "\n", "\n", "clusterdate (100)\n", "\n", "date (100)\n", "\n", "\n", "\n", "channel_scale\n", "\n", "channel_scale\n", "~\n", "Data\n", "\n", "\n", "\n", "channel_contribution\n", "\n", "channel_contribution\n", "~\n", "Deterministic\n", "\n", "\n", "\n", "channel_scale->channel_contribution\n", "\n", "\n", "\n", "\n", "\n", "target_scale\n", "\n", "target_scale\n", "~\n", "Data\n", "\n", "\n", "\n", "total_media_contribution_original_scale\n", "\n", "total_media_contribution_original_scale\n", "~\n", "Deterministic\n", "\n", "\n", "\n", "target_scale->total_media_contribution_original_scale\n", "\n", "\n", "\n", "\n", "\n", "y_sigma\n", "\n", "y_sigma\n", "~\n", "Halfnormal\n", "\n", "\n", "\n", "y\n", "\n", "y\n", "~\n", "Normal\n", "\n", "\n", "\n", "y_sigma->y\n", "\n", "\n", "\n", "\n", "\n", "saturation_lam\n", "\n", "saturation_lam\n", "~\n", "Halfnormal\n", "\n", "\n", "\n", "saturation_lam->channel_contribution\n", "\n", "\n", "\n", "\n", "\n", "intercept_contribution\n", "\n", "intercept_contribution\n", "~\n", "Normal\n", "\n", "\n", "\n", "intercept_contribution->y\n", "\n", "\n", "\n", "\n", "\n", "adstock_alpha\n", "\n", "adstock_alpha\n", "~\n", "Beta\n", "\n", "\n", "\n", "adstock_alpha->channel_contribution\n", "\n", "\n", "\n", "\n", "\n", "saturation_alpha\n", "\n", "saturation_alpha\n", "~\n", "Gamma\n", "\n", "\n", "\n", "saturation_alpha->channel_contribution\n", "\n", "\n", "\n", "\n", "\n", "channel_data\n", "\n", "channel_data\n", "~\n", "Data\n", "\n", "\n", "\n", "channel_data->channel_contribution\n", "\n", "\n", "\n", "\n", "\n", "channel_contribution->total_media_contribution_original_scale\n", "\n", "\n", "\n", "\n", "\n", "channel_contribution->y\n", "\n", "\n", "\n", "\n", "\n", "target_data\n", "\n", "target_data\n", "~\n", "Data\n", "\n", "\n", "\n", "y->target_scale\n", "\n", "\n", "\n", "\n", "\n", "y->target_data\n", "\n", "\n", "\n", "\n", "\n" ], "text/plain": [ "" ] }, "execution_count": 12, "metadata": {}, "output_type": "execute_result" } ], "source": [ "mmm2.model.to_graphviz()" ] }, { "cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "Sampling: [adstock_alpha, intercept_contribution, saturation_alpha, saturation_lam, y, y_sigma]\n" ] } ], "source": [ "prior_predictive = mmm2.sample_prior_predictive(X=X, y=y, samples=1_000)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Multidimensional Hierarchical Model" ] }, { "cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [], "source": [ "mmm3 = build_mmm_from_yaml(\n", " X=X,\n", " y=y,\n", " config_path=data_dir / \"config_files\" / \"multi_dimensional_hierarchical_model.yml\",\n", ")" ] }, { "cell_type": "code", "execution_count": 15, "metadata": {}, "outputs": [ { "data": { "image/svg+xml": [ "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "clusterchannel (2)\n", "\n", "channel (2)\n", "\n", "\n", "clustermarket (2)\n", "\n", "market (2)\n", "\n", "\n", "clusterdate (100) x market (2) x channel (2)\n", "\n", "date (100) x market (2) x channel (2)\n", "\n", "\n", "clusterdate (100) x market (2)\n", "\n", "date (100) x market (2)\n", "\n", "\n", "clustermarket (2) x channel (2)\n", "\n", "market (2) x channel (2)\n", "\n", "\n", "\n", "saturation_beta\n", "\n", "saturation_beta\n", "~\n", "Halfnormal\n", "\n", "\n", "\n", "channel_contribution\n", "\n", "channel_contribution\n", "~\n", "Deterministic\n", "\n", "\n", "\n", "saturation_beta->channel_contribution\n", "\n", "\n", "\n", "\n", "\n", "channel_scale\n", "\n", "channel_scale\n", "~\n", "Data\n", "\n", "\n", "\n", "channel_scale->channel_contribution\n", "\n", "\n", "\n", "\n", "\n", "intercept_contribution\n", "\n", "intercept_contribution\n", "~\n", "Halfcauchy\n", "\n", "\n", "\n", "y\n", "\n", "y\n", "~\n", "Truncated_normal\n", "\n", "\n", "\n", "intercept_contribution->y\n", "\n", "\n", "\n", "\n", "\n", "saturation_lam_alpha\n", "\n", "saturation_lam_alpha\n", "~\n", "Gamma\n", "\n", "\n", "\n", "saturation_lam\n", "\n", "saturation_lam\n", "~\n", "Gamma\n", "\n", "\n", "\n", "saturation_lam_alpha->saturation_lam\n", "\n", "\n", "\n", "\n", "\n", "target_scale\n", "\n", "target_scale\n", "~\n", "Data\n", "\n", "\n", "\n", "total_media_contribution_original_scale\n", "\n", "total_media_contribution_original_scale\n", "~\n", "Deterministic\n", "\n", "\n", "\n", "target_scale->total_media_contribution_original_scale\n", "\n", "\n", "\n", "\n", "\n", "y_sigma\n", "\n", "y_sigma\n", "~\n", "Halfnormal\n", "\n", "\n", "\n", "y_sigma->y\n", "\n", "\n", "\n", "\n", "\n", "channel_data\n", "\n", "channel_data\n", "~\n", "Data\n", "\n", "\n", "\n", "channel_data->channel_contribution\n", "\n", "\n", "\n", "\n", "\n", "channel_contribution->y\n", "\n", "\n", "\n", "\n", "\n", "channel_contribution->total_media_contribution_original_scale\n", "\n", "\n", "\n", "\n", "\n", "target_data\n", "\n", "target_data\n", "~\n", "Data\n", "\n", "\n", "\n", "y->target_scale\n", "\n", "\n", "\n", "\n", "\n", "y->target_data\n", "\n", "\n", "\n", "\n", "\n", "intercept_contribution_beta\n", "\n", "intercept_contribution_beta\n", "~\n", "Halfnormal\n", "\n", "\n", "\n", "intercept_contribution_beta->intercept_contribution\n", "\n", "\n", "\n", "\n", "\n", "adstock_alpha\n", "\n", "adstock_alpha\n", "~\n", "Beta\n", "\n", "\n", "\n", "adstock_alpha->channel_contribution\n", "\n", "\n", "\n", "\n", "\n", "saturation_lam->channel_contribution\n", "\n", "\n", "\n", "\n", "\n" ], "text/plain": [ "" ] }, "execution_count": 15, "metadata": {}, "output_type": "execute_result" } ], "source": [ "mmm3.model.to_graphviz()" ] }, { "cell_type": "code", "execution_count": 16, "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "Sampling: [adstock_alpha, intercept_contribution, intercept_contribution_beta, saturation_beta, saturation_lam, saturation_lam_alpha, y, y_sigma]\n" ] } ], "source": [ "prior_predictive = mmm3.sample_prior_predictive(X=X, y=y, samples=1_000)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Multidimensional Hierarchical with arbitrary effects and calibration" ] }, { "cell_type": "code", "execution_count": 19, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "PosixPath('/Users/carlostrujillo/Documents/GitHub/pymc-marketing/data/config_files/multi_dimensional_hierarchical_with_arbitrary_effects_model.yml')" ] }, "execution_count": 19, "metadata": {}, "output_type": "execute_result" } ], "source": [ "data_dir / \"config_files\" / \"multi_dimensional_hierarchical_with_arbitrary_effects_model.yml\"" ] }, { "cell_type": "code", "execution_count": 22, "metadata": {}, "outputs": [], "source": [ "mmm4 = build_mmm_from_yaml(\n", " X=X,\n", " y=y,\n", " config_path=data_dir\n", " / \"config_files\"\n", " / \"multi_dimensional_hierarchical_with_arbitrary_effects_model.yml\",\n", ")" ] }, { "cell_type": "code", "execution_count": 23, "metadata": {}, "outputs": [ { "data": { "image/svg+xml": [ "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "clusterchannel (2)\n", "\n", "channel (2)\n", "\n", "\n", "clustermarket (2)\n", "\n", "market (2)\n", "\n", "\n", "clusterdate (100) x market (2) x channel (2)\n", "\n", "date (100) x market (2) x channel (2)\n", "\n", "\n", "clusterdate (100) x market (2)\n", "\n", "date (100) x market (2)\n", "\n", "\n", "clusterdate (100)\n", "\n", "date (100)\n", "\n", "\n", "clustermarket (2) x channel (2)\n", "\n", "market (2) x channel (2)\n", "\n", "\n", "clustermarket (2) x changepoint (2)\n", "\n", "market (2) x changepoint (2)\n", "\n", "\n", "clusterweekly_fourier (6) x market (2)\n", "\n", "weekly_fourier (6) x market (2)\n", "\n", "\n", "clusterdate (100) x weekly_fourier (6) x market (2)\n", "\n", "date (100) x weekly_fourier (6) x market (2)\n", "\n", "\n", "cluster2\n", "\n", "2\n", "\n", "\n", "\n", "saturation_beta\n", "\n", "saturation_beta\n", "~\n", "Halfnormal\n", "\n", "\n", "\n", "channel_contribution\n", "\n", "channel_contribution\n", "~\n", "Deterministic\n", "\n", "\n", "\n", "saturation_beta->channel_contribution\n", "\n", "\n", "\n", "\n", "\n", "example_lift_tests\n", "\n", "example_lift_tests\n", "~\n", "Gamma\n", "\n", "\n", "\n", "saturation_beta->example_lift_tests\n", "\n", "\n", "\n", "\n", "\n", "channel_scale\n", "\n", "channel_scale\n", "~\n", "Data\n", "\n", "\n", "\n", "channel_scale->channel_contribution\n", "\n", "\n", "\n", "\n", "\n", "weekly_fourier_beta_mu\n", "\n", "weekly_fourier_beta_mu\n", "~\n", "Halfnormal\n", "\n", "\n", "\n", "weekly_fourier_beta\n", "\n", "weekly_fourier_beta\n", "~\n", "Laplace\n", "\n", "\n", "\n", "weekly_fourier_beta_mu->weekly_fourier_beta\n", "\n", "\n", "\n", "\n", "\n", "target_scale\n", "\n", "target_scale\n", "~\n", "Data\n", "\n", "\n", "\n", "channel_contribution_original_scale\n", "\n", "channel_contribution_original_scale\n", "~\n", "Deterministic\n", "\n", "\n", "\n", "target_scale->channel_contribution_original_scale\n", "\n", "\n", "\n", "\n", "\n", "total_media_contribution_original_scale\n", "\n", "total_media_contribution_original_scale\n", "~\n", "Deterministic\n", "\n", "\n", "\n", "target_scale->total_media_contribution_original_scale\n", "\n", "\n", "\n", "\n", "\n", "intercept_contribution\n", "\n", "intercept_contribution\n", "~\n", "Halfcauchy\n", "\n", "\n", "\n", "y\n", "\n", "y\n", "~\n", "Truncated_normal\n", "\n", "\n", "\n", "intercept_contribution->y\n", "\n", "\n", "\n", "\n", "\n", "saturation_lam_alpha\n", "\n", "saturation_lam_alpha\n", "~\n", "Gamma\n", "\n", "\n", "\n", "saturation_lam\n", "\n", "saturation_lam\n", "~\n", "Gamma\n", "\n", "\n", "\n", "saturation_lam_alpha->saturation_lam\n", "\n", "\n", "\n", "\n", "\n", "y_sigma\n", "\n", "y_sigma\n", "~\n", "Halfnormal\n", "\n", "\n", "\n", "y_sigma->y\n", "\n", "\n", "\n", "\n", "\n", "cost_per_target\n", "\n", "cost_per_target\n", "~\n", "Deterministic\n", "\n", "\n", "\n", "channel_contribution_original_scale->cost_per_target\n", "\n", "\n", "\n", "\n", "\n", "channel_data\n", "\n", "channel_data\n", "~\n", "Data\n", "\n", "\n", "\n", "channel_data->channel_contribution\n", "\n", "\n", "\n", "\n", "\n", "example_cpt\n", "\n", "example_cpt\n", "~\n", "Potential\n", "\n", "\n", "\n", "cost_per_target->example_cpt\n", "\n", "\n", "\n", "\n", "\n", "channel_contribution->channel_contribution_original_scale\n", "\n", "\n", "\n", "\n", "\n", "channel_contribution->y\n", "\n", "\n", "\n", "\n", "\n", "channel_contribution->total_media_contribution_original_scale\n", "\n", "\n", "\n", "\n", "\n", "channel_data_spend\n", "\n", "channel_data_spend\n", "~\n", "Data\n", "\n", "\n", "\n", "channel_data_spend->cost_per_target\n", "\n", "\n", "\n", "\n", "\n", "y->target_scale\n", "\n", "\n", "\n", "\n", "\n", "target_data\n", "\n", "target_data\n", "~\n", "Data\n", "\n", "\n", "\n", "y->target_data\n", "\n", "\n", "\n", "\n", "\n", "weekly_fourier_contribution\n", "\n", "weekly_fourier_contribution\n", "~\n", "Deterministic\n", "\n", "\n", "\n", "weekly_fourier_contribution->y\n", "\n", "\n", "\n", "\n", "\n", "trend_effect_contribution\n", "\n", "trend_effect_contribution\n", "~\n", "Deterministic\n", "\n", "\n", "\n", "trend_effect_contribution->y\n", "\n", "\n", "\n", "\n", "\n", "weekly_fourier_day\n", "\n", "weekly_fourier_day\n", "~\n", "Data\n", "\n", "\n", "\n", "weekly_fourier_components\n", "\n", "weekly_fourier_components\n", "~\n", "Deterministic\n", "\n", "\n", "\n", "weekly_fourier_day->weekly_fourier_components\n", "\n", "\n", "\n", "\n", "\n", "trend_t\n", "\n", "trend_t\n", "~\n", "Data\n", "\n", "\n", "\n", "trend_t->trend_effect_contribution\n", "\n", "\n", "\n", "\n", "\n", "intercept_contribution_beta\n", "\n", "intercept_contribution_beta\n", "~\n", "Halfnormal\n", "\n", "\n", "\n", "intercept_contribution_beta->intercept_contribution\n", "\n", "\n", "\n", "\n", "\n", "adstock_alpha\n", "\n", "adstock_alpha\n", "~\n", "Beta\n", "\n", "\n", "\n", "adstock_alpha->channel_contribution\n", "\n", "\n", "\n", "\n", "\n", "delta_mu\n", "\n", "delta_mu\n", "~\n", "Halfnormal\n", "\n", "\n", "\n", "delta\n", "\n", "delta\n", "~\n", "Normal\n", "\n", "\n", "\n", "delta_mu->delta\n", "\n", "\n", "\n", "\n", "\n", "saturation_lam->channel_contribution\n", "\n", "\n", "\n", "\n", "\n", "saturation_lam->example_lift_tests\n", "\n", "\n", "\n", "\n", "\n", "delta->trend_effect_contribution\n", "\n", "\n", "\n", "\n", "\n", "weekly_fourier_beta->weekly_fourier_components\n", "\n", "\n", "\n", "\n", "\n", "weekly_fourier_components->weekly_fourier_contribution\n", "\n", "\n", "\n", "\n", "\n" ], "text/plain": [ "" ] }, "execution_count": 23, "metadata": {}, "output_type": "execute_result" } ], "source": [ "mmm4.model.to_graphviz()" ] }, { "cell_type": "code", "execution_count": 24, "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "Sampling: [adstock_alpha, delta, delta_mu, example_lift_tests, intercept_contribution, intercept_contribution_beta, saturation_beta, saturation_lam, saturation_lam_alpha, weekly_fourier_beta, weekly_fourier_beta_mu, y, y_sigma]\n" ] } ], "source": [ "prior_predictive = mmm4.sample_prior_predictive(X=X, y=y, samples=1_000)" ] }, { "cell_type": "code", "execution_count": 25, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Last updated: Tue Oct 07 2025\n", "\n", "Python implementation: CPython\n", "Python version : 3.12.11\n", "IPython version : 9.4.0\n", "\n", "pymc_marketing: 0.16.0\n", "pytensor : 2.31.7\n", "\n", "pymc_marketing: 0.16.0\n", "matplotlib : 3.10.3\n", "arviz : 0.22.0\n", "pandas : 2.3.1\n", "\n", "Watermark: 2.5.0\n", "\n" ] } ], "source": [ "%load_ext watermark\n", "%watermark -n -u -v -iv -w -p pymc_marketing,pytensor" ] } ], "metadata": { "kernelspec": { "display_name": "pymc-marketing-dev", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.12.11" } }, "nbformat": 4, "nbformat_minor": 2 }