# Maximizing Revenue with a Price Recommender App in Python

- Canonical: https://33rdsquare.com/build-a-price-recommender-app-with-python/
- Published: 2024-09-03
- Author: Jordan Brown
- Categories: [Artificial Intelligence & Machine Learning & ChatGPT](https://33rdsquare.com/category/tech/ai/)

---

Price optimization is one of the most high-impact applications of machine learning in business. A [McKinsey study](https://www.mckinsey.com/industries/retail/our-insights/the-art-and-science-of-pricing-how-to-set-prices-to-maximize-profit) estimates that AI-driven price optimization can increase revenue by 5-10% and profits by 30%+. Optimal pricing decisions are difficult because demand varies non-linearly with price. Set prices too high and price-sensitive customers will not buy. Set prices too low and you fail to capture customers‘ willingness to pay.

The difference between current prices and optimal prices across thousands of SKUs sold through multiple channels can add up to billions of dollars in a single year. But manually analyzing historical sales data to recommend prices is intractable. In this post, I will describe how to use Python and machine learning to build a price recommendation app to maximize revenue.

## Pricing Strategies and Price Optimization

First, some background on pricing strategies. The three main approaches are:

1. Cost-plus pricing: Set prices as a fixed margin above costs
2. Competitor-based pricing: Set prices relative to competitor prices
3. Value-based pricing: Set prices based on the perceived value to the customer

Cost-plus pricing is simple but doesn‘t account for what customers are willing to pay. It risks losing sales if costs are high or leaving money on the table if costs are low.

Competitor-based pricing ensures prices are in line with the market. But it ignores differences in perceived value between brands. And it can lead to a "race to the bottom" if all companies are just trying to match competitors.

Value-based pricing aims to tailor prices for each customer segment to capture the most value. But it is difficult to implement without data on customer willingness to pay.

Price optimization uses machine learning to estimate demand at different price points. It then recommends prices that balance margin and volume to maximize total revenue or profit. Price optimization can be seen as a data-driven form of value-based pricing. It incorporates elements of cost-plus and competitor-based pricing by using costs and competitor prices as inputs.

## Price Elasticity of Demand

The key concept in price optimization is price elasticity of demand. This measures the percent change in demand for a percent change in price. If elasticity is -2, then a 10% price increase leads to a 20% decrease in demand.

Elasticity tends to be high for undifferentiated products and low for unique or luxury products. It may change at different price points and be different for each customer segment.

Estimating price elasticity requires varying prices and measuring the change in demand. Historical sales data showing purchases at different price points can be used. Panel data across multiple stores or customers facing different prices enables measuring elasticity through linear regression with controls.

Price experiments randomly assigning customers to treatment groups are the gold standard for estimating price elasticity. Comparing sales at different price points for the same product isolates the effect of price. These experiments can be run as matched market tests or online A/B tests.

The formula for price elasticity is:

```
Elasticity = (% Change in Quantity) / (% Change in Price)
           = (ΔQ / Q) / (ΔP / P)
```

For example, if price increases by 5% and demand decreases by 10%, then price elasticity is:

```
Elasticity = -10% / 5% = -2
```

The negative sign indicates that demand decreases when price increases. In other words, customers are price sensitive for this product.

## Building a Price Recommender App

Now let‘s walk through how to implement a price recommender app in Python. We‘ll follow these steps:

1. Collect and clean historical sales data
2. Estimate price elasticity through regression
3. Engineer features for the ML model
4. Train a demand forecasting model
5. Formulate the price optimization problem
6. Visualize price recommendations in a Dash app

### Data Collection and Cleaning

Start by collecting historical sales data showing the number of units sold at each price point. This data is typically available in a sales database or BI tool like Looker.

Use Pandas to load the data into a DataFrame. Key columns to include are:

- Transaction ID
- Date
- Product ID
- Price
- Quantity
- Revenue (Price * Quantity)

Clean the data by removing outliers and handling missing values. Consider aggregating the data to the weekly or monthly level to smooth out noise.

### Price Elasticity Estimation

Next estimate the price elasticity for each product using linear regression:

```
from sklearn.linear_model import LinearRegression

def estimate_elasticity(df):
    X = df[[‘Price‘]]
    y = df[‘Quantity‘]

    model = LinearRegression()
    model.fit(X, y)

    elasticity = model.coef_[0] * (df[‘Price‘].mean() / df[‘Quantity‘].mean())

    return elasticity
```

This function takes a DataFrame with Price and Quantity columns. It fits a linear regression model and calculates the elasticity as the coefficient on Price multiplied by the ratio of average price to average quantity.

Perform this estimation for each product and store the elasticities in a dictionary:

```
elasticities = {}
for product in df[‘Product ID‘].unique():
    elasticities[product] = estimate_elasticity(df[df[‘Product ID‘] == product])
```

### Feature Engineering

Next create features to be used as inputs for the demand forecasting model. Some examples:

- Lag features showing price and demand in previous weeks
- Rolling average price and demand
- Relative price vs competitors
- One-hot encoded product categories
- Holiday and seasonality indicators
- Store or region indicators

Use Pandas to engineer these features and join them with the original sales data.

### Demand Forecasting Model

A demand forecasting model predicts demand as a function of price and other relevant features. It‘s essentially a regression model that estimates the quantity sold.

Split the data into training and test sets. Use a model like Random Forest or Gradient Boosting Trees that can handle non-linear relationships. Fit the model on the training set and evaluate performance on the test set. Tune hyperparameters to optimize evaluation metrics like RMSE.

Example model training code:

```
from sklearn.ensemble import RandomForestRegressor

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2)

model = RandomForestRegressor(n_estimators=100, max_depth=5)
model.fit(X_train, y_train)

print("Test RMSE: ", mean_squared_error(y_test, model.predict(X_test), squared=False))
```

### Price Optimization Formulation

The demand forecasting model predicts sales quantity given a price. To find the optimal price to maximize revenue, we can perform a grid search.

Specify a range of prices. For each price, predict demand using the trained model. Multiply demand by price to get predicted revenue. Take the argmax of the revenue.

Price optimization can also be formulated as a constrained optimization problem:

```
Maximize: Revenue = Price * Demand
Subject to:
    Price Elasticity Constraint
    Price Bounds
    Cross-Product Constraints
```

The elasticity constraint enforces a maximum percent change in price to avoid large decreases in demand. The price bounds set a min and max price. Cross-product constraints ensure that the recommended prices for complementary products make sense together.

This optimization problem can be solved with a tool like SciPy optimize or Google OR-Tools.

### Price Recommender Dash App

Finally let‘s build an interactive Dash app to visualize the price recommendations. The app will include:

- Dropdown to select a product
- Slider to specify min and max prices
- Input box for the price elasticity constraint
- Chart showing predicted demand and revenue at each price
- Table with the top 5 price recommendations

Here‘s the basic scaffolding for the app:

```
import dash
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, Output

external_stylesheets = [‘https://codepen.io/chriddyp/pen/bWLwgP.css‘]

app = dash.Dash(__name__, external_stylesheets=external_stylesheets)

app.layout = html.Div([
    html.H2(‘Price Recommender‘),
    dcc.Dropdown(
        id=‘product-dropdown‘,
        options=[{‘label‘: i, ‘value‘: i} for i in products],
        value=products[0]
    ),
    dcc.RangeSlider(
        id=‘price-slider‘,
        min=0,
        max=100,
        step=1,
        value=[0, 100],
        marks={i: f‘${i}‘ for i in range(0, 101, 10)}
    ),
    html.Div([
        dcc.Graph(id=‘price-demand-chart‘),
        html.Table(id=‘price-recs-table‘)
    ])
])
```

This sets up the basic layout with a dropdown for the product, a range slider for the price bounds, a placeholder chart, and a placeholder table.

To connect the inputs to the outputs, we define a callback function:

```
@app.callback(
    [Output(‘price-demand-chart‘, ‘figure‘),
     Output(‘price-recs-table‘, ‘children‘)],
    [Input(‘product-dropdown‘, ‘value‘),
     Input(‘price-slider‘, ‘value‘)]
)
def update_price_recs(selected_product, price_range):
    # Filter data for selected product
    product_df = df[df[‘Product ID‘] == selected_product]

    # Get price elasticity for selected product
    elasticity = elasticities[selected_product]

    recs_df = pd.DataFrame()
    for price in range(price_range[0], price_range[1]+1):
        # Predict demand at this price
        demand = model.predict(pd.DataFrame({‘Price‘: [price]}))

        # Calculate revenue
        revenue = price * demand

        # Add to recommendations DataFrame
        recs_df = recs_df.append({
            ‘Price‘: price,
            ‘Demand‘: demand,
            ‘Revenue‘: revenue
        }, ignore_index=True)

    # Create price vs demand chart
    demand_chart = {
        ‘data‘: [
            {‘x‘: recs_df[‘Price‘], ‘y‘: recs_df[‘Demand‘], ‘type‘: ‘line‘, ‘name‘: ‘Demand‘},
            {‘x‘: recs_df[‘Price‘], ‘y‘: recs_df[‘Revenue‘], ‘type‘: ‘line‘, ‘name‘: ‘Revenue‘, ‘yaxis‘: ‘y2‘}
        ],
        ‘layout‘: {
            ‘title‘: f‘Predicted Demand and Revenue for {selected_product}‘,
            ‘xaxis‘: {‘title‘: ‘Price‘},
            ‘yaxis‘: {‘title‘: ‘Demand‘},
            ‘yaxis2‘: {‘title‘: ‘Revenue‘, ‘overlaying‘: ‘y‘, ‘side‘: ‘right‘}
        }
    }

    # Create price recommendations table
    recs_table = html.Table([
        html.Thead(html.Tr([html.Th(‘Price‘), html.Th(‘Demand‘), html.Th(‘Revenue‘)])),
        html.Tbody([
            html.Tr([
                html.Td(row[‘Price‘]),
                html.Td(round(row[‘Demand‘], 2)),
                html.Td(round(row[‘Revenue‘], 2))
            ]) for _, row in recs_df.nlargest(5, ‘Revenue‘).iterrows()
        ])
    ])

    return demand_chart, recs_table

if __name__ == ‘__main__‘:
    app.run_server(debug=True)
```

This callback function gets triggered whenever the selected product or price range changes. It performs these steps:

1. Filters the sales data for the selected product
2. Gets the estimated price elasticity for the selected product
3. Loops through all prices in the specified range
4. Predicts demand at each price using the ML model
5. Calculates revenue as price times predicted demand
6. Builds a DataFrame of price, predicted demand, and revenue
7. Creates a line chart showing price vs demand and revenue
8. Creates a table showing the top 5 prices by revenue

The function returns the price vs demand chart and the price recommendations table. These get rendered in the placeholders we defined in the app layout.

Here‘s the resulting price recommender app:

![Price Recommender App](https://33rdsquare.com/price_recommender.png)

The app is interactive – as the user selects different products and price ranges, the chart and table update with custom price recommendations.

## Conclusion

We‘ve covered a lot in this post – the benefits of price optimization, estimating price elasticity, training demand forecasting models, and building an interactive price recommender Dash app.

Pricing is one of the most challenging areas of business. For years it has been more art than science. But with the scale and granularity of sales data available today, there are big opportunities to apply data science and machine learning to optimize pricing decisions. The impact of even small improvements in price can be huge – millions of dollars in incremental annual revenue.

ML-powered pricing is still an emerging area. It requires bringing together expertise in machine learning, economics, business, and engineering. This post aims to provide a foundation for you to start experimenting with price optimization. Think about how you could apply it for your company or clients. Start small by estimating elasticities to quantify the impact of pricing actions. Then build out a prototype price recommender app for a high-priority product area. If it moves the needle, invest in the data and modeling infrastructure to scale price optimization more broadly.

The complete code for this price recommender app is available on my [GitHub](https://github.com/dswriter/price_recommender). I encourage you to clone the repo and adapt the code for your own use case. If you have any questions or feedback, feel free to reach out on [LinkedIn](https://www.linkedin.com/in/dswriter/) or [Twitter](https://twitter.com/ds_writer). Thanks for reading!

---

Source: [Maximizing Revenue with a Price Recommender App in Python](https://33rdsquare.com/build-a-price-recommender-app-with-python/)
