Comments (6)
Hi sorry for the late reply, to your question of "budget allocator and initial model not matching", please check this answer from me on another similar issue.
Regarding validation, as explained above, you'll get the same spend share as the initial model by doing this. I just picked a random model using the simulated data :
library(dplyr)
AllocatorCollect1 <- robyn_allocator(
InputCollect = InputCollect,
OutputCollect = OutputCollect,
select_model = select_model,
date_range = "all", # Default last month as initial period
channel_constr_low = 0.7,
channel_constr_up = c(1.2, 1.5, 1.5, 1.5, 1.5),
scenario = "max_response",
export = create_files
)
OutputCollect$xDecompAgg %>% filter(solID == select_model & !is.na(spend_share)) %>% select(rn, spend_share, effect_share) %>% arrange(rn)
AllocatorCollect1$dt_optimOut %>% select(channels, initSpendShare, initResponseUnitShare)
As you can see in the result, spend share are the same after setting date_range to all, because the initial model onepager considers all dates, while the allocator contains 4 weeks by default.
And yes, the effect share is different, which is also explained in the linked comment above. For initial model, the effect share is just the % of all weekly avg. effect, or simply the historical share. For allocator, I need to use the weekly avg. spend to simulate the weekly avg. carryover and then simulate the weekly avg. response. It's a simulation process, NOT the historical share anymore.
from robyn.
Just found a bug and pushed a fix on the response function. Now you can validate between initial model, robyn_response & robyn_allocator as followed:
## comparing responses
last_period <- 1
media_sorted <- sort(InputCollect$paid_media_spends)
## get last period response from initial model
val_response_a <- OutputCollect$xDecompVecCollect %>%
filter(solID == select_model) %>%
select(ds, media_sorted) %>%
tail(last_period)
## get last period response from robyn_response
val_response_b <- list()
for (i in seq_along(media_sorted)){
Response <- robyn_response(
InputCollect = InputCollect,
OutputCollect = OutputCollect,
select_model = select_model,
metric_name = media_sorted[i],
date_range = paste0("last_", last_period)
)
val_response_b["ds"] <- data.frame(ds = Response$date)
val_response_b[media_sorted[i]] <- data.frame(response = Response$response_total)
}
val_response_b <- bind_cols(val_response_b)
## get last period response from robyn_allocator
AllocatorCollect1 <- robyn_allocator(
InputCollect = InputCollect,
OutputCollect = OutputCollect,
select_model = select_model,
date_range = paste0("last_", last_period), # Default last month as initial period
# total_budget = NULL, # When NULL, default is total spend in date_range
channel_constr_low = 0.7,
channel_constr_up = c(1.2, 1.5, 1.5, 1.5, 1.5),
# channel_constr_multiplier = 3,
scenario = "max_response",
export = create_files
)
val_response_c <- AllocatorCollect1$dt_optimOut %>% select(date_min, date_max, initResponseUnit)
val_response_a
val_response_b
val_response_c
When doing last_period <- 1
, you can see they all align:
When doing last_period <- 3
, initial model & response function align and outputs the historical response for every period, but allocator does runs a simulation behind and thus will use avg. carryover of the last 3 period to determine the result.
from robyn.
@gufengzhou , So given the above example looking at the results for facebook_s. to get the expected total response for the alloted period will be:
<style> </style>initresponseUnit | Periods | TOTAL | |
---|---|---|---|
when period 1 | 106625.5 | 1 | 106625.5 |
when Period last 3 | 99103.13 | 3 | 297309.4 |
from robyn.
I ran the validation using my data...Trying to understand the results.
Val_response_a:
<style> </style>48 | 11/27/2022 | $ 161,919.87 | $ 2,361.20 |
---|---|---|---|
49 | 12/4/2022 | $ 127,123.26 | $ 58.60 |
50 | 12/11/2022 | $ 269,868.51 | $ 0.90 |
51 | 12/18/2022 | $ 240,025.21 | $ 0.01 |
52 | 12/25/2022 | $ 242,438.92 | $ 0.00 |
Val_response_b"
<style> </style>48 | 11/27/2022 | $ 161,919.87 | $ 2,361.20 |
---|---|---|---|
49 | 12/4/2022 | $ 127,123.26 | $ 58.60 |
50 | 12/11/2022 | $ 269,868.51 | $ 0.90 |
51 | 12/18/2022 | $ 240,025.21 | $ 0.01 |
52 | 12/25/2022 | $ 242,438.92 | $ 0.00 |
val_response_c:
<style> </style>date_min | date_max | initResponseUnit | |
---|---|---|---|
CSI_SPEND | 1/2/2022 | 12/25/2022 | 4241.296224 |
WRAP_SPEND | 1/2/2022 | 12/25/2022 | 402.289325 |
why is val_response_c so low. Does it divide by 52? (I ran the MMM for 52 weeks)
Thanks again for all your help on this.
from robyn.
The response level is calculated by a given spend on a given historical carryover/adstock. The given spend for response_c is the avg spend of the last 52 weeks, and the given carryover is the avg carryover of the 52 weeks.
Without looking into your data, the low response_c is because of the relatively high avg carryover and/or relatively low avg spend, compared to the actual daily levels. it's possible.
In your case, I suggest you to experiment with different date_range to find out the appropriate levels. We recommend using rather more recent periods instead of too far backwards to reflect your recent adstocking and saturation behaviour.
from robyn.
@gufengzhou, shouldn't the response C, init_response_unit = response(immediate) + carryover response?
My client's creates budget on a 52 week window. Any suggestions to be able to run allocations on this would be welcome?
from robyn.
Related Issues (20)
- Refresh output is not matching the documentation HOT 3
- Output of robyn_recreate() returns warning message referencing an object that does not exist anymore? HOT 1
- Different Results in Recreated Model HOT 7
- Error in NRMSE calculation HOT 1
- Import mode output to run optimizations HOT 2
- Error in robyn_outputs step when recreating model from previous model inputs and hyperparameters HOT 5
- Factorial Variables HOT 1
- Budget Allocator Question HOT 9
- Model Refresh HOT 2
- Error in signif(nevergrad_hp_val[[co]][index], 6) : non-numeric argument to mathematical function HOT 2
- How to install specific Dev version Robyn_3.10.4.9000 HOT 2
- Robyn not working anymore during "Calculating response curves for all models' media variables (615)." HOT 2
- py_module_available("nevergrad") = False HOT 18
- Issue when running budget allocator with 0-constraint channels but no 0-coef channels HOT 2
- Unfortunate channel naming can lead to mixed up hyperparameters in budget allocator HOT 2
- Could not import matplotlib.pyplot, - Nevergrad Issue HOT 1
- Warning message: In selectChildren(ac[!fin], -1) : error 'No child processes' in select HOT 2
- robyn_write() model performance metrics show NRMSE for the validation set not the test set. Is it normal? HOT 4
- robyn_clusters return error HOT 3
- Error when running the demo.R HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from robyn.