lightweight_mmm icon indicating copy to clipboard operation
lightweight_mmm copied to clipboard

Budget given is smaller than the lower bounds

Open vidushibadhwar96 opened this issue 2 years ago • 3 comments
trafficstars

Hi has anyone faced the below error when trying to run optimize_media.find_optimal_budgets--Budget given is smaller than the lower bounds of the constraints for optimization. This will lead to faulty optimization. Please either increase the budget or change the lower bound by increasing the percentage decrease with the bounds_lower_pct parameter.

vidushibadhwar96 avatar Aug 18 '23 14:08 vidushibadhwar96

When you are running budget optimization, budget is the total for the n_time_periods of your desired time period. If your average weekly spend is 10k and you want to optimize for a quarter(12 weeks) , then the budget would be 120k. The bounds_lower_pct and bounds_upper_pct are levers for you to set some constraints on individual media variables, the default is 0.2/20% I guess. If you look at the code in optimize_media.py the bounds are set from average media values from the training data.

You will get the above error you have mentioned, if the sum of all lower bounds for the media variables is greater than the budget specified. It is just that the optimizer finds that even if all the media variables are set to lowest possible spend, it exceeds the total budget and fails the budget constraint. What you can do is either allow the optimizer to reduce spend on some media variables (by decreasing the bounds_lower_pct) or increasing the budget.

Going by same example above, if the budget is 120k and all media channel spend are set to given bounds_lower_pct say comes to 150k, you will have the error above as the optimizer couldn't meet budget constraint. You can decrease the bounds_lower_pct to allow optimizer to meet the 120k budget or increase the total budget from 120k to 150k.

ar-asur avatar Aug 23 '23 17:08 ar-asur

Thank you for the response.The code only works when I reduce the lower bound by 1/100%. Is that normal?

vidushibadhwar96 avatar Aug 25 '23 18:08 vidushibadhwar96

When you set 1/100% for lower bound, it means that you are allowing spend to go to 0. Check the lower/upper bound for individual channels to get more information. Are you setting prices to 1 and using impressions?

So, typically the bound range should be 0.5/50% for lower and 1-2/100% for upper.

Following is the code from _get_lower_and_upper_bounds function in optimize_midea.py file.

if media.ndim == 3:
        lower_pct = jnp.expand_dims(lower_pct, axis=-1)
        upper_pct = jnp.expand_dims(upper_pct, axis=-1)

    mean_data = media.mean(axis=0)
    mean_data = MEDIA_MEAN
    lower_bounds = jnp.maximum(mean_data * (1 - lower_pct), 0)
    upper_bounds = mean_data * (1 + upper_pct)

    if media_scaler:
        lower_bounds = media_scaler.inverse_transform(lower_bounds)
        upper_bounds = media_scaler.inverse_transform(upper_bounds)

    if media.ndim == 3:
        lower_bounds = lower_bounds.sum(axis=-1)
        upper_bounds = upper_bounds.sum(axis=-1)

    return optimize.Bounds(lb=lower_bounds * n_time_periods,
                                                 ub=upper_bounds * n_time_periods)

The function just takes the mean for all media channel values, multiplies the percentage set using lower and upper argument. Using that as the avg value multiplies that by n_time_periods to get the bounds for each channel for the whole time period of the optimization.

Now couple of things could be a problem.

  • I am not sure how you are setting the budget. It has to be unscaled value of spend for the total time period you're running optimization for. Try setting it high value to check
  • Depends, If you're using just cost or just impressions or mix of cost/impressions. bounds.lb*prices is checked against the budget. So check the price values you're passing to the function. You can just use historical cost/historical impressions as an estimate.

ar-asur avatar Aug 28 '23 16:08 ar-asur