Skip to content

Instantly share code, notes, and snippets.

View abhijeet-talaulikar's full-sized avatar

Abhijeet Talaulikar abhijeet-talaulikar

View GitHub Profile
def hill_transform(x, alpha, gamma):
return 1 / (1 + (x/gamma)**-alpha)
media = pd.read_csv('media.csv', parse_dates=['DATE'])
media = media.resample('W-Mon', label='left', closed='left', on='DATE').sum()
channel_priors = {
"CTV": 0.02,
"DISPLAY": 0.05,
"DIRECT_MAIL": 0.02,
"EMAIL": 0.03,
"PAID_SOCIAL": 0.08,
"PAID_SEARCH": 0.14,
"TV": 0.01
}
# define coefficient
channel_prior = channel_priors[channel]
channel_coefficient = pm.TruncatedNormal(f"coefficient_{channel}", mu=channel_prior, sigma=0.0001, lower=0, upper=0.15)
# define saturation
alpha = pm.Uniform(f"alpha_{channel}", lower=0.5, upper=2)
gamma = pm.Uniform(f"gamma_{channel}", lower=0.5, upper=1.5)
def scale(x, y):
return x * y.sum() / x.sum()
with pm.Model() as mmm:
target = media_transformed['REVENUE'] / media_transformed['REVENUE'].mean()
media_contributions = []
for channel in channel_priors.keys():
trace_vars = [i.replace('coefficient_','') for i in dir(trace['posterior']) if i.startswith("coefficient_") or i=='intercept']
trace_coeff_vars = [i for i in dir(trace['posterior']) if i.startswith("coefficient_") or i=='intercept']
trace_alpha_vars = [i for i in dir(trace['posterior']) if i.startswith("alpha_")]
trace_gamma_vars = [i for i in dir(trace['posterior']) if i.startswith("gamma_")]
model_results = pd.DataFrame({
"variable": trace_vars,
"coefficient": [float(trace['posterior'][i].mean()) for i in trace_coeff_vars]
}).merge(
pd.DataFrame({
az.plot_posterior(
trace,
var_names=['intercept', 'coefficient_'],
filter_vars='like'
);
bias = pd.DataFrame({
"t": np.arange(104)
})
d = 2
# Fourier terms
for i in np.arange(1,d+1):
bias[f"cos_{i}"] = np.cos(2 * np.pi * i * bias["t"] / 52)
bias[f"sin_{i}"] = np.sin(2 * np.pi * i * bias["t"] / 52)
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()
media_roi = pd.concat([
media.drop(['DATE','REVENUE'],axis=1).sum(),
media_decomp.sum()
], axis=1).reset_index()
media_roi.columns = ['media','spend','revenue']
media_roi['ROI'] = (media_roi['revenue'] / media_roi['spend'])
def get_response_curve(channel, start_time, end_time):
def hill_transform(x, alpha, gamma):
return 1 / (1 + (x/gamma)**-alpha)
# parameters
coefficient = model.query("variable == @channel")['coefficient'].iloc[0]
alpha = model.query("variable == @channel")['alpha'].iloc[0]
gamma = model.query("variable == @channel")['gamma'].iloc[0]