“The moment you make a pricing mistake, is eroding your reputation or your earnings”. – Katharine Paine
Price optimization consists of using historical data to identify the most appropriate price of a product or service that maximizes the profitability of the company. There are numerous factors such as demographics, operating costs, survey data, etc. that play a role in efficient pricing, it also depends on the nature of the companies and the product being served. The company adds / regularly update features to add more value to the product and, obviously, this has an associated cost in terms of effort, time and, the most important, the reputation of companies.
As a result, it is important to understand the correct price, a little too high, you will lose your customers and a slight underpricing will result in a loss of revenue. Price optimization helps companies find the right balance between efficient prices, achieve profit goals and also serve your customers. In this blog, we will look at the simplistic approach to price optimization and also create a simulation application.
Figure 1: Snapshot of the price recommendation app
Challenges in price optimization:
Price optimization for a single product: Price optimization for a single product is predicting changing demand in response to different prices. Helps the business set the prices customers are willing to pay and maximize profits. For instance: in the smartphone market, it's a good balance between new features and price.
Price optimization for a product family: Any change in the price of a product can set off a chain reaction in a family of products. Therefore, Product family pricing becomes a daunting task. Not .: In the ice cream market, there may be different flavors, sizes as in cups, candies, cones, packs familiares o tarrinas. It is the same product with different sizes and prices.
Benefits of optimizing prices:
Immediate economic benefits: Companies can get instant results by targeting multiple KPIs, either margin, sales conversions, adding new customers or entering a new market space, etc., and then review the results to make the appropriate price changes.
Automation of business processes: Price optimizations should be more of a data-driven process. Historical data analysis, sales trends, demand, etc. helps companies design rules or build ML models or build a hybrid model that is fully automated, thus eliminating human error or emotion-based pricing decisions.
Quick response to changing market trends: The demand and the market trend change quite frequently and, sometimes, when a competitor launches a similar product at a lower price, eats the actions of others. In such a scenario, optimizing product prices in a particular product segment or geography helps companies meet this challenge.
objectives:
We will explore the next steps and, at the end of this blog, we will create the Price Optimization Simulator App with plot script.
- Price optimization overview
- Challenges and benefits of optimization
- Data exploration
- Model building and optimization
- App development with Plotly Dash
- Challenges in creating and implementing pricing optimization models and applications
Starting:
Data: We will use toy data. Price.csv and here is a quick snapshot of the data. As the dataset is small and clean, no pre-processing is necessary.
Year Quarter Quantity Price 1977 1 22.9976 142.1667 1977 2 22.6131 143.9333 1977 3 23.4054 146.5000 1977 4 22.7401 150.8000 1978 1 22.0441 160.0000 1978 2 21.7602 182.5333 1978 3 21.6064 186.2000 1978 4 21.8814 186.4333 1979 1 20.5086 211.7000 1979 2 19.0408 231.5000
Project structure: Here is the structure of our project.
Price optimization
| app.py # The file for building apps that has callback logic and UI
+ -Assets # The style sheet that defines the aesthetics of the application.
|
+ -Data
| price.csv # The dataset file
+ —Python
| optimizar_precio.py # The Python file with logic for price optimization.
| optimizar_cantidad.py # The python file with logic for quantity optimization
Loading Libraries: Let's create a file by name optimizar_precio.py and load all the necessary libraries.
import pandas as pd import numpy as np from pandas import DataFrame import matplotlib.pyplot as plt import seaborn as sns from statsmodels.formula.api import ols import plotly.express as px import plotly.graph_objects as go
Let's look at the relationship between Price and Quantity and we expect to see a linear trend.
fig_PriceVsQuantity = px.scatter( df, x="Price", y ="Quantity", color="Cost", trendline="ols") fig_PriceVsQuantity.show()
Figure 2: Price Vs Quantity
Building a basic model: In our case, we will build an OLS model (Ordinary Least Square) very basic.
# fit OLS model model = ols("Quantity ~ Price", data=df).fit()
Optimization range: In most cases, we have a rough idea of the minimum and maximum prices based on past experience. How we are in the process of identifying the best price, it will be a good starting point and we will refine it further with multiple iterations.
Price = list(range(var_range[0], var_range[1], 10)) cost = int(var_cost) quantity = [] Revenue = [] for i in Price: demand = model.params[0] + (model.params[1] * i) quantity.append(demand) Revenue.append((i-cost) * demand)
We will create a data frame with the 3 Price columns, Income and Amount that will allow us to easily access these values during the development phase of the application.
profit = pd.DataFrame({"Price": Price, "Revenue": Revenue, "Quantity": quantity}) max_val = profit.loc[(profit['Revenue'] == profit['Revenue'].max())]
Optimization line chart: Here is the feature we plan to have on the chart.
- The chart should update based on the user's selection of a price range / quantity or maybe a fixed cost.
- The graph should indicate the exact point where income is highest.
fig_PriceVsRevenue = go.Figure() fig_PriceVsRevenue.add_trace(go.Scatter( x=profit['Price'], y=profit['Revenue'])) fig_PriceVsRevenue.add_annotation(x=int(max_val['Price']), y=int(max_val['Revenue']), text="Maximum Revenue", showarrow=True, arrowhead=1) fig_PriceVsRevenue.update_layout( showlegend=False, xaxis_title="Price", yaxis_title="Revenue") fig_PriceVsRevenue.add_vline(x=int(max_val['Price']), line_width=2, line_dash="dash", line_color="red", opacity=0.25)
Figure 3: Price Vs Income
Putting it all together: The logic of the price optimization will be in the file. optimizar_precio.py
import pandas as pd import numpy as np from pandas import DataFrame import matplotlib.pyplot as plt import seaborn as sns from statsmodels.formula.api import ols import plotly.express as px import plotly.graph_objects as go def fun_optimize(var_opt, var_range, var_cost, df): fig_PriceVsQuantity = px.scatter( df, x="Price", y ="Quantity", color="Cost", trendline="ols") # fit OLS model model = ols("Quantity ~ Price", data=df).fit() Price = list(range(var_range[0], var_range[1], 10)) cost = int(var_cost) quantity = [] ...................... ...................... return [profit, fig_PriceVsRevenue, fig_PriceVsQuantity, round(max_val['Price'].values[0],2),round(max_val['Revenue'].values[0],3)]
Quantity optimization: We will follow a similar approach to optimize the amount of a given restriction for maximum revenue.. For the sake of brevity and so that the blog is not extensive, I will not put the code in the blog, but feel free to access the code from optimizar_cantidad.py
Applications development:
We will develop a price optimization application with Plotly Dash, which is a python framework for creating data applications. Let's create a file by name app.py and start loading libraries.
Paso 1: library load:
import dash import pandas as pd import numpy as np import dash_table import logging import plotly.graph_objs as go import plotly.express as px import dash_core_components as dcc import dash_html_components as html import dash_bootstrap_components as dbc from dash.dependencies import Input, Output, State import optimize_price import optimize_quantity import dash_daq as daq
Paso 2: Design the layout:
We divide the design into 4 sections side by side as we saw in the intro snapshot.
- The controls / fields, namely, the slider to select maximum and minimum, radio button to select Price or quantity to optimize, text input to configure fixed cost.
- A graph to visualize the relationship between Price Vs Quantity
- A graph to visualize the optimal income
- A table that has simulated data
Here is the UI code to generate a range slider.
html.Div( className="padding-top-bot", children=[ html.H6("OPTIMIZATION RANGE"), html.Div( id='output-container-range-slider'), dcc.RangeSlider( id='my-range-slider', min = 0, max=500, step=1, marks={ 0: '0', 500: '500' }, value=[200, 400] ), ], ),
It will be very useful to show the maximum and minimum values selected by the user and we can achieve this with a callback function.
@app.callback( dash.dependencies.Output('output-container-range-slider', 'children'), [dash.dependencies.Input('my-range-slider', 'value')]) def update_output(value): return "{}".format(value)
In the same way, we will add another two controls. please refer to app.py for the complete code.
Paso 3: To build interactivity between controls and images, we define the inputs and outputs, namely, for each change in entries made by the user, what are the outputs that need to be updated. In our case, we need to update two line charts and a table.
@app.callback( [ Output("heatmap", 'data'), Output("lineChart1", 'figure'), Output("lineChart2", 'figure'), Output("id-insights", 'children'), ], [ Input("selected-var-opt", "value"), Input("my-range-slider", "value"), Input("selected-cost-opt", "value") ])
Paso 4: We define a function update_output_All () which takes the controls as inputs, run the logic, which means it generated the images and the data table, to be completed in the user interface.
def update_output_All(var_opt, var_range, var_cost): try: if var_opt == 'price': res, fig_PriceVsRevenue, fig_PriceVsQuantity, opt_Price, opt_Revenue = Python.optimize_price.fun_optimize( var_opt, var_range, var_cost, df) res = np.round(res.sort_values( 'Revenue', ascending=False), decimals=2) if opt_Revenue > 0: return [res.to_dict('records'), fig_PriceVsRevenue, fig_PriceVsQuantity, f'The maximum revenue of {opt_Revenue} is achieved by optimizing {var_opt} of {opt_Price}, fixed cost of {var_cost} and optimization was carried for {var_opt} range between {var_range}'] .................................. .................................. except Exception as e: logging.exception('Something went wrong with interaction logic:', e)
please refer to app.py for the complete code.
recommendations: Although we are creating a very basic application with minimal fields and visuals, we still need to check the input selection, observe the patterns, identify maximum income points and draw conclusions. It would be good to add recommendations where the application tells us if we are obtaining profits or losses and also informs us of the selected parameters.
We achieve this by dynamically building a string and filling the placeholders with values during runtime. Here is the sample return string from our callback function
f'The maximum revenue of {opt_Revenue} is achieved by optimizing {var_opt} of {opt_Price}, fixed cost of {var_cost} and optimization was carried for {var_opt} range between {var_range}']
Here is the result of the sample recommendation:
“The price is really quite simple … Customers will not literally pay a penny more than the actual value of the product”. – Ron Johnson
Key points to keep in mind:
As you will have noticed, There are several stages to building a model-driven data application and each of these stages carries its own set of challenges.
Data quality: The efficiency of the ML model depends on the quality of the data. Therefore, it is important to test the data for any deviations (data drift) of the expected standard. An automated quality control process helps to identify any anomalies in the data and appropriate data pre-processing steps must be applied to rectify the deviation..
Construction of the model: A model, whether simple or complex, needs to be tested, validated and tested before being pushed for use in production. The performance of the model in production should be monitored, for instance: model size, model response time, precision, etc.
Deployment: The model is generally implemented as a service that the application consumes. and there has to be a seamless integration of various components, data sources and other systems. Many times, the models are different for each region according to the demand of that geography, and this results in multiple models, data and model pipelines.
Model monitoring *: Like any other system, the implemented models should also be monitored to detect deviations (model deviation). Models are retrained and deployed at a defined frequency, which can be weekly, monthly or quarterly, depending on the nature of the product / service and business impact.
Note: The implementation of the model was not covered as part of this blog. I will plan a separate blog dedicated to application deployment.
Closing note:
The goal of the blog was to present a very simplistic approach to price optimization and to create a web application that can help business users make decisions on the go.. We also address various aspects of building a data application from data exploration to modeling and the challenges associated with building., implementation and maintenance of said application.
- This project configuration can be used as a template to quickly replicate it for other use cases.
- you can build a more complex model to optimize any variable of your interest.
- Connect the application to a database and create CRUD operations in the application.
I hope you liked the blog. Happy Apprenticeships !!!!
You can connect with me – Linkedin
You can find the code for reference: Github
Reference:
https://dash.plotly.com/dash-daq
https://unsplash.com/
The media shown in this article is not the property of DataPeaker and is used at the author's discretion.