S - Retail Price Optimization using Python

 

Retail Price Optimization using Python



Retail Price Optimization: Case Study

Download the dataset below to solve this Data Science case study on retail price optimization. (Data Source: Kaggle)



The retail industry is extremely competitive, and pricing is a critical factor in attracting customers and boosting profits. Pricing decisions are multifaceted and are affected by numerous factors, including cost of goods sold (COGS), market demand, competition, and targeted profit margins. Therefore, companies need to fine-tune their pricing strategies to achieve the right balance that maximizes sales and ensures profitability.

In this case study, we’ll use a dataset on Retail Price Optimization submitted by Suddharshan S on Kaggle. The dataset includes the following features:

  • product_id: A unique identifier for each product.
  • product_category_name: The product category name.
  • month_year: The month and year of the retail transaction or data recording.
  • qty: The quantity of the product sold or purchased in a transaction.
  • total_price: The total price of the product, including any taxes or discounts.
  • freight_price: The shipping or freight cost associated with the product.
  • unit_price: The price per unit of the product.
  • product_name_length: The number of characters in the product name.
  • product_description_length: The number of characters in the product description.
  • product_photos_qty: The number of photos available for the product.
  • product_weight_g: The weight of the product in grams.
  • product_score: A rating or score indicating the product’s quality, popularity, or other relevant aspects.
  • customers: The number of customers who purchased the product in a transaction.
  • weekday: The day of the week when the transaction occurred.
  • weekend: A binary indicator (1 if the transaction occurred on a weekend, 0 otherwise).
  • holiday: A binary indicator (1 if the transaction occurred on a holiday, 0 otherwise).
  • month: The month of the transaction.
  • year: The year of the transaction.
  • s: Represents the effect of seasonality.
  • comp_1, comp_2, comp_3: Information related to competitors’ prices, promotions, or other relevant factors.
  • ps1, ps2, ps3: Ratings or scores for competitors’ products.
  • fp1, fp2, fp3: Freight or shipping costs for competitors’ products.

The objective is to use this data to craft a data-driven price optimization strategy that maximizes profits.

Case Study Overview

Retail price optimization is about finding the right price point for your products to maximize revenue and profit. By analyzing data on product prices and all the influencing factors, you can determine a price that not only maximizes profit but also attracts a sufficient number of customers. This article will guide you through using machine learning for retail price optimization with Python.

Retail Price Optimization using Python

Let’s kick off the process of Retail Price Optimization by importing the required Python libraries and loading the dataset:


!wget https://statso.io/wp-content/uploads/2023/04/retail.zip

--2025-02-03 10:27:14-- https://statso.io/wp-content/uploads/2023/04/retail.zip Resolving statso.io (statso.io)... 192.0.78.171, 192.0.78.225 Connecting to statso.io (statso.io)|192.0.78.171|:443... connected. HTTP request sent, awaiting response... 200 OK Length: 25481 (25K) [application/zip] Saving to: ‘retail.zip’ retail.zip 100%[===================>] 24.88K --.-KB/s in 0.03s 2025-02-03 10:27:14 (876 KB/s) - ‘retail.zip’ saved [25481/25481]

!unzip retail.zip

Archive: retail.zip inflating: retail_price.csv inflating: __MACOSX/._retail_price.csv

import pandas as pd
import plotly.express as px
import plotly.graph_objects as go
import plotly.io as pio
pio.templates.default = "plotly_white"

data = pd.read_csv('retail_price.csv')
print(data.head())

