Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.
By Yuri Fonseca
Demand models
In the previous post about pricing optimization (link here), we discussed a little about linear demand and how to estimate optimal prices in that case. In this post we are going to compare three different types of demand models for homogeneous products and how to find optimal prices for each one of them.
For the linear model, demand is given by:
where
or
where
where
Some books changes the signs of the coefficients using the assumption that
In the Figure below we can check a comparison among the shapes of the demand models:
library(ggplot2) library(reshape2) library(magrittr) linear = function(p, alpha, beta) alpha*p + beta constant_elast = function(p, alpha, beta) exp(alpha*log(p)+beta) logistic = function(p, c, alpha, p0) c/(1+exp(-alpha*(p-p0))) p = seq(1, 100) y1 = linear(p, -1, 100) y2 = constant_elast(p, -.5, 4.5) y3 = logistic(p, 100, -.2, 50) df = data.frame('Prices' = p, 'Linear' = y1, 'Constant_elast' = y2, 'Logistic' = y3) df.plot = melt(df, id = 'Prices') %>% set_colnames(c('Prices', 'Model', 'Demand')) ggplot(df.plot) + aes(x = Prices, y = Demand) + geom_line(color = 'blue', alpha = .6, lwd = 1) + facet_grid(~Model)
Of course that in practice prices does not change between 1 and 100, but the idea is to show the main differences in the shape of the models.
All the models presented above have positive and negative points. Although local linear approximation may be reasonable for small changes in prices, sometimes this assumption is too strong and does not capture the correct sensitivity of bigger price changes. In the constant elasticity model, even though it is a non-linear relationship between demand and price, the constant elasticity assumption might be too restrictive. Moreover, it tends to over estimate the demand for lower and bigger prices. In a fist moment, I would venture to say that the logistic function is the most robust and realistic among the three types.
Pricing with demand models
In a general setting, one have for the total profit function:
where,
Making
which is the famous condition that in the optimal price, marginal cost equals marginal revenue. Next, let’s see how to calculate the optimum prices for each demand functions.
Linear model
For the linear model
Example:
library(tidyverse) # Synthetic data p = seq(80,130) d = linear(p, alpha = -1.5, beta = 200) + rnorm(sd = 5, length(p)) c = 75 profit = d*(p-c) # Fit of the demand model model1 = lm(d~p) profit.fitted = model1$fitted.values*(p - c) # Pricing Optimization alpha = model1$coefficients[2] beta = model1$coefficients[1] p.max.profit = (alpha*c - beta)/(2*alpha) # Plots df.linear = data.frame('Prices' = p, 'Demand' = d, 'Profit.fitted' = profit.fitted, 'Profit' = profit) ggplot(select(df.linear, Prices, Demand)) + aes(x = Prices, y = Demand) + geom_point() + geom_smooth(method = lm)
ggplot(select(df.linear, Prices, Profit)) + aes(x = Prices, y = Profit) + geom_point() + geom_vline(xintercept = p.max.profit, lty = 2) + geom_line(data = df.linear, aes(x = Prices, y = Profit.fitted), color = 'blue')
Constant elasticity model
For the constant elasticity model, since
Therefore,
Moreover, knowing that
Thus, we can calculate the optimum profit price for the constant elasticity model as:
It is interesting to note that one needs
Example:
# Synthetic data p = seq(80,130) d = constant_elast(p, alpha = -3, beta = 15)*exp(rnorm(sd = .15, length(p))) c = 75 profit = d*(p-c) # Fitting of demand model model2 = lm(log(d)~log(p)) profit.fitted = exp(model2$fitted.values)*(p - c) # pricing optimization alpha = model2$coefficients[2] p.max.profit = c/(1-1/abs(alpha)) # Plots df.const_elast = data.frame('Prices' = p, 'Demand' = d, 'Profit.fitted' = profit.fitted, 'Profit' = profit) ggplot(select(df.const_elast, Prices, Demand)) + aes(x = log(Prices), y = log(Demand)) + geom_point() + geom_smooth(method = lm)
ggplot(select(df.const_elast, Prices, Profit)) + aes(x = Prices, y = Profit) + geom_point() + geom_vline(xintercept = p.max.profit, lty = 2) + geom_line(data = df.const_elast, aes(x = Prices, y = Profit.fitted), color = 'blue')
Logistic model
For the logistic function, one can check that
Since the last equation above does not have an analytical solution (at least we couldn’t solve it), one can easily find the result with a newton-step algorithm or minimization problem. We will use the second approach with the following formulation:
Example:
# Objective functions for optimization demand_objective = function(par, p, d) sum((d - logistic(p, par[1], par[2], par[3]))^2) price_objective = function(p, alpha, c, p0) (exp(-alpha*(p-p0))*(alpha*(p-c)+1) + 1)^2 # A cleaner alternative for pricing optimization is to min: price_objective2 = function(p, c, alpha, C, p0) -logistic(p, C, alpha, p0)*(p-c) # synthetic data p = seq(80,130) c = 75 d = logistic(p, 120, -.15, 115) + rnorm(sd = 10, length(p)) profit = d*(p-c) # Demand fitting, we can't use lm anymore par.start = c(max(d), 0, mean(d)) # initial guess demand_fit = optim(par = par.start, fn = demand_objective, method = 'BFGS', p = p, d = d) par = demand_fit$par # estimated parameters for demand function demand.fitted = logistic(p, c = par[1], alpha = par[2], p0 = par[3]) profit.fitted = demand.fitted*(p - c) # Pricing Optimization, we don't have a closed expression anymore price_fit = optim(mean(p), price_objective, method = 'BFGS', alpha = par[2], c = c, p0 = par[3]) # or price_fit2 = optim(mean(p), price_objective2, method = 'BFGS', c = c, C = par[1], alpha = par[2], p0 = par[3]) # both results are almost identical p.max.profit = price_fit$par # Graphics df.logistic = data.frame('Prices' = p, 'Demand' = d, 'Demand.fitted' = demand.fitted, 'Profit.fitted' = profit.fitted, 'Profit' = profit) ggplot(select(df.logistic, Prices, Demand)) + aes(x = Prices, y = Demand) + geom_point() + geom_line(data = df.logistic, aes(x = Prices, y = Demand.fitted), color = 'blue')
ggplot(select(df.logistic, Prices, Profit)) + aes(x = Prices, y = Profit) + geom_point() + geom_vline(xintercept = p.max.profit, lty = 2) + geom_line(data = df.logistic, aes(x = Prices, y = Profit.fitted), color = 'blue')
I hope you liked the examples. In the next post we will discuss about choice models, which are demand models when products are heterogeneous. Goodbye and good luck!
References
Phillips, Robert Lewis. Pricing and revenue optimization. Stanford University Press, 2005.
R-bloggers.com offers daily e-mail updates about R news and tutorials about learning R and many other topics. Click here if you're looking to post or find an R/data-science job.
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.