Optimization (opt.py)¶
This module provides functions for optimizing marketing budget allocation across different channels based on estimated contribution curves (response curves). It supports both Michaelis-Menten and Sigmoid saturation functions.
Functions¶
calculate_expected_contribution¶
def calculate_expected_contribution(
method: str,
parameters: Dict[str, Tuple[float, float]],
budget: Dict[str, float],
) -> Dict[str, float]:
Calculates the expected contribution for each channel given a specific budget allocation and a chosen response curve model (method).
Parameters:
method(str): The response curve model to use. Must be either"michaelis-menten"or"sigmoid".parameters(Dict[str, Tuple[float, float]]): Dictionary containing the parameters for the chosenmethodfor each channel.For
"michaelis-menten":{channel: (L, k)}whereLis max contribution andkis the half-saturation point.For
"sigmoid":{channel: (alpha, lam)}wherealphacontrols slope andlamis the transition point. (Usesabacus.core.utils.sigmoid_saturation).
budget(Dict[str, float]): Dictionary mapping each channel name to its allocated budget.
Returns:
Dict[str, float]: A dictionary mapping each channel name to its calculated contribution, plus a"total"key with the sum of contributions across all channels.
Raises:
ValueError: Ifmethodis not"michaelis-menten"or"sigmoid".
objective_distribution¶
def objective_distribution(
x: List[float],
method: str,
channels: List[str],
parameters: Dict[str, Tuple[float, float]],
) -> float:
Calculates the negative total expected contribution for a given budget distribution x. This function serves as the objective function to be minimized by the optimization algorithm (minimizing the negative contribution maximizes the actual contribution).
Parameters:
x(List[float]): A list representing the proposed budget for each channel, in the same order aschannels.method(str): The response curve model ("michaelis-menten"or"sigmoid").channels(List[str]): List of channel names corresponding to the budgets inx.parameters(Dict[str, Tuple[float, float]]): Dictionary of response curve parameters for each channel (same format ascalculate_expected_contribution).
Returns:
float: The negative of the total expected contribution for the budget distributionx.
Raises:
ValueError: Ifmethodis not"michaelis-menten"or"sigmoid".
optimize_budget_distribution¶
def optimize_budget_distribution(
method: str,
total_budget: Union[int, float],
budget_ranges: Optional[Dict[str, Tuple[float, float]]],
parameters: Dict[str, Tuple[float, float]],
channels: List[str],
) -> Dict[str, float]:
Finds the optimal budget allocation across the specified channels that maximizes the total expected contribution, given a total_budget and optional budget_ranges for each channel. Uses the SLSQP (Sequential Least Squares Quadratic Programming) optimization algorithm via scipy.optimize.minimize.
Constraints:
The sum of allocated budgets must equal
total_budget.The budget for each channel must be within the bounds specified in
budget_ranges(or between 0 andLfor Michaelis-Menten /total_budgetifbudget_rangesisNone).
Parameters:
method(str): The response curve model ("michaelis-menten"or"sigmoid").total_budget(Union[int, float]): The total amount of budget to distribute.budget_ranges(Optional[Dict[str, Tuple[float, float]]]): Optional dictionary specifying the(min_budget, max_budget)tuple for each channel. IfNone, defaults are applied (0 to L or total_budget).parameters(Dict[str, Tuple[float, float]]): Dictionary of response curve parameters for each channel.channels(List[str]): List of channel names to include in the optimization.
Returns:
Dict[str, float]: A dictionary mapping each channel name to its optimal budget allocation.
Raises:
TypeError: Ifbudget_rangesis provided but is not a dictionary.
budget_allocator¶
def budget_allocator(
method: str,
total_budget: Union[int, float],
channels: List[str],
parameters: Dict[str, Tuple[float, float]],
budget_ranges: Optional[Dict[str, Tuple[float, float]]],
) -> pd.DataFrame:
A convenient wrapper function that performs budget optimization and calculates the expected contribution for the optimal allocation.
Calls
optimize_budget_distributionto find the optimal budget split.Calls
calculate_expected_contributionusing the optimal budget.Returns the results in a pandas DataFrame.
Parameters:
method(str): The response curve model ("michaelis-menten"or"sigmoid").total_budget(Union[int, float]): The total budget to allocate.channels(List[str]): List of channel names.parameters(Dict[str, Tuple[float, float]]): Dictionary of response curve parameters.budget_ranges(Optional[Dict[str, Tuple[float, float]]]): Optional dictionary specifying budget bounds for each channel.
Returns:
pd.DataFrame: A DataFrame with channels (plus “total”) as the index and columns “estimated_contribution” and “optimal_budget”.