Uber/Ola peak hour prices are higher than regular fares. In IRCTC, Rajdhani prices increase are booking rate increases, and in Amazon, prices for the exact product change multiple times. Who decides when to change these prices or to what extent? Who decides the right price at the right time? The answers to these questions fall under the realm of Dynamic Pricing. This article provides beginners with resources and theoretical understanding to build a basic Dynamic pricing algorithm.
This article was published as a part of the Data Science Blogathon.
In August 2023, the price of onions was Rs120 per kg. What led to it? Crunch in supply due to external environmental factors and a steady demand. The market, the buyer, the seller, demand, and supply determined the price. The same goes for most products we buy and sell today: movie tickets, bus tickets, e-commerce, fuel, etc.
In the theory of price, demand and supply dictate the prices at which goods and services will trade. When consumers’ payments for goods and services align with the marginal cost of production, we achieve the optimal market price, also referred to as the point of equilibrium between demand and supply. Setting the right price at the right time is quintessential for business growth. Pricing managers thus focus on getting close to the “Right Price,” which can be achieved through data and analytics.
Dynamic pricing uses recent trends, real-time customer behavior, supply and demand, and competition pricing to assess the price of goods sold. It allows goods to be sold at different price points, such that customer satisfaction is met and businesses can thrive.
Dynamic pricing is adopted when demand is elastic. Dynamic pricing cannot be adopted when demand is inelastic or perfectly inelastic. When customers are highly sensitive to changes in price, there is a high Price Elasticity of Demand, and this property is exploited through DP.
For example – In Bangalore, when only one autorickshaw is available at a particular time and particular location on a rainy day, a customer willing to pay higher (twice or thrice the going rate – elastic price) will get it, while another customer who isn’t ready to budge will have to take the BMTC bus where prices remain constant(inelastic).
Hence, the success of dynamic pricing is the maximization of Revenue/Profits/Capacity/Market share/Customer satisfaction. Example – If in 2021, without dynamic pricing, 1M units were sold, and the organic trajectory for 2022 is 1.5M units. Deploying dynamic pricing, units sold should increase to 2M without losing out on customer NPS or other pricing indexes.
Simply put, the YOY increase in Revenue and Units is the ultimate success metric of any dynamic pricing algorithm.
For an AB experiment on dynamic pricing, the success/output metrics that can be considered are:
One cannot talk about pricing and not discuss revenue management. Optimizing pricing, inventory, and distribution to predict demand to maximize revenue.
The legal and ethical aspects of AI and ML are less discussed in India, so let’s discuss them.
FlyAirportByAir is a taxi-chopper service in Bangalore that provides taxi service to Bangalore Airport. As the demand is relatively fluid and changes based on weather, weekends, and festivals, they want to introduce dynamic pricing to improve the top line. Write an optimal pricing function that will maximize revenue given:
Given the Days left to book, total seats available, and demand for the day, find the right price for each day.
## Global Variables
DAYS = 100
SEATS = 100
DEMAND_MIN = 100
DEMAND_MAX = 200
Forecasting demand is the first step in solving dynamic pricing. Demand varies with internal and external factors. Time-series forecasting or regression methods can be used to predict future demand.
demand_hist = [np.random.randint(DEMAND_MIN, DEMAND_MAX) for i in range(10000)]
plt.hist(demand_hist, bins = 100)
print("mean", np.mean(demand_hist) )
print("STD", np.std(demand_hist)
Demand is predicted using the Random function; the mean value is 150 daily seats, and the STD is 28.9.
Let’s consider this example: D0 is the date of the journey. As people solidify their traveling plans close to the date of the journey, demand tends to be more than the initial days(D8). Even though the market demand for D0 is 8, only 3 seats were booked; my competitors absorb the rest.
Given that demand is linear, the Python representation of the same:
def linear_demand(days_left, ticket_left, demand_level):
tickets_sold_per_day = int(ticket_left/days_left)
price = demand_level - tickets_sold_per_day ## ticket_left/days_left nearly is 1.
return max(0,price)#import csv
Function to calculate revenue:
def cumu_rev(days_left,
ticket_left,
pricing_function,
rev_to_date = 0,
demand_min = DEMAND_MIN,
demand_max = DEMAND_MAX):
if days_left > 0 and ticket_left >0 :
demand = np.random.randint(demand_min, demand_max+1)
p = pricing_function(days_left, ticket_left,demand )
q = demand - p # demand is linear Q is tickets sold
q = max(0,q)
q = min(ticket_left,q) ## cannot sell more than tickets available
return q*p, p
Given this simple function, let’s calculate the price and revenue for – One day before the journey, and the total tickets left are 3. (Because demand is randomly chosen, revenue and price might vary, random.seed(10) can be defined to get constant answers all the time)
revenue,p = cumu_rev(1, 3,linear_demand )
print("Total Revenue - ", revenue)
print("Price Per Seat - ", p)
Given this simple function, let’s calculate the price and revenue for – One day before the journey, and the total number of tickets left is 10. The price per ticket should be higher because demand is more( 3 to 10).
revenue,p = cumu_rev(1, 10,linear_demand )
print("Total Revenue - ", revenue)
print("Price Per Seat - ", p)#import csv
With a simple-linear pricing function, it is evident that as demand increases, price also increases. Let’s simulate this and try to optimize the pricing function.
Let’s stress test this simple function for 10,000 seat booking simulations using pricing functions 1. linear_demand, 2. linear_adj, and 3. linear_opti_variable and choose the best pricing that gives the highest revenue, which is the goal of this exercise
def linear_demand(days_left, ticket_left, demand_level):
tickets_sold_per_day = int(ticket_left/days_left)
price = demand_level - tickets_sold_per_day ## ticket_left/days_left nearly is 1.
return max(0,price)#import csv
def linear_adj(days_left, ticket_left, demand_level):
"""
Let's say we expect a lot of traffic/views and impressions.
If demand is high we charge higher at different rates
"""
if demand_level > 180:
opti = 3
price = demand_level - int( (ticket_left/days_left) + (opti*(demand_level/180)))
elif demand_level > 150:
opti = 2
price = demand_level - int( (ticket_left/days_left) + (opti*(demand_level/180)))
elif demand_level > 100:
opti = 1
price = demand_level - int( (ticket_left/days_left) + (opti*(demand_level/180)))
elif demand_level > 0:
opti = 0
price = demand_level - int( (ticket_left/days_left) + (opti*(demand_level/180)))
return max(0,price)#import csv
def linear_opti_variable(days_left, ticket_left, demand_level, opti = 1):
price = demand_level - int( (ticket_left/days_left) + (opti*(demand_level/150)))
# price = demand_level - int (ticket_left/days_left)
## if opti = 0 then the second term becomes 0
## As opti increased second term increased.
## 150 because on average the demand is 150, (100+150)/2
## IF demand is higher than 150, then price will reduce
## IF demand is lower than 150 then price will increase.
return max(0,price)
Recursive revenue function to calculate cumulative revenue for all 10,000 simulations:
def cumu_rev(days_left,
ticket_left,
pricing_function,
rev_to_date = 0,
demand_min = DEMAND_MIN,
demand_max = DEMAND_MAX):
if days_left > 0 and ticket_left >0 :
#random.seed(10)
demand = np.random.randint(demand_min, demand_max+1)
p = pricing_function(days_left, ticket_left,demand )
q = demand - p # demand is linear Q is tickets sold
q = max(0,q)
q = min(ticket_left,q) ## cannot sell more than tickets available
return cumu_rev(days_left = days_left-1,
ticket_left =ticket_left-q,
pricing_function = pricing_function,
rev_to_date = rev_to_date+p*q)
else:
return rev_to_date
1. Output using linear_demand:
simulation = [cumu_rev(DAYS, SEATS,linear_demand ) for i in range(10000)]
plt.hist(simulation, bins = 100)
print("mean", np.mean(simulation) )
print("STD", np.std(simulation) )
plt.title("Revenue For 10K Ticket Booking")
The average revenue based on linear_demand function is Rs14,908. This is evident from the histogram.
2. Output using linear_adj:
simulation = [cumu_rev(DAYS, SEATS,linear_adj ) for i in range(10000)]
plt.hist(simulation, bins = 100)
print("mean", np.mean(simulation) )
print("STD", np.std(simulation) )
plt.title("Revenue For 10K Ticket Booking")
The average revenue based on linear_adj function is Rs16,146. This is evident from the histogram.
3. Output using linear_opti_variable:
The first step here is to choose the OTPI value which provides the highest revenue:
opti_mean = []
for j in range(20):
simulation = [cumu_rev(DAYS, SEATS,partial(linear_opti_variable, opti= j) ) for i in range(10000)]
opti_mean.append(np.mean(simulation))
plt.plot(opti_mean)
plt.title("Optimal Value For Revenue Maximization")
def argmax(lst):
return lst.index(max(lst))
print("The Best OPTI value is -" ,list(range(20))[argmax(opti_mean)])
>> Output >> The Best OPTI value is - 1
The best OPTI value is 1 based on the elbow curve. Now let’s find revenue for OTPI = 1.
simulation = [cumu_rev(DAYS, SEATS,partial(linear_opti_variable, opti = list(range(20))[argmax(opti_mean)]) ) for i in range(10000)]
plt.hist(simulation, bins = 100)
print("mean", np.mean(simulation) )
print("STD", np.std(simulation) )
The average revenue based on linear_adj function is Rs15,838. This is evident from the histogram.
Based on Maximizing Revenue, linear_adj is the best pricing function. FlyAirportByAir can test this function and based on the AB experiment, its strengths and weaknesses can be evaluated. Learning from this can be used to improve performance over time.
Across industries like airlines, railways, tourism, ticketing, etc, DP has been deployed successfully. When implemented rightly, dynamic pricing provides businesses with flexibility and a potential growth lever. With the right adjustments and ingredients, DP yields higher customer satisfaction. This article provides a beginner’s guide to the world of DP.
Key Takeaways:
Good luck! Here’s my Linkedin profile if you want to connect with me or want to help improve the article. Feel free to ping me on Topmate/Mentro; you can message me with your query. I’ll be happy to be connected. Check out my other articles on data science and analytics here.
A. DP is a pricing strategy to optimize price at a point in time, considering external factors.
A. 1. Shatabdi, Duronto, Rajdhani train fare increases by 10% when 10% of seats are booked. 2. Hotel prices vary due to demand, festival, location, and dates closer to booking dates. All these are examples of DP.
A. Static prices remain constant throughout the year, for example, BMTC/Namma metro fares. Dynamic prices vary based on competition and external factors.
A. DP will not provide efficient results in the oil and gas industry as a few large oil-rich countries will control the supply. From a demand point of view, just because patrol is cheaper, generally, people won’t fill up more than the required amount of fuel, nor is it safe to store vast quantities of fuel.
The media shown in this article is not owned by Analytics Vidhya and is used at the Author’s discretion.