product_id product_category_name month_year qty total_price \ 0 bed1 bed_bath_table 01-05-2017 1 45.95 1 bed1 bed_bath_table 01-06-2017 3 137.85 2 bed1 bed_bath_table 01-07-2017 6 275.70 3 bed1 bed_bath_table 01-08-2017 4 183.80 4 bed1 bed_bath_table 01-09-2017 2 91.90 freight_price unit_price product_name_lenght product_description_lenght \ 0 15.100000 45.95 39 161 1 12.933333 45.95 39 161 2 14.840000 45.95 39 161 3 14.287500 45.95 39 161 4 15.100000 45.95 39 161 product_photos_qty ... comp_1 ps1 fp1 comp_2 ps2 \ 0 2 ... 89.9 3.9 15.011897 215.000000 4.4 1 2 ... 89.9 3.9 14.769216 209.000000 4.4 2 2 ... 89.9 3.9 13.993833 205.000000 4.4 3 2 ... 89.9 3.9 14.656757 199.509804 4.4 4 2 ... 89.9 3.9 18.776522 163.398710 4.4 fp2 comp_3 ps3 fp3 lag_price 0 8.760000 45.95 4.0 15.100000 45.90 1 21.322000 45.95 4.0 12.933333 45.95 2 22.195932 45.95 4.0 14.840000 45.95 3 19.412885 45.95 4.0 14.287500 45.95 4 24.324687 45.95 4.0 15.100000 45.95 [5 rows x 30 columns]

Before moving forward, let’s have a look if the data has null values or not:

print(data.isnull().sum())

product_id 0 product_category_name 0 month_year 0 qty 0 total_price 0 freight_price 0 unit_price 0 product_name_lenght 0 product_description_lenght 0 product_photos_qty 0 product_weight_g 0 product_score 0 customers 0 weekday 0 weekend 0 holiday 0 month 0 year 0 s 0 volume 0 comp_1 0 ps1 0 fp1 0 comp_2 0 ps2 0 fp2 0 comp_3 0 ps3 0 fp3 0 lag_price 0 dtype: int64

Now let’s have a look at the descriptive statistics of the data:

print(data.describe())

qty total_price freight_price unit_price \ count 676.000000 676.000000 676.000000 676.000000 mean 14.495562 1422.708728 20.682270 106.496800 std 15.443421 1700.123100 10.081817 76.182972 min 1.000000 19.900000 0.000000 19.900000 25% 4.000000 333.700000 14.761912 53.900000 50% 10.000000 807.890000 17.518472 89.900000 75% 18.000000 1887.322500 22.713558 129.990000 max 122.000000 12095.000000 79.760000 364.000000 product_name_lenght product_description_lenght product_photos_qty \ count 676.000000 676.000000 676.000000 mean 48.720414 767.399408 1.994083 std 9.420715 655.205015 1.420473 min 29.000000 100.000000 1.000000 25% 40.000000 339.000000 1.000000 50% 51.000000 501.000000 1.500000 75% 57.000000 903.000000 2.000000 max 60.000000 3006.000000 8.000000 product_weight_g product_score customers ... comp_1 \ count 676.000000 676.000000 676.000000 ... 676.000000 mean 1847.498521 4.085503 81.028107 ... 79.452054 std 2274.808483 0.232021 62.055560 ... 47.933358 min 100.000000 3.300000 1.000000 ... 19.900000 25% 348.000000 3.900000 34.000000 ... 49.910000 50% 950.000000 4.100000 62.000000 ... 69.900000 75% 1850.000000 4.200000 116.000000 ... 104.256549 max 9750.000000 4.500000 339.000000 ... 349.900000 ps1 fp1 comp_2 ps2 fp2 comp_3 \ count 676.000000 676.000000 676.000000 676.000000 676.000000 676.000000 mean 4.159467 18.597610 92.930079 4.123521 18.620644 84.182642 std 0.121652 9.406537 49.481269 0.207189 6.424174 47.745789 min 3.700000 0.095439 19.900000 3.300000 4.410000 19.900000 25% 4.100000 13.826429 53.900000 4.100000 14.485000 53.785714 50% 4.200000 16.618984 89.990000 4.200000 16.811765 59.900000 75% 4.200000 19.732500 117.888889 4.200000 21.665238 99.990000 max 4.500000 57.230000 349.900000 4.400000 57.230000 255.610000 ps3 fp3 lag_price count 676.000000 676.000000 676.000000 mean 4.002071 17.965007 107.399684 std 0.233292 5.533256 76.974657 min 3.500000 7.670000 19.850000 25% 3.900000 15.042727 55.668750 50% 4.000000 16.517110 89.900000 75% 4.100000 19.447778 129.990000 max 4.400000 57.230000 364.000000 [8 rows x 27 columns]

Now let’s have a look at the distribution of the prices of the products:


Comments

Popular posts from this blog

>QueueBite — AI-Powered Restaurant Waitlist Manager