Skip to content

Commit

Permalink
Exposure fitting, curve calibration & reach and frequency allocator (#…
Browse files Browse the repository at this point in the history
…1132)

* feat: enable exposure fitting
- Exposures (Imp/GRP etc) will be prioritised over spend for parent model fitting
- Deprecate function fit_spend_exposure, incl. Michaelis Menten. Nonlinear fitting between spend and exposure wasn't improving fitting significantly. Instead, future curve calibration feature will aim to improve curve identification.
- Use cpe (cost per exposure) as ratio for spend to exposure translation. use cpe_window to scale the whole dataset in order to obtain the right spend scale for modeling period.
- remove minpack.lm / nlsLM dependency
- update exposure plot

* feat: create robyn_calibrate function
- Simulate cumulative R&F dataset with frequency bucket
- add beta coef besides alpha and gamma to nevergrad hyperparameter to improve curve fit
- plot with freq_bucket as well as onepager per trial
- add df_curve_reach_freq as dummy dataset
- create robyn_calibrate that consumes curve input and outputs hyperparameter ranges as input.
- Rename previous internal robyn_calibrate function as lift_calibration
- early stop convergence with while loop
- update documentation

* prototype: reach and frequency allocator
This is the proof of concept of a R&F allocator that includes
- Simulated R&F data
- The R&F hill params are estimated using a multiplicative equation with Nevergrad
- visualisation of surface
- R&F allocator with nlopt
- constrain validation

* update: checks, input, transformation & website
- simplify various check functions
- adapt model.R, incl. reset run_transformations params to have clearer overview of params needed. simplify transformation.R by removing unnecessary checks
- In model.R & pareto.R: remove decompSpendDist from  both scripts to reduce memory leak. Use xDecompAgg subsets instead
- In transformation.R & response.R: unify transformation namings in run_transformation and robyn_response
- In response.R: remove exposure extrapolation because it's already done in robyn_input. Also add inflexion point to output.
- In plots.R: fix onepager saturation plot issues
- In pareto.R: rewrite run_dt_resp() as response_wrapper and align transformation logic & naming.
- In pareto: Replace foreach response loop with lapply for simplicity.
- In pareto.R: Simplify plot data generation process, esp for saturation curve plot, actual vs predicted plot & immediate vs carryover plot.
- In pareto.R: Remove redundancy in xDecompVecCollect -> remove type rawMedia, rawSpend, predictedExposure, saturatedMedia & saturatedSpendReversed. Only keep adstockedMedia & decompMedia for response curve plotting.
- add set_default_hyppar for easier testing
- website update for all above changes
  • Loading branch information
gufengzhou authored Dec 19, 2024
1 parent 65f9382 commit a5ce9d9
Show file tree
Hide file tree
Showing 38 changed files with 1,867 additions and 1,358 deletions.
11 changes: 5 additions & 6 deletions R/DESCRIPTION
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
Package: Robyn
Type: Package
Title: Semi-Automated Marketing Mix Modeling (MMM) from Meta Marketing Science
Version: 3.11.1.9004
Version: 3.12.0.9000
Authors@R: c(
person("Gufeng", "Zhou", , "[email protected]", c("aut")),
person("Bernardo", "Lares", , "[email protected]", c("cre","aut")),
person("Leonel", "Sentana", , "[email protected]", c("aut")),
person("Gufeng", "Zhou", , "[email protected]", c("cre", "aut")),
person("Igor", "Skokan", , "[email protected]", c("aut")),
person("Bernardo", "Lares", , "[email protected]", c("aut")),
person("Leonel", "Sentana", , "[email protected]", c("aut")),
person("Meta Platforms, Inc.", role = c("cph", "fnd")))
Maintainer: Bernardo Lares <laresbernardo@gmail.com>
Maintainer: Gufeng Zhou <gufeng@meta.com>
Description: Semi-Automated Marketing Mix Modeling (MMM) aiming to reduce human bias by means of ridge regression and evolutionary algorithms, enables actionable decision making providing a budget allocation and diminishing returns curves and allows ground-truth calibration to account for causation.
Depends:
R (>= 4.0.0)
Expand All @@ -23,7 +23,6 @@ Imports:
jsonlite,
lares,
lubridate,
minpack.lm,
nloptr,
patchwork,
prophet,
Expand Down
4 changes: 3 additions & 1 deletion R/NAMESPACE
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ export(pareto_front)
export(plot_adstock)
export(plot_saturation)
export(robyn_allocator)
export(robyn_calibrate)
export(robyn_clusters)
export(robyn_converge)
export(robyn_csv)
Expand All @@ -43,6 +44,7 @@ export(robyn_update)
export(robyn_write)
export(run_transformations)
export(saturation_hill)
export(set_default_hyppar)
export(transform_adstock)
export(ts_validation)
import(ggplot2)
Expand All @@ -63,6 +65,7 @@ importFrom(dplyr,distinct)
importFrom(dplyr,ends_with)
importFrom(dplyr,everything)
importFrom(dplyr,filter)
importFrom(dplyr,full_join)
importFrom(dplyr,group_by)
importFrom(dplyr,lag)
importFrom(dplyr,left_join)
Expand Down Expand Up @@ -110,7 +113,6 @@ importFrom(lares,v2t)
importFrom(lubridate,day)
importFrom(lubridate,floor_date)
importFrom(lubridate,is.Date)
importFrom(minpack.lm,nlsLM)
importFrom(nloptr,nloptr)
importFrom(parallel,detectCores)
importFrom(patchwork,guide_area)
Expand Down
238 changes: 97 additions & 141 deletions R/R/allocator.R

Large diffs are not rendered by default.

21 changes: 21 additions & 0 deletions R/R/auxiliary.R
Original file line number Diff line number Diff line change
Expand Up @@ -94,3 +94,24 @@ baseline_vars <- function(InputCollect, baseline_level) {
}
return(x)
}

# Calculate dot product
.dot_product <- function(range, proportion) {
mapply(function(proportion) {
c(range %*% c(1 - proportion, proportion))
},
proportion = proportion)
}

# Calculate quantile interval
.qti <- function(x, interval = 0.95) {
check_qti(interval)
int_low <- (1 - interval)/2
int_up <- 1 - int_low
qt_low <- quantile(x, int_low)
qt_up <- quantile(x, int_up)
return(c(qt_low, qt_up))
}

# Calculate MSE
.mse_loss <- function(y, y_hat) mean((y - y_hat)^2)
Loading

0 comments on commit a5ce9d9

Please sign in to comment.