Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove ruff E501 ignore #619

Merged
merged 11 commits into from
Apr 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
169 changes: 79 additions & 90 deletions docs/source/notebooks/mmm/mmm_budget_allocation_example.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -34,21 +34,6 @@
"Before delving into the specifics of budget allocation, the initial step is to install the PyMC-Marketing library and ascertain its version. This step will confirm support for the budget allocation function. The following pip command can be run on your Jupyter Notebook:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "-LnDMZnXIh-x",
"outputId": "8d14a8c8-d5c7-4894-8333-eb437b69cd17"
},
"outputs": [],
"source": [
"!pip install pymc-marketing"
]
},
{
"cell_type": "markdown",
"metadata": {
Expand Down Expand Up @@ -119,7 +104,7 @@
},
"outputs": [],
"source": [
"name = '/pymc-marketing/data/budget_optimizer_model.nc'\n",
"name = \"/pymc-marketing/data/budget_optimizer_model.nc\"\n",
"mmm = DelayedSaturatedMMM.load(name)"
]
},
Expand Down Expand Up @@ -308,7 +293,7 @@
],
"source": [
"sigmoid_response_curve_fig = mmm.plot_direct_contribution_curves(\n",
"show_fit = True, method='michaelis-menten'\n",
" show_fit=True, method=\"michaelis-menten\"\n",
")"
]
},
Expand Down Expand Up @@ -337,9 +322,13 @@
},
"outputs": [],
"source": [
"sigmoid_params = mmm.compute_channel_curve_optimization_parameters_original_scale(method='sigmoid')\n",
"sigmoid_params = mmm.compute_channel_curve_optimization_parameters_original_scale(\n",
" method=\"sigmoid\"\n",
")\n",
"\n",
"menten_params = mmm.compute_channel_curve_optimization_parameters_original_scale(method='michaelis-menten')"
"menten_params = mmm.compute_channel_curve_optimization_parameters_original_scale(\n",
" method=\"michaelis-menten\"\n",
")"
]
},
{
Expand Down Expand Up @@ -431,15 +420,15 @@
},
"outputs": [],
"source": [
"total_budget = 5 #Imagine is 5K or 5M\n",
"#Define your channels\n",
"channels = ['x1','x2']\n",
"#The initial split per channel\n",
"total_budget = 5 # Imagine is 5K or 5M\n",
"# Define your channels\n",
"channels = [\"x1\", \"x2\"]\n",
"# The initial split per channel\n",
"budget_per_channel = total_budget / len(channels)\n",
"#Initial budget per channel as dictionary.\n",
"# Initial budget per channel as dictionary.\n",
"initial_budget_dict = {channel: budget_per_channel for channel in channels}\n",
"#bounds for each channel\n",
"min_budget, max_budget = 1,5\n",
"# bounds for each channel\n",
"min_budget, max_budget = 1, 5\n",
"budget_bounds = {channel: [min_budget, max_budget] for channel in channels}"
]
},
Expand Down Expand Up @@ -733,10 +722,10 @@
],
"source": [
"result_sigmoid = mmm.optimize_channel_budget_for_maximum_contribution(\n",
" method = 'sigmoid', #define saturation function\n",
" total_budget = total_budget,\n",
" parameters = sigmoid_params,\n",
" budget_bounds = budget_bounds\n",
" method=\"sigmoid\", # define saturation function\n",
" total_budget=total_budget,\n",
" parameters=sigmoid_params,\n",
" budget_bounds=budget_bounds,\n",
")\n",
"\n",
"result_sigmoid"
Expand Down Expand Up @@ -1032,10 +1021,10 @@
],
"source": [
"result_menten = mmm.optimize_channel_budget_for_maximum_contribution(\n",
" method = 'michaelis-menten',\n",
" total_budget = total_budget,\n",
" parameters = menten_params,\n",
" budget_bounds = budget_bounds\n",
" method=\"michaelis-menten\",\n",
" total_budget=total_budget,\n",
" parameters=menten_params,\n",
" budget_bounds=budget_bounds,\n",
")\n",
"result_menten"
]
Expand All @@ -1059,18 +1048,16 @@
},
"outputs": [],
"source": [
"#Use the function `calculate_expected_contribution` to estimate\n",
"#the contribution of your initial budget based on the curve parameters.\n",
"# Use the function `calculate_expected_contribution` to estimate\n",
"# the contribution of your initial budget based on the curve parameters.\n",
"initial_contribution = calculate_expected_contribution(\n",
" method='sigmoid',\n",
" parameters = sigmoid_params,\n",
" budget = initial_budget_dict\n",
" method=\"sigmoid\", parameters=sigmoid_params, budget=initial_budget_dict\n",
")\n",
"\n",
"# Initial budget & contribution dictionary\n",
"initial_scenario = {\n",
" 'initial_contribution': initial_contribution,\n",
" 'initial_budget': initial_budget_dict\n",
" \"initial_contribution\": initial_contribution,\n",
" \"initial_budget\": initial_budget_dict,\n",
"}"
]
},
Expand Down Expand Up @@ -1114,9 +1101,11 @@
}
],
"source": [
"#Use the function `compare_budget_scenearios` to validate\n",
"#The estimated contribution from one scenario agains the other\n",
"figure_ = mmm.plot_budget_scenearios(base_data=initial_scenario, method='sigmoid', scenarios_data=[result_sigmoid])"
"# Use the function `compare_budget_scenearios` to validate\n",
"# The estimated contribution from one scenario agains the other\n",
"figure_ = mmm.plot_budget_scenearios(\n",
" base_data=initial_scenario, method=\"sigmoid\", scenarios_data=[result_sigmoid]\n",
")"
]
},
{
Expand Down Expand Up @@ -1158,30 +1147,37 @@
},
"outputs": [],
"source": [
"#Initialize two variables to save the results and base conditions for each scenario.\n",
"# Initialize two variables to save the results and base conditions for each scenario.\n",
"scenarios_result = []\n",
"scenarios_base = []\n",
"\n",
"for scenario in np.array([0.6, 0.8, 1.2, 1.8]):\n",
" scenarios_result.append(\n",
" mmm.optimize_channel_budget_for_maximum_contribution(\n",
" method = 'sigmoid', #define saturation function\n",
" total_budget = total_budget * scenario,\n",
" parameters = sigmoid_params,\n",
" budget_bounds = {channel: [1, total_budget * scenario] for channel in channels}\n",
" ).to_dict()\n",
" )\n",
"\n",
" scenarios_base.append(\n",
" {'initial_contribution': calculate_expected_contribution(\n",
" method='sigmoid', #define saturation function\n",
" parameters = sigmoid_params,\n",
" budget = {channel: total_budget * scenario / len(channels) for channel in channels}\n",
" ),\n",
"\n",
" 'initial_budget': {channel: total_budget * scenario / len(channels) for channel in channels}\n",
" }\n",
" )"
" scenarios_result.append(\n",
" mmm.optimize_channel_budget_for_maximum_contribution(\n",
" method=\"sigmoid\", # define saturation function\n",
" total_budget=total_budget * scenario,\n",
" parameters=sigmoid_params,\n",
" budget_bounds={\n",
" channel: [1, total_budget * scenario] for channel in channels\n",
" },\n",
" ).to_dict()\n",
" )\n",
"\n",
" scenarios_base.append(\n",
" {\n",
" \"initial_contribution\": calculate_expected_contribution(\n",
" method=\"sigmoid\", # define saturation function\n",
" parameters=sigmoid_params,\n",
" budget={\n",
" channel: total_budget * scenario / len(channels)\n",
" for channel in channels\n",
" },\n",
" ),\n",
" \"initial_budget\": {\n",
" channel: total_budget * scenario / len(channels) for channel in channels\n",
" },\n",
" }\n",
" )"
]
},
{
Expand Down Expand Up @@ -1222,9 +1218,11 @@
}
],
"source": [
"#Use the function `compare_budget_scenearios` to validate\n",
"#The estimated contribution from one scenario agains the other\n",
"_figure = mmm.plot_budget_scenearios(base_data=initial_scenario, method='sigmoid', scenarios_data=scenarios_result)"
"# Use the function `compare_budget_scenearios` to validate\n",
"# The estimated contribution from one scenario agains the other\n",
"_figure = mmm.plot_budget_scenearios(\n",
" base_data=initial_scenario, method=\"sigmoid\", scenarios_data=scenarios_result\n",
")"
]
},
{
Expand Down Expand Up @@ -1526,12 +1524,10 @@
],
"source": [
"platform_base_optimization = mmm.optimize_channel_budget_for_maximum_contribution(\n",
" method = 'sigmoid',\n",
" total_budget = total_budget,\n",
" parameters = sigmoid_params,\n",
" budget_bounds = {'x1':[0,1.5],\n",
" 'x2':[0,1.5]\n",
" }\n",
" method=\"sigmoid\",\n",
" total_budget=total_budget,\n",
" parameters=sigmoid_params,\n",
" budget_bounds={\"x1\": [0, 1.5], \"x2\": [0, 1.5]},\n",
")\n",
"\n",
"platform_base_optimization"
Expand Down Expand Up @@ -1580,7 +1576,7 @@
],
"source": [
"sigmoid_response_curve_fig = mmm.plot_direct_contribution_curves(\n",
"show_fit = True, method='sigmoid', xlim_max=3\n",
" show_fit=True, method=\"sigmoid\", xlim_max=3\n",
")"
]
},
Expand Down Expand Up @@ -1874,12 +1870,10 @@
],
"source": [
"platform_base_optimization = mmm.optimize_channel_budget_for_maximum_contribution(\n",
" method = 'sigmoid',\n",
" total_budget = total_budget,\n",
" parameters = sigmoid_params,\n",
" budget_bounds = {'x1':[0,1.2],\n",
" 'x2':[0,1.5]\n",
" }\n",
" method=\"sigmoid\",\n",
" total_budget=total_budget,\n",
" parameters=sigmoid_params,\n",
" budget_bounds={\"x1\": [0, 1.2], \"x2\": [0, 1.5]},\n",
")\n",
"\n",
"platform_base_optimization"
Expand Down Expand Up @@ -1923,7 +1917,11 @@
}
],
"source": [
"_figure = mmm.plot_budget_scenearios(base_data=initial_scenario, method='sigmoid', scenarios_data=[platform_base_optimization])"
"_figure = mmm.plot_budget_scenearios(\n",
" base_data=initial_scenario,\n",
" method=\"sigmoid\",\n",
" scenarios_data=[platform_base_optimization],\n",
")"
]
},
{
Expand Down Expand Up @@ -1952,15 +1950,6 @@
"\n",
"Consequently, your engagements, feedback, and thoughts are not merely welcomed but actively solicited to make this tool as practical and universally applicable as possible."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "Hy7ueyLb4F4Q"
},
"outputs": [],
"source": []
}
],
"metadata": {
Expand Down
6 changes: 4 additions & 2 deletions pymc_marketing/clv/distributions.py
Original file line number Diff line number Diff line change
Expand Up @@ -350,7 +350,9 @@ class ParetoNBD(PositiveContinuous):
Population-level distribution class for a continuous, non-contractual, Pareto/NBD process,
based on Schmittlein, et al. in [2]_.

The likelihood function is derived from equations (22) and (23) of [3]_, with terms rearranged for numerical stability.
The likelihood function is derived from equations (22) and (23) of [3]_, with terms
rearranged for numerical stability.

The modified expression is provided below:

.. math::
Expand Down Expand Up @@ -389,7 +391,7 @@ class ParetoNBD(PositiveContinuous):
.. [3] Fader, Peter & G. S. Hardie, Bruce (2005).
"A Note on Deriving the Pareto/NBD Model and Related Expressions."
http://brucehardie.com/notes/009/pareto_nbd_derivations_2005-11-05.pdf
"""
""" # noqa: E501

rv_op = pareto_nbd

Expand Down
6 changes: 4 additions & 2 deletions pymc_marketing/clv/models/beta_geo.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,12 @@ class BetaGeoModel(CLVModel):
DataFrame containing the following columns:
* `frequency`: number of repeat purchases (with possible values 0, 1, 2, ...)
* `recency`: time between the first and the last purchase (with possible values 0, 1, 2, ...)
* `T`: time between the first purchase and the end of the observation period (with possible values 0, 1, 2, ...)
* `T`: time between the first purchase and the end of the observation
period (with possible values 0, 1, 2, ...)
* `customer_id`: unique customer identifier
model_config: dict, optional
Dictionary of model prior parameters. If not provided, the model will use default priors specified in the `default_model_config` class attribute.
Dictionary of model prior parameters. If not provided, the model will use default priors specified in
the `default_model_config` class attribute.
sampler_config: dict, optional
Dictionary of sampler parameters. Defaults to None.

Expand Down
10 changes: 6 additions & 4 deletions pymc_marketing/clv/models/gamma_gamma.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,8 @@ def expected_customer_spend(

Eq 5 from [1], p.3

Adapted from: https://github.com/CamDavidsonPilon/lifetimes/blob/aae339c5437ec31717309ba0ec394427e19753c4/lifetimes/fitters/gamma_gamma_fitter.py#L117 # noqa: E501
"""
Adapted from: https://github.com/CamDavidsonPilon/lifetimes/blob/aae339c5437ec31717309ba0ec394427e19753c4/lifetimes/fitters/gamma_gamma_fitter.py#L117
""" # noqa: E501

mean_transaction_value, frequency = to_xarray(
customer_id, mean_transaction_value, frequency
Expand Down Expand Up @@ -162,7 +162,8 @@ class GammaGammaModel(BaseGammaGammaModel):
- mean_transaction_value: Mean transaction value of each customer.
- frequency: Number of transactions observed for each customer.
model_config: dict, optional
Dictionary of model prior parameters. If not provided, the model will use default priors specified in the `default_model_config` class attribute.
Dictionary of model prior parameters. If not provided, the model will use default priors specified in the
`default_model_config` class attribute.
sampler_config: dict, optional
Dictionary of sampler parameters. Defaults to None.

Expand Down Expand Up @@ -295,7 +296,8 @@ class GammaGammaModelIndividual(BaseGammaGammaModel):
coming from the same customer.
- individual_transaction_value: Value of individual transactions.
model_config: dict, optional
Dictionary of model prior parameters. If not provided, the model will use default priors specified in the `default_model_config` class attribute.
Dictionary of model prior parameters. If not provided, the model will use default priors specified in the
`default_model_config` class attribute.
sampler_config: dict, optional
Dictionary of sampler parameters. Defaults to None.

Expand Down
Loading
Loading