itheenigma commited on
Commit
7d3e93d
·
1 Parent(s): 4062d22

fixed code to get marginal cpc curve to start from origin and moved graphs to show cpc even when breakeven is not reached

Browse files
Files changed (1) hide show
  1. marginal_cpc_calculator.py +40 -28
marginal_cpc_calculator.py CHANGED
@@ -6,8 +6,10 @@ import pandas as pd
6
  def hello():
7
  print ("world!")
8
 
9
- def polynomial_func(x, a,b,c,d):
10
- y = a * x - b * x**2 + c * x**3 + d
 
 
11
  return y
12
 
13
  def get_country_metrics(country,min_date='2023-07-01',max_date='2023-09-01'):
@@ -73,14 +75,18 @@ def calculate_max_spend(df,min_date,max_date,
73
 
74
  try:
75
  output_msg=[]
76
- plt.style.use('ggplot')
77
  fig = plt.figure(figsize=(18,6))
78
 
79
- params, cv = curve_fit(polynomial_func, df_temp['cum_cost'],df_temp['marginal_income'].fillna(0), p0=(1, 1,1,1))
80
- a,b,c,d = params
 
 
 
81
 
82
  # determine quality of the fit
83
- squaredDiffs = np.square(df_temp['marginal_income'].fillna(0) - polynomial_func(df_temp['cum_cost'], a,b,c,d))
 
84
  squaredDiffsFromMean = np.square(df_temp['marginal_income'].fillna(0) - np.mean(df_temp['marginal_income'].fillna(0)))
85
  rSquared = 1 - np.sum(squaredDiffs) / np.sum(squaredDiffsFromMean)
86
 
@@ -90,12 +96,16 @@ def calculate_max_spend(df,min_date,max_date,
90
 
91
  # inspect the parameters
92
  if pprint==True:
93
- output_msg.append(f"Marginal income equation Y = {a} * x - {b} * x^2 + {c} * x^3 + {d}")
 
94
 
95
  # calculate max costs when it becomes negative ROAS
 
 
 
96
  df_marginal = pd.DataFrame(zip(np.arange(500000),
97
- polynomial_func(np.arange(500000), a,b,c,d)
98
- )).rename(columns={0:'cumulative_cost',1:'marginal_income'})
99
  # join actuals to get the full picture
100
  _ = df_temp[['cost','cpc','cum_cost', 'cum_clicks', 'cum_cpc', 'cum_revenue', 'cum_income']]
101
  # converting cost to integer in order to join with the marginal dataset
@@ -136,32 +146,34 @@ def calculate_max_spend(df,min_date,max_date,
136
  output_msg.append(f"For this spend, marginal_cpc={marginal_cpc_HAS}, cumulative_clicks={cum_clicks_HAS}, Average_cpc={cum_cpc_HAS}, cumulative_revenue={cum_revenue_HAS}")
137
  output_msg.append(f"Total amount spent in negative ROAS={total_negative_roas_spend}")
138
  # print (output_msg)
139
- try:
140
- ax1 = fig.add_subplot(121);
141
- plt.scatter(df_temp['cum_cost'],df_temp['cpc']);
142
- plt.axhline(1*cvr*aov,color='black',linestyle='--');plt.axhline(1*cvr*aov*pc,color='blue',linestyle='--');
143
- plt.annotate(f'Any clicks above {np.round(cvr*aov,2)} SEK cpc has negative ROAS \n Above {np.round(cvr*aov*pc,2)} SEK is negative PC',size=12,xy=[0,40], color="black")
144
- plt.xlabel('cumulative cost'); plt.ylabel('cpc')
145
- # ax2.axes.get_xaxis().set_visible(False)
146
- ax1.title.set_text('CPC for at different spend levels');
147
- except:
148
- pass
149
- try:
150
- ax2 = fig.add_subplot(122)
151
- plt.plot(df_temp['cum_cost'],df_temp['marginal_income'], '.', label="data")
152
- plt.plot(df_temp['cum_cost'], polynomial_func(df_temp['cum_cost'], a,b,c,d), '--', color='blue', label="fitted")
153
- plt.xlabel('cumulative cost'); plt.ylabel('marginal income')
154
- ax2.title.set_text('Net income at different spend levels')
155
- except:
156
- pass
157
  else:
158
  marginal_cpc,cum_clicks,cum_cpc,cum_revenue = np.nan, np.nan, np.nan, np.nan
159
  total_negative_roas_spend=np.nan
160
  if pprint==True:
 
161
  print (f"Not enough data for mCPC analysis. Max threshold resulted in {max_spend_threshold}. Highest amount spent during this period is: {highest_amount_spent}")
162
- # return df_marginal
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
163
  values = (max_spend_threshold,highest_amount_spent,total_negative_roas_spend,marginal_cpc,cum_clicks,cum_cpc,cum_revenue,rSquared)
164
  return fig,output_msg,values
 
165
 
166
  def loop_mCPC_countries(df,min_date,max_date,
167
  country_list=['UK', 'DE', 'US', 'NL', 'SE', 'CH', 'BE', 'EU', 'FR', 'AU'],
 
6
  def hello():
7
  print ("world!")
8
 
9
+ # def polynomial_func(x, a,b,c,d):
10
+ # y = a * x - b * x**2 + c * x**3 + d
11
+ def polynomial_func(x, a,b,c):
12
+ y = a * x - b * x**2 + c * x**3
13
  return y
14
 
15
  def get_country_metrics(country,min_date='2023-07-01',max_date='2023-09-01'):
 
75
 
76
  try:
77
  output_msg=[]
78
+ plt.style.use('fivethirtyeight')
79
  fig = plt.figure(figsize=(18,6))
80
 
81
+ # params, cv = curve_fit(polynomial_func, df_temp['cum_cost'],df_temp['marginal_income'].fillna(0), p0=(1, 1,1,1))
82
+ # a,b,c,d = params
83
+ params, cv = curve_fit(polynomial_func, df_temp['cum_cost'],df_temp['marginal_income'].fillna(0), p0=(1, 1,1))
84
+ a,b,c = params
85
+
86
 
87
  # determine quality of the fit
88
+ # squaredDiffs = np.square(df_temp['marginal_income'].fillna(0) - polynomial_func(df_temp['cum_cost'], a,b,c,d))
89
+ squaredDiffs = np.square(df_temp['marginal_income'].fillna(0) - polynomial_func(df_temp['cum_cost'], a,b,c))
90
  squaredDiffsFromMean = np.square(df_temp['marginal_income'].fillna(0) - np.mean(df_temp['marginal_income'].fillna(0)))
91
  rSquared = 1 - np.sum(squaredDiffs) / np.sum(squaredDiffsFromMean)
92
 
 
96
 
97
  # inspect the parameters
98
  if pprint==True:
99
+ # output_msg.append(f"Marginal income equation Y = {a} * x - {b} * x^2 + {c} * x^3 + {d}")
100
+ output_msg.append(f"Marginal income equation Y = {a} * x - {b} * x^2 + {c} * x^3")
101
 
102
  # calculate max costs when it becomes negative ROAS
103
+ # df_marginal = pd.DataFrame(zip(np.arange(500000),
104
+ # polynomial_func(np.arange(500000), a,b,c,d)
105
+ # )).rename(columns={0:'cumulative_cost',1:'marginal_income'})
106
  df_marginal = pd.DataFrame(zip(np.arange(500000),
107
+ polynomial_func(np.arange(500000), a,b,c)
108
+ )).rename(columns={0:'cumulative_cost',1:'marginal_income'})
109
  # join actuals to get the full picture
110
  _ = df_temp[['cost','cpc','cum_cost', 'cum_clicks', 'cum_cpc', 'cum_revenue', 'cum_income']]
111
  # converting cost to integer in order to join with the marginal dataset
 
146
  output_msg.append(f"For this spend, marginal_cpc={marginal_cpc_HAS}, cumulative_clicks={cum_clicks_HAS}, Average_cpc={cum_cpc_HAS}, cumulative_revenue={cum_revenue_HAS}")
147
  output_msg.append(f"Total amount spent in negative ROAS={total_negative_roas_spend}")
148
  # print (output_msg)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
149
  else:
150
  marginal_cpc,cum_clicks,cum_cpc,cum_revenue = np.nan, np.nan, np.nan, np.nan
151
  total_negative_roas_spend=np.nan
152
  if pprint==True:
153
+ output_msg.append(f"Not enough data for mCPC analysis. Max threshold resulted in {max_spend_threshold}. Highest amount spent during this period is: {highest_amount_spent}")
154
  print (f"Not enough data for mCPC analysis. Max threshold resulted in {max_spend_threshold}. Highest amount spent during this period is: {highest_amount_spent}")
155
+ try:
156
+ ax1 = fig.add_subplot(121);
157
+ plt.scatter(df_temp['cum_cost'],df_temp['cpc'],color='black');
158
+ plt.axhline(1*cvr*aov,color='red',linestyle='--');plt.axhline(1*cvr*aov*pc,color='blue',linestyle='--');
159
+ plt.annotate(f'Any clicks above {np.round(cvr*aov,2)} SEK cpc has negative ROAS \n Above {np.round(cvr*aov*pc,2)} SEK is negative PC',size=12,xy=[0,40], color="black")
160
+ plt.xlabel('Cumulative ad spend that month (in SEK)'); plt.ylabel('Cost per individual click (in SEK)')
161
+ # ax2.axes.get_xaxis().set_visible(False)
162
+ ax1.title.set_text('CPC for at different spend levels');
163
+ except:
164
+ pass
165
+ try:
166
+ ax2 = fig.add_subplot(122)
167
+ plt.plot(df_temp['cum_cost'],df_temp['marginal_income'], '.', label="data", color='r')
168
+ # plt.plot(df_temp['cum_cost'], polynomial_func(df_temp['cum_cost'], a,b,c,d), '--', color='blue', label="fitted")
169
+ plt.plot(df_temp['cum_cost'], polynomial_func(df_temp['cum_cost'], a,b,c), '--', color='blue', label="fitted")
170
+ plt.xlabel('cumulative cost'); plt.ylabel('marginal income')
171
+ ax2.title.set_text('Net income at different spend levels')
172
+ except:
173
+ pass
174
  values = (max_spend_threshold,highest_amount_spent,total_negative_roas_spend,marginal_cpc,cum_clicks,cum_cpc,cum_revenue,rSquared)
175
  return fig,output_msg,values
176
+ # return fig,output_msg,values,df_marginal
177
 
178
  def loop_mCPC_countries(df,min_date,max_date,
179
  country_list=['UK', 'DE', 'US', 'NL', 'SE', 'CH', 'BE', 'EU', 'FR', 'AU'],