Skip to content

Instantly share code, notes, and snippets.

View abhijeet-talaulikar's full-sized avatar

Abhijeet Talaulikar abhijeet-talaulikar

View GitHub Profile
posterior = pm.sample_posterior_predictive(trace, mmm)
predictions = posterior['posterior_predictive']['revenue'].mean(axis=0).mean(axis=0) * media['REVENUE'].mean()
media_decomp = pd.DataFrame({i:np.array(trace['posterior']["contribution_"+str(i)]).mean(axis=(0,1)) for i in channel_priors.keys()}, index=dates) * media['REVENUE'].mean()
plt.plot(media['REVENUE'])
plt.plot(predictions)
plt.title("Model Fit")
current_revenue = media_roi['revenue'].sum()
current_budget = media_roi['spend'].sum()
new_budget = current_budget * 1.05
# initialize model
opt_model = grb.Model(name="Media Budget Optimization")
x_vars = opt_model.addVars(media_roi['media'], vtype=grb.GRB.CONTINUOUS,
lb=0, name="media")
# keep total spend less than new available budget
opt_model.addConstr(sum(x_vars[i] for i in media_roi['media']) <=
new_budget, name="New Budget")
# Value of the objective function (ROI)
print(f"The Optimal Objective Value {opt_model.objVal}")
# Values of decision variables (Funds allocated to each channel)
opt_df = pd.DataFrame.from_dict(x_vars, orient="index", columns=["Variable Object"])
opt_df.reset_index(inplace=True)
opt_df.rename(columns={"index": "Media"}, inplace=True)
opt_df["Budget Allocated"] = opt_df["Variable Object"].apply(lambda item: item.X)
plt.bar(opt_df["Media"], opt_df["Budget Allocated"])
plt.xlabel("Media")
def BayesianMMM(splits="W"):
if splits == "Q":
time_series = pd.PeriodIndex(dates, freq='Q').astype(str).str[-1].astype(int).values
elif splits == "H":
time_series = pd.PeriodIndex(dates, freq='Q').astype(str).str[-1].map({'1':1, '2':1, '3':2, '4':2}).values
elif splits == "YoY":
time_series = np.array([1]*52 + [2]*52)
else:
time_series = np.arange(104)
if splits == "Q":
time_series = pd.PeriodIndex(dates, freq='Q').astype(str).str[-1].astype(int).values
elif splits == "H":
time_series = pd.PeriodIndex(dates, freq='Q').astype(str).str[-1].map({'1':1, '2':1, '3':2, '4':2}).values
elif splits == "YoY":
time_series = np.array([1]*52 + [2]*52)
else:
time_series = np.arange(104)
rolling_channel_coefficient = pm.GaussianRandomWalk(
f"coefficient_{channel}",
sigma=sigma_walk,
init_dist=pm.Normal.dist(channel_prior, 0.01),
dims="time"
)
mmm, trace = BayesianMMM("W")
import matplotlib.pyplot as plt
plt.figure(figsize=(15,5))
for channel in ['CTV', 'DIRECT_MAIL', 'EMAIL', 'TV']:
plt.plot(
trace.posterior[f'coefficient_{channel}'].values.mean(axis=(0,1)),
linewidth=2,
mmm, trace = BayesianMMM("Q")
paid_search_df = pd.DataFrame({
'quarter': "Quarter "+pd.PeriodIndex(dates, freq='Q').astype(str).str[-1].astype(str).values,
'coefficient': trace['posterior']['coefficient_PAID_SEARCH'].mean(axis=(0,1))
})
paid_search_df.groupby('quarter').mean().plot.bar();
plt.title("Paid Search Effectiveness over Quarters")
plt.ylim(bottom=0.12)
mmm, trace = BayesianMMM("YoY")
paid_search_df = pd.DataFrame({
'year': np.array(["Year before that"]*52 + ["Last Year"]*52),
'coefficient': trace['posterior']['coefficient_PAID_SEARCH'].mean(axis=(0,1))
})
display(paid_search_df.groupby('year').mean())
paid_search_df.groupby('year').mean().plot.bar();