4 Pacing for Optimization
Warning
🚧 This chapter is a work in progress.
Maths: control theory (PID)!
Explain how pacing optimizes delivery (for different parties).
Use Observable to render example of multiplier changing over time?
import random
import matplotlib.pyplot as plt
# Constants
= 1000.0 # Daily budget
BUDGET = 1440 # Minutes in a day
TOTAL_MINUTES = 0.8 # Proportional gain
K_p = 0.05 # Integral gain
K_i = 0.1 # Derivative gain
K_d = 0.2 # $2 CPM is 200/1000 cents per impression
OPPORTUNITY_VALUE # the value and budget above need to be in same units, so assume cents
# Initialization
= 0.01 # Initial pickiness (how selective to be with ad opportunities)
pickiness_level = 0
previous_error = 0
integral_error = 0
spent
# Data for plotting
= []
opportunities_per_minute = []
pickiness_levels = []
actual_spend = []
target_spend
# Simulation loop
for minute in range(TOTAL_MINUTES):
# Simulate opportunities with smoother variation
if minute == 0:
= random.randint(10, 20) # Initial range
opportunities else:
# Limit changes to +/- 5 opportunities from previous minute
= max(5, min(25, opportunities_per_minute[-1] + random.randint(-5, 5)))
opportunities
opportunities_per_minute.append(opportunities)
# Target spend per minute with linear (not opportunity based) pacing
= BUDGET / TOTAL_MINUTES
target_spend_per_minute * minute)
target_spend.append(target_spend_per_minute
# Calculate overall pace
= spent / (target_spend_per_minute * minute) if minute > 0 else 0
pace
# Calculate error
= (1 - pace) / (1 + pace)
error
# PID control
= (error - previous_error)
derivative_error += error
integral_error = pickiness_level + (K_p * error + K_i * integral_error + K_d * derivative_error)
new_pickiness_level
pickiness_levels.append(new_pickiness_level)= error
previous_error
# Simulate spending with fixed opportunity value
# if new_pickiness_level is between 0 and 1, then you are only winning a fraction of all opportunities per minute
= opportunities * OPPORTUNITY_VALUE * new_pickiness_level
spent_this_minute += spent_this_minute
spent
actual_spend.append(spent)
# Plotting
=(12, 8))
plt.figure(figsize
3, 1, 1)
plt.subplot(
plt.plot(opportunities_per_minute)"Ad Opportunities per Minute")
plt.title(
3, 1, 2)
plt.subplot(
plt.plot(pickiness_levels)"Adjusted Pickiness Level")
plt.title(
3, 1, 3)
plt.subplot(='Target Spend')
plt.plot(target_spend, label='Actual Spend')
plt.plot(actual_spend, label"Spending Over Time")
plt.title(
plt.legend()
plt.show()