Skip to content

Commit

Permalink
Merge branch 'main' into time-varying-prior
Browse files Browse the repository at this point in the history
  • Loading branch information
wd60622 authored Mar 19, 2024
2 parents 3ce5ac4 + 06b111e commit dac69da
Show file tree
Hide file tree
Showing 45 changed files with 5,350 additions and 3,373 deletions.
25 changes: 22 additions & 3 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ on:
branches: [main]

env:
OLDEST_PYMC_VERSION: "5.8.2"
OLDEST_PYMC_VERSION: "5.10.4"

jobs:
test:
Expand Down Expand Up @@ -38,12 +38,31 @@ jobs:
name: ${{ matrix.config.python-version }}
fail_ci_if_error: false

test_slow:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Set up Python
uses: actions/setup-python@v3
with:
python-version: "3.10"
- name: Run tests
run: |
pip install -e .[test]
pytest --only-slow --cov-report=xml --no-cov-on-fail --durations=50
- name: Upload coverage to Codecov
uses: codecov/codecov-action@v3
with:
token: ${{ secrets.CODECOV_TOKEN }} # use token for more robust uploads
name: "test_slow"
fail_ci_if_error: false

all:
if: ${{ always() }}
runs-on: ubuntu-latest
name: All checks
needs: [ test ]
needs: [ test, test_slow ]
steps:
- name: Confirm checks passed
if: ${{ needs.test.result != 'success' }}
if: ${{ (needs.test.result != 'success' || needs.test_slow.result != 'success') }}
run: exit 1
11 changes: 9 additions & 2 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,25 @@ ci:

repos:
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.2.2
rev: v0.3.2
hooks:
- id: ruff
args: ["--fix", "--show-source"]
- id: ruff-format
- repo: https://github.com/pre-commit/mirrors-mypy
rev: v1.8.0
rev: v1.9.0
hooks:
- id: mypy
args: [--ignore-missing-imports]
files: ^pymc_marketing/
additional_dependencies: [numpy>=1.20, pandas-stubs]
- repo: https://github.com/nbQA-dev/nbQA
rev: 1.8.4
hooks:
- id: nbqa-ruff
args: ["--fix", "--show-source"]
files: ^docs/source/notebooks/
exclude: ^docs/source/notebooks/clv/dev/
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.5.0
hooks:
Expand Down
8 changes: 4 additions & 4 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,16 +46,16 @@ For more instructions see the [Pull request checklist](#pull-request-checklist)

Always use a feature branch. It's good practice to never routinely work on the `main` branch of any repository.
1. Create an environment. For example:
1. Create a dedicated development environment from the file present in the repo:
```bash
conda create -n pymc_marketing_env
conda env create -f environment.yml
```
Activate the environment.
This will create an environment called `pymc-marketing-dev`. Activate the environment.
```bash
conda activate pymc_marketing_env
conda activate pymc-marketing-dev
```
Install the package (in editable mode) and its development dependencies:
Expand Down
5 changes: 2 additions & 3 deletions docs/source/guide/benefits/model_deployment.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -218,7 +218,7 @@
"source": [
"We first illustrate the use of `model_config` to define custom priors within the model.\n",
"\n",
"Because there are potentially many variables that can be configured, each model provides a `default_model_config` attribute. This will allow you to see which settings are available by default and easily update only the ones you care about by merging dictionary keys.\n",
"Because there are potentially many variables that can be configured, each model provides a `default_model_config` attribute. This will allow you to see which settings are available by default and only define the ones you need to change.\n",
"\n",
"We need to create a dummy model to be able to see the configuration dictionary."
]
Expand Down Expand Up @@ -305,8 +305,7 @@
"metadata": {},
"outputs": [],
"source": [
"custom_beta_channel_prior = {'beta_channel': {'sigma': prior_sigma, 'dims': ('channel',)}}\n",
"my_model_config = dummy_model.default_model_config | custom_beta_channel_prior"
"my_model_config = {'beta_channel': {'sigma': prior_sigma, 'dims': ('channel',)}}"
]
},
{
Expand Down
2 changes: 1 addition & 1 deletion docs/source/guide/clv/clv_intro.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,4 +32,4 @@ By combining the purchasing behavior of each customer with the expected period o

## Putting it all together

To see how all these different components come together, you can review the {ref}`CLV Quickstart <clv_quickstart>` or one of {ref}`specific CLV models <clv_examples>` available within PyMC-Marketing.
To see how all these different components come together, you can review the {ref}`CLV Quickstart <clv_quickstart>` or one of {ref}`specific CLV models <howto>` available within PyMC-Marketing.
8 changes: 6 additions & 2 deletions docs/source/guide/mmm/comparison.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,9 @@ Given the popularity of the Media Mix Modelling (MMM) approach, there are many p
| Company | PyMC Labs | Google | Meta | Uber | Recast |
| Open source||||||
| Model | 🏗️ Build | 🏗️ Build | 🏗️ Build | 🏗️ Build | 🛒 Buy |
| Budget optimizer | coming soon |||||
| Time-varying parameters | coming soon |||| ? |
| Budget optimizer ||||||
| Time-varying parameters | coming soon |||||
| Custom priors ||||||
| Lift-test calibration | coming soon |||||
| Out of sample predictions ||||||
| Unit-tested ||||| ? |
8 changes: 6 additions & 2 deletions docs/source/guide/mmm/resources.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,18 +37,22 @@ To add more substance to our session and ensure it's not just informative but al

[![Youtube video thumbnail image](https://img.youtube.com/vi/ikCK76gq65Q/maxresdefault.jpg)](https://youtu.be/ikCK76gq65Q?si=fitQK_GrQcoSNWJq)

## Business Cases

* PyMC Labs: [Bayesian Media Mix Models: Modelling changes in marketing effectiveness over time](https://www.pymc-labs.com/blog-posts/modelling-changes-marketing-effectiveness-over-time/)
* Bolt: [Better budgeting with Bayesian models: Bolt’s story with PyMC-Marketing](https://bolt.eu/en/blog/budgeting-with-bayesian-models-pymc-marketing/)
* Shell & DataBricks: [Revolutionizing Tech Marketing: The Synergy of PyMC and Databricks](https://www.databricks.com/blog/revolutionizing-tech-marketing)

## Blogposts

* PyMC Labs: [Improving the Speed and Accuracy of Bayesian Media Mix Models](https://www.pymc-labs.io/blog-posts/reducing-customer-acquisition-costs-how-we-helped-optimizing-hellofreshs-marketing-budget/)
* PyMC Labs: [Bayesian Media Mix Models: Modelling changes in marketing effectiveness over time](https://www.pymc-labs.io/blog-posts/modelling-changes-marketing-effectiveness-over-time/)
* 1749: [Measuring Marketing Effectiveness Over the Long-Term](https://1749.io/resource-center/f/measuring-marketing-effectiveness-over-the-long-term)
* 1749: [Marketing Mix Modeling in a Modern Era: Time-Varying Parameters](https://1749.io/resource-center/f/marketing-mix-modeling-in-a-modern-era-time-varying-parameters)
* 1749: [A Comprehensive Guide to Marketing-Mix Modeling](https://1749.io/resource-center/f/a-comprehensive-guide-to-bayesian-marketing-mix-modeling)
* Juan Orduz: [Media Effect Estimation with Orbit's KTR Model](https://juanitorduz.github.io/orbit_mmm/)
* Juan Orduz: [Media Effect Estimation with PyMC: Adstock, Saturation & Diminishing Returns](https://juanitorduz.github.io/pymc_mmm/)
* Juan Orduz: [Media Mix Model and Experimental Calibration: A Simulation Study](https://juanitorduz.github.io/mmm_roas/)
* Dr. Robert Kübler: [Convenient Bayesian Marketing Mix Modeling with PyMC Marketing](https://towardsdatascience.com/convenient-bayesian-marketing-mix-modeling-with-pymc-marketing-8b02a9a9c4aa)
* Carlos Eduardo Trujillo Agostini: [Better budgeting with Bayesian models: Bolt’s story with PyMC-Marketing](https://bolt.eu/en/blog/budgeting-with-bayesian-models-pymc-marketing/)

### Tutorials

Expand Down
3 changes: 3 additions & 0 deletions docs/source/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,9 @@ conda create -c conda-forge -n marketing_env pymc-marketing
conda activate marketing_env
```

### Installation for developers
If you are a developer of pymc-marketing, or want to start contributing, [refer to the contributing guide](https://github.com/pymc-labs/pymc-marketing/blob/main/CONTRIBUTING.md) to get started.

See the official [PyMC installation guide](https://www.pymc.io/projects/docs/en/latest/installation.html) if more detail is needed.

## Quickstart
Expand Down
12 changes: 5 additions & 7 deletions docs/source/notebooks/clv/bg_nbd.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,9 @@
"metadata": {},
"outputs": [],
"source": [
"import arviz as az\n",
"import numpy as np\n",
"import pandas as pd\n",
"import matplotlib.pyplot as plt\n",
"import numpy as np"
"from lifetimes import BetaGeoFitter"
]
},
{
Expand All @@ -40,7 +39,7 @@
"metadata": {},
"outputs": [],
"source": [
"from pymc_marketing import clv"
"from lifetimes.datasets import load_cdnow_summary"
]
},
{
Expand All @@ -50,8 +49,7 @@
"metadata": {},
"outputs": [],
"source": [
"from lifetimes.datasets import load_cdnow_summary\n",
"from lifetimes import BetaGeoFitter"
"from pymc_marketing import clv"
]
},
{
Expand Down Expand Up @@ -159,7 +157,7 @@
" 'frequency': df[\"frequency\"].values,\n",
" 'recency': df[\"recency\"].values,\n",
" 'T': df['T'].values,\n",
"})\n"
"})"
]
},
{
Expand Down
19 changes: 9 additions & 10 deletions docs/source/notebooks/clv/clv_quickstart.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,6 @@
"import matplotlib.pyplot as plt\n",
"import numpy as np\n",
"import pandas as pd\n",
"import pymc as pm\n",
"from arviz.labels import MapLabeller\n",
"\n",
"from pymc_marketing import clv"
Expand Down Expand Up @@ -327,9 +326,9 @@
],
"source": [
"rfm_data = clv.utils.rfm_summary(\n",
" raw_transactions, \n",
" customer_id_col = \"id\", \n",
" datetime_col = \"date\", \n",
" raw_trans,\n",
" customer_id_col = \"id\",\n",
" datetime_col = \"date\",\n",
" monetary_value_col = \"spent\",\n",
" datetime_format = \"%Y%m%d\",\n",
" time_unit = \"W\")\n",
Expand Down Expand Up @@ -830,9 +829,9 @@
"source": [
"num_purchases = bgm.expected_num_purchases(\n",
" customer_id=rfm_data[\"customer_id\"],\n",
" t=1, \n",
" frequency=rfm_data[\"frequency\"], \n",
" recency=rfm_data[\"recency\"], \n",
" t=1,\n",
" frequency=rfm_data[\"frequency\"],\n",
" recency=rfm_data[\"recency\"],\n",
" T=rfm_data[\"T\"]\n",
")"
]
Expand Down Expand Up @@ -970,7 +969,7 @@
],
"source": [
"ids = [841, 1981, 157, 1516]\n",
"ax = az.plot_posterior(num_purchases.sel(customer_id=ids), grid=(2, 2));\n",
"ax = az.plot_posterior(num_purchases.sel(customer_id=ids), grid=(2, 2))\n",
"for axi, id in zip(ax.ravel(), ids):\n",
" axi.set_title(f\"Customer: {id}\", size=20)\n",
"plt.suptitle(\"Expected number purchases in the next period\", fontsize=28, y=1.05);"
Expand Down Expand Up @@ -1011,7 +1010,7 @@
"source": [
"az.plot_posterior(\n",
" bgm.expected_num_purchases_new_customer(t=10)\n",
");\n",
")\n",
"plt.title(\"Expected purchases of a new customer in the first 10 periods\");"
]
},
Expand Down Expand Up @@ -1193,7 +1192,7 @@
" frequency=np.full(10, customer_1516[\"frequency\"], dtype=\"int\"),\n",
" recency=np.full(10, customer_1516[\"recency\"]),\n",
" T=(np.arange(0, 10) + customer_1516[\"recency\"]).astype(\"int\"),\n",
" \n",
"\n",
"))\n",
"customer_1516_history"
]
Expand Down
Loading

0 comments on commit dac69da

Please sign in to comment.