Advertising Diminishing Returns & Saturation

In this post we take the basic model developed in Marketing Mix Modeling Explained – with R and add the non-linear effect of advertising. I distinguish between advertising and advertising returns. I call the later sales for ease of readability.

Advertising non-linearity beyond the adstock/carry-over idea comes from two concepts: (1) diminishing returns and (2) saturation. Diminishing returns means that advertising exhibits non-constant and a decreasing marginal return to scale. For example, sales from $200 of advertising are less than twice the sales of $100 of advertising. A subsequent part of diminishing returns is the saturation effect where sales reach a limit after which more advertising has near zero incremental effect.

Diminishing Returns Response Curves
There is a number of functions used to model this non-linear advertising – sales relationship. I present few that are the most popular. I also specify the parameters ranges usually used with each function where applicable. But like they say, a picture is worth a 1,000 words.

  1. Power Functionαxβ ; 0 < β ≤ 1
    The power function has a the nice property that when β = 1 the function becomes linear. β = 1, of course, means that there is no diminishing returns within the observed data ranges. This function will never saturate as lim y = ∞ as x reaches ∞. This could be unreasonable for testing marketing outside of the observed ranges of modeled data. Aside from it’s use in advertising, the power function is also used to model price variable when β < 0.
  2. Michaelis-Menten Function(αx) / (1 + β⋅x) β ≥ 0
    The Michaelis-Menten function has a similar property to the power function as it becomes linear but when β = 0. This function has the added bonus of reaching a sales saturation of β/α.
  3. Negative Exponential Function= α⋅(1 − eβ⋅x) ; β > 0
    This function is called the negative exponential function due the −β portion. It is also referred to as the 2-parameter asymptotic exponential. Maximum sales attained by this modeling form, i.e. saturation, is α.

There are three important questions to ask:

  1. What happens at zero level of advertising?
  2. What happens at very high level of advertising?
  3. What happens between zero and high level of advertising?

Naturally, zero level of advertising should produce no sales effect and higher level of advertising effect should reach an upper limit mathematically called an asymptote. What happens in between is up to a great debate and is the subject of next post but it suffices to say an S curve function is sometimes desired.

The input variable, x, in all of the three functions above can be one of three things (1) advertising, (2) advertising adstock or (3) cumulative advertising for a certain period of time.

Last thing I want to add is that these functions are monotonically increasing, i.e. sales for higher level of advertising units is always greater than sales for lower level of advertising. Mathematically, f(x+ϵ) > f(x). This, of course, means advertising can do no harm, which is a whole different topic on it’s own.


10 thoughts on “Advertising Diminishing Returns & Saturation

  1. Doro

    Thank you for the interesting post Gabriel! Can you give an example of how to apply the functions to the adstock model illustrated in your previous post? I tried to use nls() to optimize the parameters of negative exponential function as well as the adstock decay rate but got this error:
    Error in nlsModel(formula, mf, start, wts) :
    singular gradient matrix at initial parameter estimates

    1. AnalyticsArtist Post author

      Hi Doro,

      The nls function will fail quite a bit. You can use the nlsLM function from the minpack.lm package. Here is an example I put in the comments of Adstock Rate – Deriving with Analytical Methods.

      # Set seed for reproducibility
      # Create empty shell advertising for 104 weeks (2 years)
      ad1 <- rep(0, 104)
      ad2 <- rep(0, 104)
      # Fill advertising with data
      ad1[3:64]  <- runif(64-3+1, 0, 200)
      ad2[53:93] <- runif(93-53+1, 0, 200)
      # Define adstock function
      adstock <- function(x, rate=0){
          return(as.numeric(filter(x=x, filter=rate, method="recursive")))
      # Create sales variable
      sales <- 1000 + 30 * adstock(ad1, .3) + 20 * adstock(ad2, .7)
      # Create noise
      sales <- sales + rnorm(104, mean = 0, sd = 3)
      # Solve with nlsLM
      nlsLM(sales~b0 + b1 * adstock(ad1, r1) + b2 * adstock(ad2, r2), 
            algorithm = "LM",
            start     = c(b0=   1, b1=   1, b2=   1, r1=0, r2=0),
            lower     = c(b0=-Inf, b1=-Inf, b2=-Inf, r1=0, r2=0),
            upper     = c(b0= Inf, b1= Inf, b2= Inf, r1=1, r2=1))
      ## Nonlinear regression model
      ##   model: sales ~ b0 + b1 * adstock(ad1, r1) + b2 * adstock(ad2, r2)
      ##    data: parent.frame()
      ##      b0      b1      b2      r1      r2
      ## 1000.45   29.99   20.00    0.30    0.70
      ##  residual sum-of-squares: 943
      ## Number of iterations to convergence: 13 
      ## Achieved convergence tolerance: 1.49e-08
  2. Prateek

    Thanks a lot Gabriel, tried to used nlsLM function for the saturation effect but i am not getting exactly how to combine this with the original Sales equation. Can you please help me with its code in R.


Leave a comment

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s