Spaces:
Running
Running
Pragya Jatav
commited on
Commit
·
f7bb281
1
Parent(s):
ed0b93a
m1
Browse files- Model_Result_Overview.py +2 -2
- Overview_data_test_panel@#prospects.xlsx +0 -0
- Streamlit_functions.py +70 -45
- __pycache__/Streamlit_functions.cpython-310.pyc +0 -0
- __pycache__/classes.cpython-310.pyc +0 -0
- __pycache__/response_curves_model_quality.cpython-310.pyc +0 -0
- __pycache__/response_curves_model_quality_base.cpython-310.pyc +0 -0
- __pycache__/utilities.cpython-310.pyc +0 -0
- __pycache__/utilities_with_panel.cpython-310.pyc +0 -0
- classes.py +50 -33
- pages/2_Scenario_Planner.py +0 -0
- pages/3_Saved_Scenarios.py +6 -5
- response_curves_model_quality.py +20 -17
- response_curves_model_quality_base.py +7 -7
- response_curves_parameters.xlsx +0 -0
- summary_df.pkl +1 -1
- utilities.py +17 -8
- utilities_with_panel.py +16 -16
Model_Result_Overview.py
CHANGED
@@ -35,7 +35,7 @@ def get_random_effects(media_data, panel_col, mdf):
|
|
35 |
random_eff_df = pd.DataFrame(columns=[panel_col, "random_effect"])
|
36 |
|
37 |
for i, market in enumerate(media_data[panel_col].unique()):
|
38 |
-
print(i, end='\r')
|
39 |
intercept = mdf.random_effects[market].values[0]
|
40 |
random_eff_df.loc[i, 'random_effect'] = intercept
|
41 |
random_eff_df.loc[i, panel_col] = market
|
@@ -245,7 +245,7 @@ if auth_status:
|
|
245 |
|
246 |
# with columns[0]:
|
247 |
# st.metric(label='Spends', value=format_numbers(float(scenario.actual_total_spends)))
|
248 |
-
#
|
249 |
# with columns[1]:
|
250 |
# st.metric(label=target, value=format_numbers(float(scenario.actual_total_sales),include_indicator=False))
|
251 |
|
|
|
35 |
random_eff_df = pd.DataFrame(columns=[panel_col, "random_effect"])
|
36 |
|
37 |
for i, market in enumerate(media_data[panel_col].unique()):
|
38 |
+
# print(i, end='\r')
|
39 |
intercept = mdf.random_effects[market].values[0]
|
40 |
random_eff_df.loc[i, 'random_effect'] = intercept
|
41 |
random_eff_df.loc[i, panel_col] = market
|
|
|
245 |
|
246 |
# with columns[0]:
|
247 |
# st.metric(label='Spends', value=format_numbers(float(scenario.actual_total_spends)))
|
248 |
+
# #### print(f"##################### {scenario.actual_total_sales} ##################")
|
249 |
# with columns[1]:
|
250 |
# st.metric(label=target, value=format_numbers(float(scenario.actual_total_sales),include_indicator=False))
|
251 |
|
Overview_data_test_panel@#prospects.xlsx
CHANGED
Binary files a/Overview_data_test_panel@#prospects.xlsx and b/Overview_data_test_panel@#prospects.xlsx differ
|
|
Streamlit_functions.py
CHANGED
@@ -348,8 +348,8 @@ def waterfall(start_date,end_date,btn_chart):
|
|
348 |
font=dict(size=16),
|
349 |
# align='left'
|
350 |
)
|
351 |
-
# print(cur_data)
|
352 |
-
# print(prev_data)
|
353 |
# fig.show()
|
354 |
return fig
|
355 |
|
@@ -738,7 +738,7 @@ def media_decomp():
|
|
738 |
|
739 |
media_cols = media_decomp_df.columns
|
740 |
for i in range(2,len(media_cols)):
|
741 |
-
# print(media_cols[i])
|
742 |
cumulative_df[media_cols[i]] = cumulative_df[media_cols[i]] + cumulative_df[media_cols[i-1]]
|
743 |
# cumulative_df
|
744 |
|
@@ -1081,22 +1081,21 @@ def scenario_spend_forecasting2(delta_df,start_date,end_date):
|
|
1081 |
start_date = pd.to_datetime(start_date)
|
1082 |
end_date = pd.to_datetime(end_date)
|
1083 |
|
1084 |
-
cur_data = df[(df['Date'] >= start_date) & (df['Date']
|
1085 |
cur_data = cur_data[spend_cols2]
|
1086 |
cur_data.columns = channels2
|
1087 |
|
1088 |
cur_data["Date2"] = cur_data["Date"]+ pd.Timedelta(days=6)
|
|
|
|
|
|
|
1089 |
# cur_data["Date"] = delta_df["Date"]
|
1090 |
-
cur_data["Date_diff"] = (cur_data["Date"]-start_date).dt.days
|
1091 |
-
cur_data["Date_diff_months"] =(np.ceil(cur_data["Date_diff"] / 30))
|
1092 |
|
1093 |
-
data2 = cur_data.groupby("
|
1094 |
'Date':"min",
|
1095 |
-
"Date2":"max"
|
1096 |
-
}).reset_index()
|
1097 |
-
|
1098 |
-
|
1099 |
-
data1 = cur_data.groupby("Date_diff_months").agg({
|
1100 |
'BROADCAST TV':"sum",
|
1101 |
'CABLE TV':"sum",
|
1102 |
'CONNECTED & OTT TV':"sum",
|
@@ -1110,41 +1109,67 @@ def scenario_spend_forecasting2(delta_df,start_date,end_date):
|
|
1110 |
'DIGITAL PARTNERS':"sum",
|
1111 |
'AUDIO':"sum",
|
1112 |
'EMAIL':"sum"
|
1113 |
-
}).
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1114 |
|
1115 |
-
|
1116 |
-
|
1117 |
-
|
1118 |
-
|
1119 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1120 |
|
1121 |
-
data3 = pd.DataFrame(index = data1.index)
|
1122 |
-
for c in months_list:
|
1123 |
-
|
1124 |
|
1125 |
-
df1 = df_modified2[months_list].transpose()
|
1126 |
-
df1["Metrics"] = "Last Year Spends"
|
1127 |
|
1128 |
-
data3 = data3.transpose()
|
1129 |
-
data3 = data3.astype(int)
|
1130 |
-
data2.index = data2["Date_diff_months"]
|
1131 |
-
data2.columns = ["
|
1132 |
-
data3["start date"] = data2["start date"].dt.date
|
1133 |
-
data3["end date"] = data2["end date"].dt.date
|
1134 |
-
data3["Month"] = data3.index
|
1135 |
-
cols = ["Month","start date","end date",'BROADCAST TV',
|
1136 |
-
|
1137 |
-
|
1138 |
-
|
1139 |
-
|
1140 |
-
|
1141 |
-
|
1142 |
-
|
1143 |
-
|
1144 |
-
|
1145 |
-
|
1146 |
-
|
1147 |
-
|
1148 |
# data3["Metrics"] = "Forecasted Year Spends"
|
1149 |
|
1150 |
# df2 = df_modified2["Delta_percent"].transpose()
|
@@ -1187,6 +1212,6 @@ def scenario_spend_forecasting2(delta_df,start_date,end_date):
|
|
1187 |
# # # # df_modified = delta_percent
|
1188 |
# # # # df_modified["Optimised Spends"] = df_modified["Current Spends"]*
|
1189 |
# # spend_cols1 = pd.DataFrame(spend_cols)[0].to_list()
|
1190 |
-
|
1191 |
-
return
|
1192 |
|
|
|
348 |
font=dict(size=16),
|
349 |
# align='left'
|
350 |
)
|
351 |
+
# # print(cur_data)
|
352 |
+
# # print(prev_data)
|
353 |
# fig.show()
|
354 |
return fig
|
355 |
|
|
|
738 |
|
739 |
media_cols = media_decomp_df.columns
|
740 |
for i in range(2,len(media_cols)):
|
741 |
+
# # print(media_cols[i])
|
742 |
cumulative_df[media_cols[i]] = cumulative_df[media_cols[i]] + cumulative_df[media_cols[i-1]]
|
743 |
# cumulative_df
|
744 |
|
|
|
1081 |
start_date = pd.to_datetime(start_date)
|
1082 |
end_date = pd.to_datetime(end_date)
|
1083 |
|
1084 |
+
cur_data = df[(df['Date'] >= start_date) & (df['Date'] < end_date)]
|
1085 |
cur_data = cur_data[spend_cols2]
|
1086 |
cur_data.columns = channels2
|
1087 |
|
1088 |
cur_data["Date2"] = cur_data["Date"]+ pd.Timedelta(days=6)
|
1089 |
+
cur_data["Month"] = cur_data["Date"].dt.month
|
1090 |
+
|
1091 |
+
|
1092 |
# cur_data["Date"] = delta_df["Date"]
|
1093 |
+
# cur_data["Date_diff"] = (cur_data["Date"]-start_date).dt.days
|
1094 |
+
# cur_data["Date_diff_months"] =(np.ceil(cur_data["Date_diff"] / 30))
|
1095 |
|
1096 |
+
data2 = cur_data.groupby("Month").agg({
|
1097 |
'Date':"min",
|
1098 |
+
"Date2":"max",
|
|
|
|
|
|
|
|
|
1099 |
'BROADCAST TV':"sum",
|
1100 |
'CABLE TV':"sum",
|
1101 |
'CONNECTED & OTT TV':"sum",
|
|
|
1109 |
'DIGITAL PARTNERS':"sum",
|
1110 |
'AUDIO':"sum",
|
1111 |
'EMAIL':"sum"
|
1112 |
+
}).reset_index()
|
1113 |
+
|
1114 |
+
def get_month_name(month_number):
|
1115 |
+
|
1116 |
+
months = ["January", "February", "March", "April", "May", "June",
|
1117 |
+
"July", "August", "September", "October", "November", "December"]
|
1118 |
+
if 1 <= month_number <= 12:
|
1119 |
+
return months[month_number - 1]
|
1120 |
+
else:
|
1121 |
+
return "Invalid month number"
|
1122 |
|
1123 |
+
data2["Month year"] = data2["Month"].apply(get_month_name) + ' ' +(data2["Date"].dt.year+1).astype(str)
|
1124 |
+
print(data2.columns)
|
1125 |
+
data2 = data2[['Month year' ,'Date', 'Date2', 'BROADCAST TV', 'CABLE TV',
|
1126 |
+
'CONNECTED & OTT TV', 'VIDEO', 'DISPLAY PROSPECTING',
|
1127 |
+
'DISPLAY RETARGETING', 'SOCIAL PROSPECTING', 'SOCIAL RETARGETING',
|
1128 |
+
'SEARCH BRAND', 'SEARCH NON-BRAND', 'DIGITAL PARTNERS', 'AUDIO',
|
1129 |
+
'EMAIL']]
|
1130 |
+
data2.columns = ['Month ','Base Data Start Date', 'Base Data End Date', 'BROADCAST TV', 'CABLE TV',
|
1131 |
+
'CONNECTED & OTT TV', 'VIDEO', 'DISPLAY PROSPECTING',
|
1132 |
+
'DISPLAY RETARGETING', 'SOCIAL PROSPECTING', 'SOCIAL RETARGETING',
|
1133 |
+
'SEARCH BRAND', 'SEARCH NON-BRAND', 'DIGITAL PARTNERS', 'AUDIO',
|
1134 |
+
'EMAIL']
|
1135 |
+
data2['Base Data Start Date'] = data2['Base Data Start Date'].dt.date
|
1136 |
+
data2['Base Data End Date'] = data2['Base Data End Date'].dt.date
|
1137 |
+
#.transpose()
|
1138 |
+
# st.dataframe(data2)
|
1139 |
+
# st.dataframe(data1)
|
1140 |
+
# months_list = cur_data["Month"].unique()
|
1141 |
+
# data1["Channels"]=data1.index
|
1142 |
+
# df_modified = delta_df.merge(key_df,on = "Channel_name",how = "inner")
|
1143 |
+
# df_modified2 = df_modified.merge(data1,on = "Channels",how ="outer")
|
1144 |
+
# df_modified2.index = df_modified2["Channels"]
|
1145 |
|
1146 |
+
# data3 = pd.DataFrame(index = data1.index)
|
1147 |
+
# for c in months_list:
|
1148 |
+
# data3[c] = df_modified2[c]*(1+df_modified2["Delta_percent"]/100)
|
1149 |
|
1150 |
+
# df1 = df_modified2[months_list].transpose()
|
1151 |
+
# df1["Metrics"] = "Last Year Spends"
|
1152 |
|
1153 |
+
# data3 = data3.transpose()
|
1154 |
+
# data3 = data3.astype(int)
|
1155 |
+
# # data2.index = data2["Date_diff_months"]
|
1156 |
+
# data2.columns = ["start date","end date"]
|
1157 |
+
# data3["start date"] = data2["start date"].dt.date
|
1158 |
+
# data3["end date"] = data2["end date"].dt.date
|
1159 |
+
# data3["Month"] = data3.index
|
1160 |
+
# cols = ["Month","start date","end date",'BROADCAST TV',
|
1161 |
+
# 'CABLE TV',
|
1162 |
+
# 'CONNECTED & OTT TV',
|
1163 |
+
# 'VIDEO',
|
1164 |
+
# 'DISPLAY PROSPECTING',
|
1165 |
+
# 'DISPLAY RETARGETING',
|
1166 |
+
# 'SOCIAL PROSPECTING',
|
1167 |
+
# 'SOCIAL RETARGETING',
|
1168 |
+
# 'SEARCH BRAND',
|
1169 |
+
# 'SEARCH NON-BRAND',
|
1170 |
+
# 'DIGITAL PARTNERS',
|
1171 |
+
# 'AUDIO',
|
1172 |
+
# 'EMAIL']
|
1173 |
# data3["Metrics"] = "Forecasted Year Spends"
|
1174 |
|
1175 |
# df2 = df_modified2["Delta_percent"].transpose()
|
|
|
1212 |
# # # # df_modified = delta_percent
|
1213 |
# # # # df_modified["Optimised Spends"] = df_modified["Current Spends"]*
|
1214 |
# # spend_cols1 = pd.DataFrame(spend_cols)[0].to_list()
|
1215 |
+
data2.set_index('Month ', inplace=True)
|
1216 |
+
return data2
|
1217 |
|
__pycache__/Streamlit_functions.cpython-310.pyc
CHANGED
Binary files a/__pycache__/Streamlit_functions.cpython-310.pyc and b/__pycache__/Streamlit_functions.cpython-310.pyc differ
|
|
__pycache__/classes.cpython-310.pyc
CHANGED
Binary files a/__pycache__/classes.cpython-310.pyc and b/__pycache__/classes.cpython-310.pyc differ
|
|
__pycache__/response_curves_model_quality.cpython-310.pyc
CHANGED
Binary files a/__pycache__/response_curves_model_quality.cpython-310.pyc and b/__pycache__/response_curves_model_quality.cpython-310.pyc differ
|
|
__pycache__/response_curves_model_quality_base.cpython-310.pyc
CHANGED
Binary files a/__pycache__/response_curves_model_quality_base.cpython-310.pyc and b/__pycache__/response_curves_model_quality_base.cpython-310.pyc differ
|
|
__pycache__/utilities.cpython-310.pyc
CHANGED
Binary files a/__pycache__/utilities.cpython-310.pyc and b/__pycache__/utilities.cpython-310.pyc differ
|
|
__pycache__/utilities_with_panel.cpython-310.pyc
CHANGED
Binary files a/__pycache__/utilities_with_panel.cpython-310.pyc and b/__pycache__/utilities_with_panel.cpython-310.pyc differ
|
|
classes.py
CHANGED
@@ -4,7 +4,6 @@ from collections import OrderedDict
|
|
4 |
import pandas as pd
|
5 |
from numerize.numerize import numerize
|
6 |
# from gekko import GEKKO
|
7 |
-
|
8 |
def class_to_dict(class_instance):
|
9 |
attr_dict = {}
|
10 |
if isinstance(class_instance, Channel):
|
@@ -68,7 +67,7 @@ class Channel:
|
|
68 |
self.dates = dates
|
69 |
self.conversion_rate = conversion_rate
|
70 |
self.actual_spends = spends.copy()
|
71 |
-
|
72 |
|
73 |
if modified_spends is None:
|
74 |
self.modified_spends = self.actual_spends.copy()
|
@@ -84,8 +83,8 @@ class Channel:
|
|
84 |
|
85 |
self.upper_limit = self.actual_spends.max() + self.actual_spends.std()
|
86 |
self.power = np.ceil(np.log(self.actual_spends.max()) / np.log(10)) - 3
|
87 |
-
self.actual_sales = None
|
88 |
-
self.actual_sales = self.response_curve(self.actual_spends)#sales.copy()#
|
89 |
self.actual_total_spends = self.actual_spends.sum()
|
90 |
self.actual_total_sales = self.actual_sales.sum()
|
91 |
self.modified_sales = self.calculate_sales()
|
@@ -106,7 +105,7 @@ class Channel:
|
|
106 |
)
|
107 |
|
108 |
def calculate_sales(self):
|
109 |
-
print("in calc_sales")
|
110 |
return self.response_curve(self.modified_spends)
|
111 |
|
112 |
def hill_equation(x, Kd, n):
|
@@ -119,27 +118,40 @@ class Channel:
|
|
119 |
self.upper_limit + (x - self.upper_limit) * self.upper_limit / x,
|
120 |
)
|
121 |
if self.response_curve_type == "hill-eq":
|
122 |
-
|
123 |
-
print(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
124 |
Kd= self.response_curve_params["Kd"]
|
125 |
n= self.response_curve_params["n"]
|
126 |
x_min= self.response_curve_params["x_min"]
|
127 |
x_max= self.response_curve_params["x_max"]
|
128 |
y_min= self.response_curve_params["y_min"]
|
129 |
y_max= self.response_curve_params['y_max']
|
130 |
-
# print(x_min)
|
131 |
-
# print(Kd,n,x_min,x_max,y_min,y_max)
|
132 |
-
print(np.sum(x)/104)
|
133 |
-
x_inp = ( x- x_min) / (x_max - x_min)
|
134 |
-
# print(
|
|
|
135 |
x_out = x_inp**n / (Kd**n + x_inp**n) #self.hill_equation(x_inp,Kd, n)
|
136 |
-
print(x_out)
|
137 |
-
|
138 |
-
|
|
|
|
|
|
|
|
|
139 |
sales[np.isnan(sales)] = 0
|
140 |
-
print(sales)
|
141 |
-
print(np.sum(sales))
|
142 |
-
# print(sales)
|
143 |
if self.response_curve_type == "s-curve":
|
144 |
if self.power >= 0:
|
145 |
x = x / 10**self.power
|
@@ -254,14 +266,18 @@ class Scenario:
|
|
254 |
return total_modified_spends
|
255 |
|
256 |
def calculate_actual_total_sales(self):
|
257 |
-
total_actual_sales = self.constant.sum() +
|
|
|
258 |
for channel in self.channels.values():
|
259 |
total_actual_sales += channel.actual_total_sales
|
|
|
|
|
260 |
return total_actual_sales
|
261 |
|
262 |
def calculate_modified_total_sales(self):
|
263 |
-
total_modified_sales = self.constant.sum() + self.correction.sum()
|
264 |
for channel in self.channels.values():
|
|
|
265 |
total_modified_sales += channel.modified_total_sales
|
266 |
return total_modified_sales
|
267 |
|
@@ -322,9 +338,9 @@ class Scenario:
|
|
322 |
|
323 |
def cost_func(channel,x):
|
324 |
x_inp = (x/104 - param_dicts["x_min"][channel]) / (param_dicts["x_max"][channel] - param_dicts["x_min"][channel])
|
325 |
-
# print(x_inp)
|
326 |
x_out = hill_equation(x_inp, param_dicts["Kd"][channel], param_dicts["n"][channel])
|
327 |
-
# print(x_out)
|
328 |
#
|
329 |
return (param_dicts["y_max"][channel] - param_dicts["y_min"][channel])*(x_out + param_dicts["y_min"][channel])*104
|
330 |
|
@@ -332,7 +348,7 @@ class Scenario:
|
|
332 |
|
333 |
|
334 |
def optimize_spends(self, sales_percent, channels_list, algo="trust-constr"):
|
335 |
-
print("%"*100)
|
336 |
desired_sales = self.actual_total_sales * (1 + sales_percent / 100.0)
|
337 |
|
338 |
def constraint(x):
|
@@ -346,10 +362,11 @@ class Scenario:
|
|
346 |
(1+np.array([-50.0, 100.0]) / 100.0)
|
347 |
* self.channels[ch].actual_total_spends
|
348 |
)
|
349 |
-
|
350 |
initial_point = []
|
351 |
for bound in bounds:
|
352 |
initial_point.append(bound[0])
|
|
|
353 |
|
354 |
power = np.ceil(np.log(sum(initial_point)) / np.log(10))
|
355 |
|
@@ -406,8 +423,8 @@ class Scenario:
|
|
406 |
self.update(channel_name, modified_spends)
|
407 |
return -1 * self.modified_total_sales
|
408 |
|
409 |
-
print(bounds)
|
410 |
-
print("$"*100)
|
411 |
res = minimize(
|
412 |
lambda x: objective_function(x) / 1e3,
|
413 |
method="trust-constr",
|
@@ -424,7 +441,7 @@ class Scenario:
|
|
424 |
# bounds=bounds,
|
425 |
# tol=1e-16
|
426 |
# )
|
427 |
-
print(res)
|
428 |
for channel_name, modified_spends in zip(channels_list, res.x):
|
429 |
self.update(channel_name, modified_spends)
|
430 |
|
@@ -440,9 +457,9 @@ class Scenario:
|
|
440 |
param_dicts = {col: response_curve_params[col].to_dict() for col in response_curve_params.columns}
|
441 |
|
442 |
x_inp = (x/104 - param_dicts["x_min"][channel]) / (param_dicts["x_max"][channel] - param_dicts["x_min"][channel])
|
443 |
-
# print(x_inp)
|
444 |
x_out = self.hill_equation(x_inp, param_dicts["Kd"][channel], param_dicts["n"][channel])
|
445 |
-
# print(x_out)
|
446 |
#
|
447 |
return (param_dicts["y_max"][channel] - param_dicts["y_min"][channel])*(x_out + param_dicts["y_min"][channel])*104
|
448 |
|
@@ -462,7 +479,7 @@ class Scenario:
|
|
462 |
|
463 |
# x_vars=[]
|
464 |
# x_vars = [m.Var(value=param_dicts["current_spends"][_], lb=param_dicts["x_min"][_]*104, ub=5*param_dicts["current_spends"][_]) for _ in channels_list]
|
465 |
-
# print(x_vars)
|
466 |
# # x_vars,lower_bounds
|
467 |
|
468 |
# # Define the objective function to minimize
|
@@ -470,8 +487,8 @@ class Scenario:
|
|
470 |
# spends = 0
|
471 |
# i = 0
|
472 |
# for i,c in enumerate(channels_list):
|
473 |
-
# # print(c)
|
474 |
-
# # print(x_vars[i])
|
475 |
# cost = cost + (self.cost_func(c, x_vars[i]))
|
476 |
# spends = spends +x_vars[i]
|
477 |
|
@@ -486,7 +503,7 @@ class Scenario:
|
|
486 |
# m.solve(disp=True)
|
487 |
|
488 |
# for i, var in enumerate(x_vars):
|
489 |
-
# print(f"x{i+1} = {var.value[0]}")
|
490 |
|
491 |
# for channel_name, modified_spends in zip(channels_list, x_vars):
|
492 |
# self.update(channel_name, modified_spends.value[0])
|
|
|
4 |
import pandas as pd
|
5 |
from numerize.numerize import numerize
|
6 |
# from gekko import GEKKO
|
|
|
7 |
def class_to_dict(class_instance):
|
8 |
attr_dict = {}
|
9 |
if isinstance(class_instance, Channel):
|
|
|
67 |
self.dates = dates
|
68 |
self.conversion_rate = conversion_rate
|
69 |
self.actual_spends = spends.copy()
|
70 |
+
self.actual_sales = sales.copy()
|
71 |
|
72 |
if modified_spends is None:
|
73 |
self.modified_spends = self.actual_spends.copy()
|
|
|
83 |
|
84 |
self.upper_limit = self.actual_spends.max() + self.actual_spends.std()
|
85 |
self.power = np.ceil(np.log(self.actual_spends.max()) / np.log(10)) - 3
|
86 |
+
# self.actual_sales = None
|
87 |
+
# self.actual_sales = self.response_curve(self.actual_spends)#sales.copy()#
|
88 |
self.actual_total_spends = self.actual_spends.sum()
|
89 |
self.actual_total_sales = self.actual_sales.sum()
|
90 |
self.modified_sales = self.calculate_sales()
|
|
|
105 |
)
|
106 |
|
107 |
def calculate_sales(self):
|
108 |
+
# # print("in calc_sales")
|
109 |
return self.response_curve(self.modified_spends)
|
110 |
|
111 |
def hill_equation(x, Kd, n):
|
|
|
118 |
self.upper_limit + (x - self.upper_limit) * self.upper_limit / x,
|
119 |
)
|
120 |
if self.response_curve_type == "hill-eq":
|
121 |
+
# dividing_parameter = check_dividing_parameter()
|
122 |
+
# # print("lalala")
|
123 |
+
# # print(self.name)
|
124 |
+
if len(x) == 1:
|
125 |
+
dividing_rate = 104
|
126 |
+
# x = np.sum(x)
|
127 |
+
else:
|
128 |
+
dividing_rate = 1
|
129 |
+
# x = np.sum(x)
|
130 |
+
# dividing_rate = 104
|
131 |
Kd= self.response_curve_params["Kd"]
|
132 |
n= self.response_curve_params["n"]
|
133 |
x_min= self.response_curve_params["x_min"]
|
134 |
x_max= self.response_curve_params["x_max"]
|
135 |
y_min= self.response_curve_params["y_min"]
|
136 |
y_max= self.response_curve_params['y_max']
|
137 |
+
# # print(x_min)
|
138 |
+
# # print(Kd,n,x_min,x_max,y_min,y_max)
|
139 |
+
# # print(np.sum(x)/104)
|
140 |
+
x_inp = ( x/dividing_rate- x_min) / (x_max - x_min)
|
141 |
+
# # print("x",x)
|
142 |
+
# # print("x_inp",x_inp)
|
143 |
x_out = x_inp**n / (Kd**n + x_inp**n) #self.hill_equation(x_inp,Kd, n)
|
144 |
+
# # print("x_out",x_out)
|
145 |
+
|
146 |
+
|
147 |
+
x_val_inv = (x_out*x_max + (1 - x_out) * x_min)
|
148 |
+
sales = (x_val_inv*y_min/y_max)*dividing_rate
|
149 |
+
# sales = ((x_max - x_min)*x_out + x_min)*dividing_rate
|
150 |
+
|
151 |
sales[np.isnan(sales)] = 0
|
152 |
+
# # print(sales)
|
153 |
+
# # print(np.sum(sales))
|
154 |
+
# # print("sales",sales)
|
155 |
if self.response_curve_type == "s-curve":
|
156 |
if self.power >= 0:
|
157 |
x = x / 10**self.power
|
|
|
266 |
return total_modified_spends
|
267 |
|
268 |
def calculate_actual_total_sales(self):
|
269 |
+
total_actual_sales = 0 #self.constant.sum() +
|
270 |
+
# # print(self.correction)
|
271 |
for channel in self.channels.values():
|
272 |
total_actual_sales += channel.actual_total_sales
|
273 |
+
# # print(channel.actual_total_sales)
|
274 |
+
# # print(total_actual_sales)
|
275 |
return total_actual_sales
|
276 |
|
277 |
def calculate_modified_total_sales(self):
|
278 |
+
total_modified_sales = 0 #self.constant.sum() + self.correction.sum()
|
279 |
for channel in self.channels.values():
|
280 |
+
# print(channel,channel.modified_total_sales)
|
281 |
total_modified_sales += channel.modified_total_sales
|
282 |
return total_modified_sales
|
283 |
|
|
|
338 |
|
339 |
def cost_func(channel,x):
|
340 |
x_inp = (x/104 - param_dicts["x_min"][channel]) / (param_dicts["x_max"][channel] - param_dicts["x_min"][channel])
|
341 |
+
# # print(x_inp)
|
342 |
x_out = hill_equation(x_inp, param_dicts["Kd"][channel], param_dicts["n"][channel])
|
343 |
+
# # print(x_out)
|
344 |
#
|
345 |
return (param_dicts["y_max"][channel] - param_dicts["y_min"][channel])*(x_out + param_dicts["y_min"][channel])*104
|
346 |
|
|
|
348 |
|
349 |
|
350 |
def optimize_spends(self, sales_percent, channels_list, algo="trust-constr"):
|
351 |
+
# # print("%"*100)
|
352 |
desired_sales = self.actual_total_sales * (1 + sales_percent / 100.0)
|
353 |
|
354 |
def constraint(x):
|
|
|
362 |
(1+np.array([-50.0, 100.0]) / 100.0)
|
363 |
* self.channels[ch].actual_total_spends
|
364 |
)
|
365 |
+
# # print(self.channels[ch].actual_total_spends)
|
366 |
initial_point = []
|
367 |
for bound in bounds:
|
368 |
initial_point.append(bound[0])
|
369 |
+
# initial_point = np.nan_to_num(initial_point, nan=0.0, posinf=0.0, neginf=0.0)
|
370 |
|
371 |
power = np.ceil(np.log(sum(initial_point)) / np.log(10))
|
372 |
|
|
|
423 |
self.update(channel_name, modified_spends)
|
424 |
return -1 * self.modified_total_sales
|
425 |
|
426 |
+
# # print(bounds)
|
427 |
+
# # print("$"*100)
|
428 |
res = minimize(
|
429 |
lambda x: objective_function(x) / 1e3,
|
430 |
method="trust-constr",
|
|
|
441 |
# bounds=bounds,
|
442 |
# tol=1e-16
|
443 |
# )
|
444 |
+
# # print(res)
|
445 |
for channel_name, modified_spends in zip(channels_list, res.x):
|
446 |
self.update(channel_name, modified_spends)
|
447 |
|
|
|
457 |
param_dicts = {col: response_curve_params[col].to_dict() for col in response_curve_params.columns}
|
458 |
|
459 |
x_inp = (x/104 - param_dicts["x_min"][channel]) / (param_dicts["x_max"][channel] - param_dicts["x_min"][channel])
|
460 |
+
# # print(x_inp)
|
461 |
x_out = self.hill_equation(x_inp, param_dicts["Kd"][channel], param_dicts["n"][channel])
|
462 |
+
# # print(x_out)
|
463 |
#
|
464 |
return (param_dicts["y_max"][channel] - param_dicts["y_min"][channel])*(x_out + param_dicts["y_min"][channel])*104
|
465 |
|
|
|
479 |
|
480 |
# x_vars=[]
|
481 |
# x_vars = [m.Var(value=param_dicts["current_spends"][_], lb=param_dicts["x_min"][_]*104, ub=5*param_dicts["current_spends"][_]) for _ in channels_list]
|
482 |
+
# # print(x_vars)
|
483 |
# # x_vars,lower_bounds
|
484 |
|
485 |
# # Define the objective function to minimize
|
|
|
487 |
# spends = 0
|
488 |
# i = 0
|
489 |
# for i,c in enumerate(channels_list):
|
490 |
+
# # # print(c)
|
491 |
+
# # # print(x_vars[i])
|
492 |
# cost = cost + (self.cost_func(c, x_vars[i]))
|
493 |
# spends = spends +x_vars[i]
|
494 |
|
|
|
503 |
# m.solve(disp=True)
|
504 |
|
505 |
# for i, var in enumerate(x_vars):
|
506 |
+
# # print(f"x{i+1} = {var.value[0]}")
|
507 |
|
508 |
# for channel_name, modified_spends in zip(channels_list, x_vars):
|
509 |
# self.update(channel_name, modified_spends.value[0])
|
pages/2_Scenario_Planner.py
CHANGED
The diff for this file is too large to render.
See raw diff
|
|
pages/3_Saved_Scenarios.py
CHANGED
@@ -32,7 +32,7 @@ def comparison_scenarios_df():
|
|
32 |
summary_df_spend = None
|
33 |
summary_df_prospect = None
|
34 |
# summary_df_efficiency = None
|
35 |
-
|
36 |
for scenario_name in scenarios_to_compare:
|
37 |
scenario_dict = st.session_state['saved_scenarios'][scenario_name]
|
38 |
_spends = []
|
@@ -295,7 +295,7 @@ def download_scenarios():
|
|
295 |
wb.remove(wb.active)
|
296 |
st.session_state['xlsx_buffer'] = io.BytesIO()
|
297 |
summary_df = None
|
298 |
-
|
299 |
for scenario_name in scenarios_to_download:
|
300 |
scenario_dict = st.session_state['saved_scenarios'][scenario_name]
|
301 |
_spends = []
|
@@ -385,8 +385,8 @@ auth_status = st.session_state.get('authentication_status')
|
|
385 |
if auth_status == True:
|
386 |
is_state_initiaized = st.session_state.get('initialized',False)
|
387 |
if not is_state_initiaized:
|
388 |
-
|
389 |
-
initialize_data()
|
390 |
|
391 |
|
392 |
saved_scenarios = st.session_state['saved_scenarios']
|
@@ -429,7 +429,8 @@ if auth_status == True:
|
|
429 |
|
430 |
column_1, column_2,column_3 = st.columns((6,1,1))
|
431 |
with column_1:
|
432 |
-
st.
|
|
|
433 |
# with column_3:
|
434 |
# st.write("")
|
435 |
# st.button('Delete scenario', on_click=delete_scenario)
|
|
|
32 |
summary_df_spend = None
|
33 |
summary_df_prospect = None
|
34 |
# summary_df_efficiency = None
|
35 |
+
#=# print(scenarios_to_download)
|
36 |
for scenario_name in scenarios_to_compare:
|
37 |
scenario_dict = st.session_state['saved_scenarios'][scenario_name]
|
38 |
_spends = []
|
|
|
295 |
wb.remove(wb.active)
|
296 |
st.session_state['xlsx_buffer'] = io.BytesIO()
|
297 |
summary_df = None
|
298 |
+
## print(scenarios_to_download)
|
299 |
for scenario_name in scenarios_to_download:
|
300 |
scenario_dict = st.session_state['saved_scenarios'][scenario_name]
|
301 |
_spends = []
|
|
|
385 |
if auth_status == True:
|
386 |
is_state_initiaized = st.session_state.get('initialized',False)
|
387 |
if not is_state_initiaized:
|
388 |
+
## print("Scenario page state reloaded")
|
389 |
+
initialize_data(target_file = "Overview_data_test_panel@#prospects.xlsx")
|
390 |
|
391 |
|
392 |
saved_scenarios = st.session_state['saved_scenarios']
|
|
|
429 |
|
430 |
column_1, column_2,column_3 = st.columns((6,1,1))
|
431 |
with column_1:
|
432 |
+
st.markdown(f'<span style="font-size:28px"><strong>Selected Scenario:</strong> {selected_scenario}</span>', unsafe_allow_html=True)
|
433 |
+
# st.header(f"Selected Scenario: {selected_scenario}")
|
434 |
# with column_3:
|
435 |
# st.write("")
|
436 |
# st.button('Delete scenario', on_click=delete_scenario)
|
response_curves_model_quality.py
CHANGED
@@ -112,7 +112,7 @@ def data_output(channel,X,y,y_fit_inv,x_ext_data,y_fit_inv_ext):
|
|
112 |
for i in range(len(y_fit_inv_ext)):
|
113 |
y_fit_inv_v2_ext.append(y_fit_inv_ext[i][0])
|
114 |
|
115 |
-
# print(x_ext_data)
|
116 |
ext_df = pd.DataFrame()
|
117 |
ext_df[f'{channel}_Spends'] = x_ext_data
|
118 |
ext_df[fit_col] = y_fit_inv_v2_ext
|
@@ -125,7 +125,7 @@ def data_output(channel,X,y,y_fit_inv,x_ext_data,y_fit_inv_ext):
|
|
125 |
|
126 |
ext_df['MAT'] = ["ext","ext","ext"]
|
127 |
|
128 |
-
# print(ext_df)
|
129 |
plot_df= plot_df.append(ext_df)
|
130 |
return plot_df
|
131 |
|
@@ -148,7 +148,7 @@ def input_data(df,spend_col,prospect_col):
|
|
148 |
return X,y,x_data,y_data,x_minmax,y_minmax
|
149 |
|
150 |
def extend_s_curve(x_max,x_minmax,y_minmax, Kd_fit, n_fit):
|
151 |
-
# print(x_max)
|
152 |
x_ext_data = [x_max*1.2,x_max*1.3,x_max*1.5]
|
153 |
# x_ext_data = [1500000,2000000,2500000]
|
154 |
# x_ext_data = [x_max+100,x_max+200,x_max+5000]
|
@@ -157,7 +157,7 @@ def extend_s_curve(x_max,x_minmax,y_minmax, Kd_fit, n_fit):
|
|
157 |
for i in range(len(x_scaled)):
|
158 |
x_data.append(x_scaled[i][0])
|
159 |
|
160 |
-
# print(x_data)
|
161 |
y_fit = hill_equation(x_data, Kd_fit, n_fit)
|
162 |
y_fit_inv = y_minmax.inverse_transform(np.array(y_fit).reshape(-1,1))
|
163 |
|
@@ -170,8 +170,8 @@ def fit_data(spend_col,prospect_col,channel):
|
|
170 |
|
171 |
X,y,x_data,y_data,x_minmax,y_minmax = input_data(temp_df,spend_col,prospect_col)
|
172 |
y_fit, y_fit_inv, Kd_fit, n_fit = hill_func(x_data,y_data,x_minmax,y_minmax)
|
173 |
-
# print('k: ',Kd_fit)
|
174 |
-
# print('n: ', n_fit)
|
175 |
|
176 |
##### extend_s_curve
|
177 |
x_ext_data,y_fit_inv_ext= extend_s_curve(temp_df[spend_col].max(),x_minmax,y_minmax, Kd_fit, n_fit)
|
@@ -183,7 +183,7 @@ plotly_data = fit_data(spend_cols[0],prospect_cols[0],channel_cols[0])
|
|
183 |
plotly_data.tail()
|
184 |
|
185 |
for i in range(1,13):
|
186 |
-
# print(i)
|
187 |
pdf = fit_data(spend_cols[i],prospect_cols[i],channel_cols[i])
|
188 |
plotly_data = plotly_data.merge(pdf,on = ["Date","MAT"],how = "left")
|
189 |
|
@@ -210,6 +210,8 @@ def response_curves(channel,x_modified,y_modified):
|
|
210 |
))
|
211 |
|
212 |
plotly_data2 = plotly_data.copy()
|
|
|
|
|
213 |
# .dropna(subset=[x_col]).reset_index(inplace = True)
|
214 |
fig.add_trace(go.Scatter(
|
215 |
x=plotly_data[plotly_data2['Date'] == plotly_data2['Date'].max()][x_col],
|
@@ -217,7 +219,7 @@ def response_curves(channel,x_modified,y_modified):
|
|
217 |
mode='markers',
|
218 |
marker=dict(
|
219 |
size=13 # Adjust the size value to make the markers larger or smaller
|
220 |
-
, color = '
|
221 |
),
|
222 |
name="Current Spends"
|
223 |
))
|
@@ -356,7 +358,7 @@ def data_output(channel,X,y,y_fit_inv,x_ext_data,y_fit_inv_ext):
|
|
356 |
for i in range(len(y_fit_inv_ext)):
|
357 |
y_fit_inv_v2_ext.append(y_fit_inv_ext[i][0])
|
358 |
|
359 |
-
# print(x_ext_data)
|
360 |
ext_df = pd.DataFrame()
|
361 |
ext_df[f'{channel}_Spends'] = x_ext_data
|
362 |
ext_df[fit_col] = y_fit_inv_v2_ext
|
@@ -369,7 +371,7 @@ def data_output(channel,X,y,y_fit_inv,x_ext_data,y_fit_inv_ext):
|
|
369 |
|
370 |
ext_df['MAT'] = ["ext","ext","ext"]
|
371 |
|
372 |
-
# print(ext_df)
|
373 |
plot_df= plot_df.append(ext_df)
|
374 |
return plot_df
|
375 |
|
@@ -392,7 +394,7 @@ def input_data(df,spend_col,prospect_col):
|
|
392 |
return X,y,x_data,y_data,x_minmax,y_minmax
|
393 |
|
394 |
def extend_s_curve(x_max,x_minmax,y_minmax, Kd_fit, n_fit):
|
395 |
-
# print(x_max)
|
396 |
x_ext_data = [x_max*1.2,x_max*1.3,x_max*1.5]
|
397 |
# x_ext_data = [1500000,2000000,2500000]
|
398 |
# x_ext_data = [x_max+100,x_max+200,x_max+5000]
|
@@ -401,7 +403,7 @@ def extend_s_curve(x_max,x_minmax,y_minmax, Kd_fit, n_fit):
|
|
401 |
for i in range(len(x_scaled)):
|
402 |
x_data.append(x_scaled[i][0])
|
403 |
|
404 |
-
# print(x_data)
|
405 |
y_fit = hill_equation(x_data, Kd_fit, n_fit)
|
406 |
y_fit_inv = y_minmax.inverse_transform(np.array(y_fit).reshape(-1,1))
|
407 |
|
@@ -414,8 +416,8 @@ def fit_data(spend_col,prospect_col,channel):
|
|
414 |
|
415 |
X,y,x_data,y_data,x_minmax,y_minmax = input_data(temp_df,spend_col,prospect_col)
|
416 |
y_fit, y_fit_inv, Kd_fit, n_fit = hill_func(x_data,y_data,x_minmax,y_minmax)
|
417 |
-
# print('k: ',Kd_fit)
|
418 |
-
# print('n: ', n_fit)
|
419 |
|
420 |
##### extend_s_curve
|
421 |
x_ext_data,y_fit_inv_ext= extend_s_curve(temp_df[spend_col].max(),x_minmax,y_minmax, Kd_fit, n_fit)
|
@@ -427,7 +429,7 @@ plotly_data = fit_data(spend_cols[0],prospect_cols[0],channel_cols[0])
|
|
427 |
plotly_data.tail()
|
428 |
|
429 |
for i in range(1,13):
|
430 |
-
# print(i)
|
431 |
pdf = fit_data(spend_cols[i],prospect_cols[i],channel_cols[i])
|
432 |
plotly_data = plotly_data.merge(pdf,on = ["Date","MAT"],how = "left")
|
433 |
|
@@ -455,10 +457,11 @@ def response_curves(channel,x_modified,y_modified):
|
|
455 |
))
|
456 |
|
457 |
plotly_data2 = plotly_data.copy()
|
|
|
458 |
# .dropna(subset=[x_col]).reset_index(inplace = True)
|
459 |
fig.add_trace(go.Scatter(
|
460 |
-
x=
|
461 |
-
y=
|
462 |
mode='markers',
|
463 |
marker=dict(
|
464 |
size=13 # Adjust the size value to make the markers larger or smaller
|
|
|
112 |
for i in range(len(y_fit_inv_ext)):
|
113 |
y_fit_inv_v2_ext.append(y_fit_inv_ext[i][0])
|
114 |
|
115 |
+
# # print(x_ext_data)
|
116 |
ext_df = pd.DataFrame()
|
117 |
ext_df[f'{channel}_Spends'] = x_ext_data
|
118 |
ext_df[fit_col] = y_fit_inv_v2_ext
|
|
|
125 |
|
126 |
ext_df['MAT'] = ["ext","ext","ext"]
|
127 |
|
128 |
+
# # print(ext_df)
|
129 |
plot_df= plot_df.append(ext_df)
|
130 |
return plot_df
|
131 |
|
|
|
148 |
return X,y,x_data,y_data,x_minmax,y_minmax
|
149 |
|
150 |
def extend_s_curve(x_max,x_minmax,y_minmax, Kd_fit, n_fit):
|
151 |
+
# # print(x_max)
|
152 |
x_ext_data = [x_max*1.2,x_max*1.3,x_max*1.5]
|
153 |
# x_ext_data = [1500000,2000000,2500000]
|
154 |
# x_ext_data = [x_max+100,x_max+200,x_max+5000]
|
|
|
157 |
for i in range(len(x_scaled)):
|
158 |
x_data.append(x_scaled[i][0])
|
159 |
|
160 |
+
# # print(x_data)
|
161 |
y_fit = hill_equation(x_data, Kd_fit, n_fit)
|
162 |
y_fit_inv = y_minmax.inverse_transform(np.array(y_fit).reshape(-1,1))
|
163 |
|
|
|
170 |
|
171 |
X,y,x_data,y_data,x_minmax,y_minmax = input_data(temp_df,spend_col,prospect_col)
|
172 |
y_fit, y_fit_inv, Kd_fit, n_fit = hill_func(x_data,y_data,x_minmax,y_minmax)
|
173 |
+
# # print('k: ',Kd_fit)
|
174 |
+
# # print('n: ', n_fit)
|
175 |
|
176 |
##### extend_s_curve
|
177 |
x_ext_data,y_fit_inv_ext= extend_s_curve(temp_df[spend_col].max(),x_minmax,y_minmax, Kd_fit, n_fit)
|
|
|
183 |
plotly_data.tail()
|
184 |
|
185 |
for i in range(1,13):
|
186 |
+
# # print(i)
|
187 |
pdf = fit_data(spend_cols[i],prospect_cols[i],channel_cols[i])
|
188 |
plotly_data = plotly_data.merge(pdf,on = ["Date","MAT"],how = "left")
|
189 |
|
|
|
210 |
))
|
211 |
|
212 |
plotly_data2 = plotly_data.copy()
|
213 |
+
plotly_data2 = plotly_data[plotly_data[x_col].isnull()==False]
|
214 |
+
print(plotly_data[plotly_data2['Date'] == plotly_data2['Date'].max()][x_col])
|
215 |
# .dropna(subset=[x_col]).reset_index(inplace = True)
|
216 |
fig.add_trace(go.Scatter(
|
217 |
x=plotly_data[plotly_data2['Date'] == plotly_data2['Date'].max()][x_col],
|
|
|
219 |
mode='markers',
|
220 |
marker=dict(
|
221 |
size=13 # Adjust the size value to make the markers larger or smaller
|
222 |
+
, color = 'yellow'
|
223 |
),
|
224 |
name="Current Spends"
|
225 |
))
|
|
|
358 |
for i in range(len(y_fit_inv_ext)):
|
359 |
y_fit_inv_v2_ext.append(y_fit_inv_ext[i][0])
|
360 |
|
361 |
+
# # print(x_ext_data)
|
362 |
ext_df = pd.DataFrame()
|
363 |
ext_df[f'{channel}_Spends'] = x_ext_data
|
364 |
ext_df[fit_col] = y_fit_inv_v2_ext
|
|
|
371 |
|
372 |
ext_df['MAT'] = ["ext","ext","ext"]
|
373 |
|
374 |
+
# # print(ext_df)
|
375 |
plot_df= plot_df.append(ext_df)
|
376 |
return plot_df
|
377 |
|
|
|
394 |
return X,y,x_data,y_data,x_minmax,y_minmax
|
395 |
|
396 |
def extend_s_curve(x_max,x_minmax,y_minmax, Kd_fit, n_fit):
|
397 |
+
# # print(x_max)
|
398 |
x_ext_data = [x_max*1.2,x_max*1.3,x_max*1.5]
|
399 |
# x_ext_data = [1500000,2000000,2500000]
|
400 |
# x_ext_data = [x_max+100,x_max+200,x_max+5000]
|
|
|
403 |
for i in range(len(x_scaled)):
|
404 |
x_data.append(x_scaled[i][0])
|
405 |
|
406 |
+
# # print(x_data)
|
407 |
y_fit = hill_equation(x_data, Kd_fit, n_fit)
|
408 |
y_fit_inv = y_minmax.inverse_transform(np.array(y_fit).reshape(-1,1))
|
409 |
|
|
|
416 |
|
417 |
X,y,x_data,y_data,x_minmax,y_minmax = input_data(temp_df,spend_col,prospect_col)
|
418 |
y_fit, y_fit_inv, Kd_fit, n_fit = hill_func(x_data,y_data,x_minmax,y_minmax)
|
419 |
+
# # print('k: ',Kd_fit)
|
420 |
+
# # print('n: ', n_fit)
|
421 |
|
422 |
##### extend_s_curve
|
423 |
x_ext_data,y_fit_inv_ext= extend_s_curve(temp_df[spend_col].max(),x_minmax,y_minmax, Kd_fit, n_fit)
|
|
|
429 |
plotly_data.tail()
|
430 |
|
431 |
for i in range(1,13):
|
432 |
+
# # print(i)
|
433 |
pdf = fit_data(spend_cols[i],prospect_cols[i],channel_cols[i])
|
434 |
plotly_data = plotly_data.merge(pdf,on = ["Date","MAT"],how = "left")
|
435 |
|
|
|
457 |
))
|
458 |
|
459 |
plotly_data2 = plotly_data.copy()
|
460 |
+
plotly_data2 = plotly_data[plotly_data[x_col].isnull()==False]
|
461 |
# .dropna(subset=[x_col]).reset_index(inplace = True)
|
462 |
fig.add_trace(go.Scatter(
|
463 |
+
x=plotly_data2[plotly_data2['Date'] == plotly_data2['Date'].max()][x_col],
|
464 |
+
y=plotly_data2[plotly_data2['Date'] == plotly_data2['Date'].max()][y_col],
|
465 |
mode='markers',
|
466 |
marker=dict(
|
467 |
size=13 # Adjust the size value to make the markers larger or smaller
|
response_curves_model_quality_base.py
CHANGED
@@ -111,7 +111,7 @@ def data_output(channel,X,y,y_fit_inv,x_ext_data,y_fit_inv_ext):
|
|
111 |
for i in range(len(y_fit_inv_ext)):
|
112 |
y_fit_inv_v2_ext.append(y_fit_inv_ext[i][0])
|
113 |
|
114 |
-
# print(x_ext_data)
|
115 |
ext_df = pd.DataFrame()
|
116 |
ext_df[f'{channel}_Spends'] = x_ext_data
|
117 |
ext_df[f'{channel}_Prospects'] = y_fit_inv_v2_ext
|
@@ -125,7 +125,7 @@ def data_output(channel,X,y,y_fit_inv,x_ext_data,y_fit_inv_ext):
|
|
125 |
|
126 |
ext_df['MAT'] = ["ext","ext","ext"]
|
127 |
|
128 |
-
# print(ext_df.columns)
|
129 |
plot_df= plot_df.append(ext_df)
|
130 |
return plot_df
|
131 |
|
@@ -148,7 +148,7 @@ def input_data(df,spend_col,prospect_col):
|
|
148 |
return X,y,x_data,y_data,x_minmax,y_minmax
|
149 |
|
150 |
def extend_s_curve(x_max,x_minmax,y_minmax, Kd_fit, n_fit):
|
151 |
-
# print(x_max)
|
152 |
x_ext_data = [x_max*1.2,x_max*1.3,x_max*1.5]
|
153 |
# x_ext_data = [1500000,2000000,2500000]
|
154 |
# x_ext_data = [x_max+100,x_max+200,x_max+5000]
|
@@ -157,7 +157,7 @@ def extend_s_curve(x_max,x_minmax,y_minmax, Kd_fit, n_fit):
|
|
157 |
for i in range(len(x_scaled)):
|
158 |
x_data.append(x_scaled[i][0])
|
159 |
|
160 |
-
# print(x_data)
|
161 |
y_fit = hill_equation(x_data, Kd_fit, n_fit)
|
162 |
y_fit_inv = y_minmax.inverse_transform(np.array(y_fit).reshape(-1,1))
|
163 |
|
@@ -170,8 +170,8 @@ def fit_data(spend_col,prospect_col,channel):
|
|
170 |
|
171 |
X,y,x_data,y_data,x_minmax,y_minmax = input_data(temp_df,spend_col,prospect_col)
|
172 |
y_fit, y_fit_inv, Kd_fit, n_fit = hill_func(x_data,y_data,x_minmax,y_minmax)
|
173 |
-
# print('k: ',Kd_fit)
|
174 |
-
# print('n: ', n_fit)
|
175 |
|
176 |
##### extend_s_curve
|
177 |
x_ext_data,y_fit_inv_ext= extend_s_curve(temp_df[spend_col].max(),x_minmax,y_minmax, Kd_fit, n_fit)
|
@@ -183,7 +183,7 @@ plotly_data = fit_data(spend_cols[0],prospect_cols[0],channel_cols[0])
|
|
183 |
plotly_data.tail()
|
184 |
|
185 |
for i in range(1,13):
|
186 |
-
print(i)
|
187 |
pdf = fit_data(spend_cols[i],prospect_cols[i],channel_cols[i])
|
188 |
plotly_data = plotly_data.merge(pdf,on = ["Date","MAT"],how = "left")
|
189 |
|
|
|
111 |
for i in range(len(y_fit_inv_ext)):
|
112 |
y_fit_inv_v2_ext.append(y_fit_inv_ext[i][0])
|
113 |
|
114 |
+
# # print(x_ext_data)
|
115 |
ext_df = pd.DataFrame()
|
116 |
ext_df[f'{channel}_Spends'] = x_ext_data
|
117 |
ext_df[f'{channel}_Prospects'] = y_fit_inv_v2_ext
|
|
|
125 |
|
126 |
ext_df['MAT'] = ["ext","ext","ext"]
|
127 |
|
128 |
+
# # print(ext_df.columns)
|
129 |
plot_df= plot_df.append(ext_df)
|
130 |
return plot_df
|
131 |
|
|
|
148 |
return X,y,x_data,y_data,x_minmax,y_minmax
|
149 |
|
150 |
def extend_s_curve(x_max,x_minmax,y_minmax, Kd_fit, n_fit):
|
151 |
+
# # print(x_max)
|
152 |
x_ext_data = [x_max*1.2,x_max*1.3,x_max*1.5]
|
153 |
# x_ext_data = [1500000,2000000,2500000]
|
154 |
# x_ext_data = [x_max+100,x_max+200,x_max+5000]
|
|
|
157 |
for i in range(len(x_scaled)):
|
158 |
x_data.append(x_scaled[i][0])
|
159 |
|
160 |
+
# # print(x_data)
|
161 |
y_fit = hill_equation(x_data, Kd_fit, n_fit)
|
162 |
y_fit_inv = y_minmax.inverse_transform(np.array(y_fit).reshape(-1,1))
|
163 |
|
|
|
170 |
|
171 |
X,y,x_data,y_data,x_minmax,y_minmax = input_data(temp_df,spend_col,prospect_col)
|
172 |
y_fit, y_fit_inv, Kd_fit, n_fit = hill_func(x_data,y_data,x_minmax,y_minmax)
|
173 |
+
# # print('k: ',Kd_fit)
|
174 |
+
# # print('n: ', n_fit)
|
175 |
|
176 |
##### extend_s_curve
|
177 |
x_ext_data,y_fit_inv_ext= extend_s_curve(temp_df[spend_col].max(),x_minmax,y_minmax, Kd_fit, n_fit)
|
|
|
183 |
plotly_data.tail()
|
184 |
|
185 |
for i in range(1,13):
|
186 |
+
# print(i)
|
187 |
pdf = fit_data(spend_cols[i],prospect_cols[i],channel_cols[i])
|
188 |
plotly_data = plotly_data.merge(pdf,on = ["Date","MAT"],how = "left")
|
189 |
|
response_curves_parameters.xlsx
CHANGED
Binary files a/response_curves_parameters.xlsx and b/response_curves_parameters.xlsx differ
|
|
summary_df.pkl
CHANGED
@@ -1,3 +1,3 @@
|
|
1 |
version https://git-lfs.github.com/spec/v1
|
2 |
-
oid sha256:
|
3 |
size 1822
|
|
|
1 |
version https://git-lfs.github.com/spec/v1
|
2 |
+
oid sha256:6828b9886464f55ba02eb0b7cd0f315e46f06c8ba520c041294ec6ff7d426965
|
3 |
size 1822
|
utilities.py
CHANGED
@@ -206,12 +206,12 @@ def panel_level(input_df, date_column="Date"):
|
|
206 |
|
207 |
|
208 |
def initialize_data(
|
209 |
-
panel=None,
|
210 |
):
|
211 |
# uopx_conv_rates = {'streaming_impressions' : 0.007,'digital_impressions' : 0.007,'search_clicks' : 0.00719,'tv_impressions' : 0.000173,
|
212 |
# "digital_clicks":0.005,"streaming_clicks":0.004,'streaming_spends':1,"tv_spends":1,"search_spends":1,
|
213 |
# "digital_spends":1}
|
214 |
-
# print('State initialized')
|
215 |
|
216 |
excel = pd.read_excel(target_file, sheet_name=None)
|
217 |
|
@@ -305,15 +305,16 @@ def initialize_data(
|
|
305 |
if updated_rcs is not None and updated_rcs_key in list(updated_rcs.keys()):
|
306 |
response_curves[inp_col] = updated_rcs[updated_rcs_key]
|
307 |
|
|
|
308 |
## conversion rates
|
309 |
spend_col = [
|
310 |
_col
|
311 |
for _col in spend_df.columns
|
312 |
if _col.startswith(inp_col.rsplit("_", 1)[0])
|
313 |
][0]
|
314 |
-
|
315 |
-
# print('
|
316 |
-
# print(spend_col)
|
317 |
conv = (
|
318 |
spend_df.set_index("Week")[spend_col]
|
319 |
/ input_df.set_index("Date")[inp_col].clip(lower=1)
|
@@ -323,9 +324,10 @@ def initialize_data(
|
|
323 |
conv_rates[inp_col] = list(conv.drop("Week", axis=1).mean().to_dict().values())[
|
324 |
0
|
325 |
]
|
326 |
-
|
|
|
327 |
# conv_rates[inp_col] = uopx_conv_rates[inp_col]
|
328 |
-
|
329 |
|
330 |
channel = Channel(
|
331 |
name=inp_col,
|
@@ -352,12 +354,15 @@ def initialize_data(
|
|
352 |
sales = channel.actual_sales
|
353 |
else:
|
354 |
sales += channel.actual_sales
|
|
|
355 |
other_contributions = (
|
356 |
output_df.drop([*output_cols], axis=1).sum(axis=1, numeric_only=True).values
|
357 |
)
|
358 |
correction = output_df.drop("Date", axis=1).sum(axis=1).values - (
|
359 |
sales + other_contributions
|
360 |
)
|
|
|
|
|
361 |
scenario = Scenario(
|
362 |
name="default",
|
363 |
channels=channels,
|
@@ -400,6 +405,10 @@ def initialize_data(
|
|
400 |
channel_name: False for channel_name in channel_list
|
401 |
}
|
402 |
st.session_state["disable_download_button"] = True
|
|
|
|
|
|
|
|
|
403 |
|
404 |
|
405 |
def create_channel_summary(scenario):
|
@@ -700,7 +709,7 @@ def create_channel_spends_sales_plot(channel):
|
|
700 |
df = raw_df.sort_values(by="Date")
|
701 |
x = df.Date
|
702 |
scenario = class_from_dict(st.session_state["default_scenario_dict"])
|
703 |
-
_sales = scenario.constant + scenario.correction
|
704 |
channel_sales_spends_fig = make_subplots(specs=[[{"secondary_y": True}]])
|
705 |
channel_sales_spends_fig.add_trace(
|
706 |
go.Bar(
|
|
|
206 |
|
207 |
|
208 |
def initialize_data(
|
209 |
+
target_file, panel=None, updated_rcs=None, metrics=None
|
210 |
):
|
211 |
# uopx_conv_rates = {'streaming_impressions' : 0.007,'digital_impressions' : 0.007,'search_clicks' : 0.00719,'tv_impressions' : 0.000173,
|
212 |
# "digital_clicks":0.005,"streaming_clicks":0.004,'streaming_spends':1,"tv_spends":1,"search_spends":1,
|
213 |
# "digital_spends":1}
|
214 |
+
# # print('State initialized')
|
215 |
|
216 |
excel = pd.read_excel(target_file, sheet_name=None)
|
217 |
|
|
|
305 |
if updated_rcs is not None and updated_rcs_key in list(updated_rcs.keys()):
|
306 |
response_curves[inp_col] = updated_rcs[updated_rcs_key]
|
307 |
|
308 |
+
# # print(response_curves)
|
309 |
## conversion rates
|
310 |
spend_col = [
|
311 |
_col
|
312 |
for _col in spend_df.columns
|
313 |
if _col.startswith(inp_col.rsplit("_", 1)[0])
|
314 |
][0]
|
315 |
+
# # print(spend_col)
|
316 |
+
# # print('## printing spendssss')
|
317 |
+
# # print(spend_col)
|
318 |
conv = (
|
319 |
spend_df.set_index("Week")[spend_col]
|
320 |
/ input_df.set_index("Date")[inp_col].clip(lower=1)
|
|
|
324 |
conv_rates[inp_col] = list(conv.drop("Week", axis=1).mean().to_dict().values())[
|
325 |
0
|
326 |
]
|
327 |
+
# # print(conv_rates)
|
328 |
+
### print('Before',conv_rates[inp_col])
|
329 |
# conv_rates[inp_col] = uopx_conv_rates[inp_col]
|
330 |
+
### print('After',(conv_rates[inp_col]))
|
331 |
|
332 |
channel = Channel(
|
333 |
name=inp_col,
|
|
|
354 |
sales = channel.actual_sales
|
355 |
else:
|
356 |
sales += channel.actual_sales
|
357 |
+
# # print(actual_output_dic)
|
358 |
other_contributions = (
|
359 |
output_df.drop([*output_cols], axis=1).sum(axis=1, numeric_only=True).values
|
360 |
)
|
361 |
correction = output_df.drop("Date", axis=1).sum(axis=1).values - (
|
362 |
sales + other_contributions
|
363 |
)
|
364 |
+
# # print(other_contributions)
|
365 |
+
# # print(correction)
|
366 |
scenario = Scenario(
|
367 |
name="default",
|
368 |
channels=channels,
|
|
|
405 |
channel_name: False for channel_name in channel_list
|
406 |
}
|
407 |
st.session_state["disable_download_button"] = True
|
408 |
+
# if target_file == :
|
409 |
+
# st.session_state["dividing_parameter"] =
|
410 |
+
# else :
|
411 |
+
|
412 |
|
413 |
|
414 |
def create_channel_summary(scenario):
|
|
|
709 |
df = raw_df.sort_values(by="Date")
|
710 |
x = df.Date
|
711 |
scenario = class_from_dict(st.session_state["default_scenario_dict"])
|
712 |
+
_sales = 0 #scenario.constant + scenario.correction
|
713 |
channel_sales_spends_fig = make_subplots(specs=[[{"secondary_y": True}]])
|
714 |
channel_sales_spends_fig.add_trace(
|
715 |
go.Bar(
|
utilities_with_panel.py
CHANGED
@@ -98,7 +98,7 @@ DATA_PATH = './data'
|
|
98 |
|
99 |
IMAGES_PATH = './data/images_224_224'
|
100 |
|
101 |
-
# New -
|
102 |
if 'bin_dict' not in st.session_state:
|
103 |
|
104 |
with open("data_import.pkl", "rb") as f:
|
@@ -395,7 +395,7 @@ def initialize_data(target_col,selected_markets):
|
|
395 |
# uopx_conv_rates = {'streaming_impressions' : 0.007,'digital_impressions' : 0.007,'search_clicks' : 0.00719,'tv_impressions' : 0.000173,
|
396 |
# "digital_clicks":0.005,"streaming_clicks":0.004,'streaming_spends':1,"tv_spends":1,"search_spends":1,
|
397 |
# "digital_spends":1}
|
398 |
-
|
399 |
# excel = pd.read_excel("data_test_overview_panel.xlsx",sheet_name=None)
|
400 |
#excel = pd.read_excel("Overview_data_test_panel@#revenue.xlsx" + target_col + ".xlsx",sheet_name=None)
|
401 |
|
@@ -469,7 +469,7 @@ def initialize_data(target_col,selected_markets):
|
|
469 |
for inp_col in channel_list:
|
470 |
#st.write(inp_col)
|
471 |
|
472 |
-
# # New -
|
473 |
# if is_panel:
|
474 |
# input_df1 = input_df.groupby([date_col]).agg({inp_col:'sum'}).reset_index() # aggregate spends on date
|
475 |
# spends = input_df1[inp_col].values
|
@@ -484,7 +484,7 @@ def initialize_data(target_col,selected_markets):
|
|
484 |
|
485 |
|
486 |
# contribution
|
487 |
-
# New -
|
488 |
out_col = [_col for _col in output_df.columns if _col.startswith(inp_col)][0]
|
489 |
if is_panel :
|
490 |
output_df1 = output_df.groupby([date_col]).agg({out_col:'sum'}).reset_index()
|
@@ -505,12 +505,12 @@ def initialize_data(target_col,selected_markets):
|
|
505 |
|
506 |
x = x.astype('float64')
|
507 |
y = y.astype('float64')
|
508 |
-
|
509 |
-
|
510 |
-
|
511 |
-
|
512 |
# st.write(y.max(),x.max())
|
513 |
-
print(y.max(),x.max())
|
514 |
if y.max()<=0.01:
|
515 |
if x.max()<=0.01 :
|
516 |
st.write("here-here")
|
@@ -539,15 +539,15 @@ def initialize_data(target_col,selected_markets):
|
|
539 |
## conversion rates
|
540 |
spend_col = [_col for _col in spend_df.columns if _col.startswith(inp_col.rsplit('_',1)[0])][0]
|
541 |
|
542 |
-
|
543 |
-
|
544 |
conv = (spend_df.set_index('Week')[spend_col] / input_df.set_index('Date')[inp_col].clip(lower=1)).reset_index()
|
545 |
conv.rename(columns={'index':'Week'},inplace=True)
|
546 |
conv['year'] = conv.Week.dt.year
|
547 |
conv_rates[inp_col] = list(conv.drop('Week',axis=1).mean().to_dict().values())[0]
|
548 |
-
|
549 |
# conv_rates[inp_col] = uopx_conv_rates[inp_col]
|
550 |
-
|
551 |
|
552 |
|
553 |
channel = Channel(name=inp_col,dates=dates,
|
@@ -617,7 +617,7 @@ def initialize_data(target_col,selected_markets):
|
|
617 |
# channel_list = []
|
618 |
# for col in raw_df.columns:
|
619 |
# if 'click' in col.lower() or 'spend' in col.lower() or 'imp' in col.lower():
|
620 |
-
#
|
621 |
# channel_list.append(col)
|
622 |
# else:
|
623 |
# pass
|
@@ -708,8 +708,8 @@ def create_channel_summary(scenario):
|
|
708 |
if name_mod.lower().endswith(' imp'):
|
709 |
name_mod = name_mod.replace('Imp', ' Impressions')
|
710 |
|
711 |
-
print(name_mod, channel.actual_total_spends, channel.conversion_rate,
|
712 |
-
|
713 |
|
714 |
summary_columns.append(name_mod)
|
715 |
|
|
|
98 |
|
99 |
IMAGES_PATH = './data/images_224_224'
|
100 |
|
101 |
+
# New - S# print 2
|
102 |
if 'bin_dict' not in st.session_state:
|
103 |
|
104 |
with open("data_import.pkl", "rb") as f:
|
|
|
395 |
# uopx_conv_rates = {'streaming_impressions' : 0.007,'digital_impressions' : 0.007,'search_clicks' : 0.00719,'tv_impressions' : 0.000173,
|
396 |
# "digital_clicks":0.005,"streaming_clicks":0.004,'streaming_spends':1,"tv_spends":1,"search_spends":1,
|
397 |
# "digital_spends":1}
|
398 |
+
## print('State initialized')
|
399 |
# excel = pd.read_excel("data_test_overview_panel.xlsx",sheet_name=None)
|
400 |
#excel = pd.read_excel("Overview_data_test_panel@#revenue.xlsx" + target_col + ".xlsx",sheet_name=None)
|
401 |
|
|
|
469 |
for inp_col in channel_list:
|
470 |
#st.write(inp_col)
|
471 |
|
472 |
+
# # New - S# print 2
|
473 |
# if is_panel:
|
474 |
# input_df1 = input_df.groupby([date_col]).agg({inp_col:'sum'}).reset_index() # aggregate spends on date
|
475 |
# spends = input_df1[inp_col].values
|
|
|
484 |
|
485 |
|
486 |
# contribution
|
487 |
+
# New - S# print 2
|
488 |
out_col = [_col for _col in output_df.columns if _col.startswith(inp_col)][0]
|
489 |
if is_panel :
|
490 |
output_df1 = output_df.groupby([date_col]).agg({out_col:'sum'}).reset_index()
|
|
|
505 |
|
506 |
x = x.astype('float64')
|
507 |
y = y.astype('float64')
|
508 |
+
## print('## printing yyyyyyyyy')
|
509 |
+
## print(inp_col)
|
510 |
+
## print(x.max())
|
511 |
+
## print(y.max())
|
512 |
# st.write(y.max(),x.max())
|
513 |
+
# print(y.max(),x.max())
|
514 |
if y.max()<=0.01:
|
515 |
if x.max()<=0.01 :
|
516 |
st.write("here-here")
|
|
|
539 |
## conversion rates
|
540 |
spend_col = [_col for _col in spend_df.columns if _col.startswith(inp_col.rsplit('_',1)[0])][0]
|
541 |
|
542 |
+
## print('## printing spendssss')
|
543 |
+
## print(spend_col)
|
544 |
conv = (spend_df.set_index('Week')[spend_col] / input_df.set_index('Date')[inp_col].clip(lower=1)).reset_index()
|
545 |
conv.rename(columns={'index':'Week'},inplace=True)
|
546 |
conv['year'] = conv.Week.dt.year
|
547 |
conv_rates[inp_col] = list(conv.drop('Week',axis=1).mean().to_dict().values())[0]
|
548 |
+
### print('Before',conv_rates[inp_col])
|
549 |
# conv_rates[inp_col] = uopx_conv_rates[inp_col]
|
550 |
+
### print('After',(conv_rates[inp_col]))
|
551 |
|
552 |
|
553 |
channel = Channel(name=inp_col,dates=dates,
|
|
|
617 |
# channel_list = []
|
618 |
# for col in raw_df.columns:
|
619 |
# if 'click' in col.lower() or 'spend' in col.lower() or 'imp' in col.lower():
|
620 |
+
# ### print(col)
|
621 |
# channel_list.append(col)
|
622 |
# else:
|
623 |
# pass
|
|
|
708 |
if name_mod.lower().endswith(' imp'):
|
709 |
name_mod = name_mod.replace('Imp', ' Impressions')
|
710 |
|
711 |
+
# print(name_mod, channel.actual_total_spends, channel.conversion_rate,
|
712 |
+
channel.actual_total_spends * channel.conversion_rate
|
713 |
|
714 |
summary_columns.append(name_mod)
|
715 |
|