简体   繁体   中英

In R, given y = f(x), how do I find the global max of y/x?

I have created a curve that shows for each level of spend (X) a unique output in revenue (Y).

The curve is defined by the following (monotone) function:

calculate_abc_revenue <- function(a, b, c, spend) {

  res <- ifelse(
    a/(1+b*(spend)^c) >= 0,
    a/(1+b*(spend)^c),
    0
    )

  return(res)

}

Where a , b and c are given parameters and should be treated as constant:

a0 <- 1303066.36937866
b0 <- 15560519.9999999
c0 <- -1.09001859302511

Now, if we define ROI as:

revenue <- calculate_abc_revenue(a = a0, b = b0, c = c0, spend)
ROI <- revenue/spend

How do I find the exact values of revenue and spend that make ROI max?

I currently use a spend vector of length n that helps me finding approximately the max ROI, but most of the times the result is not 100% exact as the real max ROI can fall between two points sent as input.

I would like to avoid to increase the length of the spend vector as it would increase the calculation time (and it wouldn't guarantee that the solution found is a global max anyway).

By setting ROI as a function, we can use optimize :

ROI <- function(spend) calculate_abc_revenue(a0, b0, c0, spend)/spend

optspend <- optimize(ROI, c(0, 1e12), maximum = TRUE)$maximum
c("optimal spend" = optspend, revenue = calculate_abc_revenue(a0, b0, c0, optspend))
#> optimal spend       revenue 
#>      435274.1      107613.0

Here is another approach. It uses unitroot applied to the derivative of the ROI-function f . (only valid for spend > 0 ) From this function the derivative is build from which a function is created. This function is then fed into unitroot .

Plots in the upper row show ROI over a wide range of investment and its derivative. The lower row shows a zoomed version of those.

#| function related to investment (spend) ROI
f = expression(1 / spend * (a0 / (1 + b0 * spend^c0)))     

#| get the derivative
ff_2 <- D(f, 'spend')
#| uniroot
ff_2 <- function(spend){}
body(ff_2) <- ff
res <- uniroot(ff_2, c(1e5, 1e6))
c("optimal spend" = res$root, revenue = calculate_abc_revenue(spend = res$root))
# optimal spend       revenue 
#    435274.1      107613.0 

在此处输入图像描述


Original Data

a0 <- 1303066.36937866
b0 <- 15560519.9999999
c0 <- -1.09001859302511

#| Original function
calculate_abc_revenue <- function(a = a0,b = b0, c = c0,spend) {
  res <- ifelse(
    a/(1+b*(spend)^c) >= 0,
    a/(1+b*(spend)^c),
    0
  )
  return(res)
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM