This dataset contains two related tables:
salesandingredients. It is designed for projects focusing on sales forecasting, ingredient optimization, and supply chain management for a pizza delivery business. By leveraging historical data, users can build predictive models to minimize ingredient waste, prevent stockouts, and optimize purchasing strategies.
Sales Table:
Shape: 48,620 rows × 16 columns
Columns:
pizza_id: Unique identifier for a pizza
- type: num
- range: [1:48620]
order_id: Unique identifier for a sales order
- type: num
- range: [1:21350]
pizza_name_id: Identifier linking the pizza to its recipe
- type: chr
quantity: Number of pizzas sold
- type: num
- range: [1:4]
order_date: The date of the order
- type: POSIXct
order_time: The time of the order
- type: POSIXct
unit_price: Price per unit of pizza - type: num
- range: [9.75:35.95]
total_price: quantity x unit_price
- type: num
- rage: [9.75:83]
pizza_size: Size of the pizza
- type: chr
- values: “S”, “M”, “L”, “XL”, “XXL”
pizza_category: Category of the pizza
- type: chr
- values: “Classic”, “Supreme”, “Veggie”, “Chicken”
pizza_ingredients: Ingredients used in the pizza
- type: chr
Ingredients Table:
Shape: 518 rows × 4 columns Columns: pizza_name_id: Identifier linking the pizza to its recipe. - type: chr pizza_name: Name of the pizza. - type: chr pizza_ingredients: List of ingredients in the pizza. - type: chr Items_Qty_In_Grams: Quantity of each ingredient in grams. - type: num - range: [5:200]
Για την Domino’s Pizza, η Επιχειρηματική Αναλυτική (ΕΑ) χρησιμοποιείται κυρίως για βελτίωση της ταχύτητας εξυπηρέτησης, πρόβλεψη ζήτησης και καλύτερη εμπειρία πελάτη. Παρακάτω φαίνονται οι βασικές μέθοδοι, οι στόχοι τους και ο τύπος επιχειρηματικής αναλυτικής στον οποίο ανήκουν.
“Demand planning is knowing what our consumers want before they do. If we are doing our job, we know they’re going to have a pizza next Thursday before they do,” quips Darren O’Keefe, Head of Inventory at Domino’s Pizza UK & Ireland Ltd.
Μέθοδος/τεχνική
Στόχος/πρόκληση
Τύπος ΕΑ
“We don’t fall victim to fashionable tech, but rather listen to our customers and internal stakeholders to understand their objectives and visions,” explains Sody Kahlon, Chief Information & Technology Officer at Domino’s Pizza UK & Ireland Ltd. “This then allows us to adopt the most relevant solution to meet their needs. The realm of AI has opened our choices to further increase our personalization, enhance internal efficiencies, derive rapid conclusions from data insights, improve our forecasting, strengthen our cybersecurity, and experiment with novel innovation.”
Μέθοδος/τεχνική
Στόχος/πρόκληση
Τύπος ΕΑ
The company created a data lake consisting of key order information by taking advantage of Amazon Simple Storage Service (Amazon S3) for data storage and AWS Glue for data quering. It also uses Amazon SageMaker to build and train machine learning models to predict the likelihood that an order will be placed, so a store can begin making that order right before it is placed.
Σχέση quantity και total_price Αναμένουμε θετική
συσχέτιση (πολύ κοντά στο 1)
- Ερμηνεία: Όσο περισσότερες πίτσες αγοράζει ένας πελάτης σε μια γραμμή
παραγγελίας, τόσο αυξάνεται το συνολικό κόστος. Αν η συσχέτιση δεν είναι
1.0, είναι γιατί οι πίτσες έχουν διαφορετικές τιμές μονάδας
(unit_price).
Σχέση unit_price και quantity Αναμένουμε θετική
συσχέτιση (>0.5)
- Ερμηνεία: Είναι λογικό οι πίτσες με μεγαλύτερη ζήτηση να έχουν
μεγαλύτερη τιμή ανά τεμάχιο. Εάν η τιμή είναι πολύ κοντά στο μηδέν, αυτό
σημαίνει ότι οι πελάατες αγοράζουν την ίδια ποσότητα πίτσας ανεξάρτητα
απόο την τιμή της.
Σχέση unit_price και total_price Αναμένουμε θετική
συσχέτιση (>0.5)
- Ερμηνεία: Με βάση τις παραπάνω υποθέσεις μας, αναμένουμε και τη σχέση
μεταξύ τιμής τεμαχίου και συνολικής τιμής να είναι θετική. Δηλαδή, όσο
αυξάνεται η μία να αυξάνεται και η άλλη.
# Δημιουργία ενός subset μόνο με τις αριθμητικές μεταβλητές
numeric_vars <- Pizza_Sale[, c("quantity", "unit_price", "total_price")]
# Υπολογισμός του πίνακα συσχέτισης
cor_matrix <- cor(numeric_vars, use = "complete.obs")
# Εμφάνιση του πίνακα
print(cor_matrix)
## quantity unit_price total_price
## quantity 1.000000000 0.007143956 0.5419504
## unit_price 0.007143956 1.000000000 0.8360716
## total_price 0.541950378 0.836071621 1.0000000
# Scatter plot
library(ggplot2)
ggplot(Pizza_Sale, aes(x = unit_price, y = quantity)) +
geom_point(size = 3, alpha = 0.7) +
scale_y_continuous(breaks = seq(0, 10000, by = 2500)) + # από 0 έως 10χιλ, με βήμα 2.5χιλ
labs(
title = "Σχέση τιμής τεμαχίου και ποσότητας",
x = "Τιμή τεμαχίου",
y = "Ποσότητα (σε τεμάχια)"
)
Παρατηρούμε τόσο από τον συντελεστή συσχέτισης όσο και από το διάγραμμα, ότι η τιμή τεμαχίου και η ποσότητα δεν έχουν τόσο ισχυρή σχέση όσο αναμέναμε. Αντίθετα, οι πελάτες φαίνεται να αγοράζουν σχεδόν την ίδια ποσότητα πίτσας ανεξάρτητα από την τιμή.
Εδώ διαπιστώνουμε ότι η αρχική μας υπόθεση ήταν εσφαλμένη, καθώς σημαντικός παράγοντας είναι και το είδος της πίτσας. Δεν αναφερόμαστε στην ίδια πίτσα με διαφορετικές τιμές, αλλά σε διαφορετικές πίτσες. Το γεγονός ότι η ζήτηση δεν επηρεάζεται τόσο από την τιμή τεμαχίου δείχνει ότι η τιμή της κάθε πίτσας είναι αντιπροσωπευτική της αντιλαμβανόμενης αξίας της από τον πελάτη.
# Boxplot
ggplot(Pizza_Sale, aes(x = pizza_category, y = total_price, fill = factor(pizza_category))) +
geom_boxplot() +
scale_y_continuous(breaks = seq(0, 90, by = 2)) + # από 0 έως 90, με βήμα 2
labs(
title = "Σχέση κατηγορίας πίτσας και συνολικής τιμής ενός είδους πίτσας ανά παραγγελία",
x = "Κατηγορία πίτσας",
y = "Συνολική τιμή"
) +
theme(legend.position = "none")
## Warning: Removed 7 rows containing non-finite outside the scale range
## (`stat_boxplot()`).
Παρατηρούμε ότι περισσότερα λεφτά δίνουν οι πελάτες για να αγοράσουν πίτσες των κατηγοριών Veggie και Chicken, αφού η διάμεσός τους φτάνει σχεδόν τα 17$ συνολικής τιμής. Δηλαδή το 50% των πελατών που αγοράζουν Chicken pizza δίνει πάνω από 17 δολλάρια και το 50% των πελατών που αγοράζουν Veggie pizza δίνει πάνω απο 17 δολλάρια.
Επίσης, παρατηρούμε ότι η μεταβλητότητα των τιμών είναι μεγαλύτερη στις Supreme πίτσες, με το εύρος των συνολικών τιμών να κυμαίνεται μεταξύ 16 και 21 δολλαρίων.
Ακόμη, οι περισσότεροι outliers (16) εντοπίζονται στις Classic πίτσες, οι οποίες φαίνεται να έχουν περισσότερες παραγγελίες που “εκτοξεύουν” τον τζίρο.
ggplot(data = Pizza_Sale, aes(x = order_time)) +
geom_histogram(fill = "tomato", color = "white") +
scale_x_datetime(
breaks = seq(from = min(Pizza_Sale$order_time),
to = max(Pizza_Sale$order_time),
by = "30 min"),
date_labels = "%H:%M"
) +
coord_flip() +
labs(
title = "Πωλήσεις ανά ώρα της ημέρας",
x = "Ώρα της ημέρας",
y = "Συχνότητα"
) +
theme_minimal()
## `stat_bin()` using `bins = 30`. Pick better value `binwidth`.
Παρατηρούμε ότι οι ώρες αιχμής στα Domino’s (πάνω πό 2000 παραγγελίες) είναι μεταξύ 12:00-14:00 και μεταξύ 17:00-19:30. Οι περισσότερες παραγγελίες κατά τη διάρκεια της ημέρας (>3000) είναι μεταξύ 12:30-13:30.
ggplot(Pizza_Sale, aes(x = pizza_category, y = quantity, fill = factor(pizza_category), color = "white")) +
geom_bar(stat = "summary", fun = "sum") +
labs(
x = "Κατηγορία πίτσας",
y = "Ποσότητα"
) +
theme(legend.position = "none")
Παρατηρούμε ότι τις περισσότερες πωλήσεις είχε η κατηγορία Classic, με σχεδόν 15000 τεμάχια, ενώ τελευταία σε πωλήσεις είναι η κατηγορία Chicken, με μικρή διαφορά όμως από τις υπόλοιπες.
total_quantity <- aggregate(Items_Qty_In_Grams ~ pizza_name_id,
data = Pizza_ingredients,
FUN = sum)
price_per_pizza <- aggregate(unit_price ~ pizza_name_id,
data = Pizza_Sale,
FUN = mean)
final <- merge(total_quantity, price_per_pizza, by = "pizza_name_id")
m <- lm(unit_price ~ Items_Qty_In_Grams, data = final)
# Add regression line to plot:
ggplot(final, aes(Items_Qty_In_Grams , unit_price)) +
geom_point() +
geom_abline(aes(intercept = coef(m)[1], slope = coef(m)[2]), colour = "red") +
labs(title = "Σχέση Τιμής Πίτσας και Βάρους Υλικών",
x = "Συνολικό Βάρος (g)",
y = "Τιμή Μονάδας (€)") +
theme_minimal()
Παρατηρούμε ότι όσο αυξάνονται οι ποσότητες των υλικών (σε γραμμάρια) σε μια πίτσα τόσο αυξάνεται και η τιμή της.
plot(m)
# Υπολογισμός βάρους ΚΑΙ πλήθους υλικών ανά πίτσα
ingredients_summary <- aggregate(Items_Qty_In_Grams ~ pizza_name_id,
data = Pizza_ingredients,
FUN = function(x) c(Sum = sum(x), Count = length(x)))
# Μετατροπή σε καθαρό dataframe
ingredients_summary <- data.frame(pizza_name_id = ingredients_summary$pizza_name_id,
total_weight = ingredients_summary$Items_Qty_In_Grams[,1],
num_ingredients = ingredients_summary$Items_Qty_In_Grams[,2])
# Merge με τις τιμές
final2 <- merge(ingredients_summary, price_per_pizza, by = "pizza_name_id")
# Μοντέλο
m2 <- lm(unit_price ~ total_weight + num_ingredients, data = final2)
# Add regression line to plot:
ggplot(final2, aes(x = total_weight, y = unit_price)) +
geom_point(aes(size = num_ingredients), color = "steelblue") +
geom_smooth(method = "lm", formula = y ~ x, color = "red") +
labs(title = "Πολυμεταβλητό Μοντέλο: Τιμή vs Βάρος & Πλήθος Υλικών",
subtitle = "Το μέγεθος των σημείων αντιστοιχεί στον αριθμό των υλικών",
x = "Συνολικό Βάρος (g)",
y = "Τιμή Μονάδας (€)",
size = "Πλήθος Υλικών") +
theme_minimal()
Παρατηρούμε ότι όσο αυξάνονται οι ποσότητες των υλικών (σε γραμμάρια) σε μια πίτσα τόσο αυξάνεται και η τιμή της. Όσον αφορά το πλήθος των διαφορετικών υλικών ανά πίτσα, παρατηρούμε ότι δεν υπάρχει άμεση συσχέτιση με την τιμή της πίτσας, καθώς υπάρχουν μεγάλες κουκκίδες σε όλο το μήκος του ευθύγραμμου τμήματος.
plot(m2)
SSE1 <- sum(m$residuals^2)
SSE2 <- sum(m2$residuals^2)
SSE1
## [1] 607.7683
SSE2
## [1] 578.6697
Ένα κριτήριο ικανοποιητικής προσέγγισης (εκτίμησης) είναι δυνατόν να στηριχθεί στην ελαχιστοποίηση μιας κατάλληλα επιλεγμένης συνάρτησης της απόκλισης αυτού που παρατηρείται (yi) από αυτό που εκτιμάται ότι πρέπει να παρατηρηθεί (a + bxi).
Επομένως με την προσθήκη της δεύτερης ανεξάρτητης μεταβλητής βελτιώνεται η προσέγγισή μας.
Παίρνουμε ως μοντέλο βάσης το m (άρα ως SST το SSE1) και ως SSE το SSE2. Έτσι:
R_squared <- 1 - (SSE2/SSE1)
R_squared
## [1] 0.04787768
Το R_squared είναι πολύ πιο κοντά στο 0 απ’ ό,τι στο 1.
Το R^2 μας δείχνει την προστιθέμενη αξία από τη χρήση του μοντέλου. R^2 = 0 μας δείχνει ότι δεν υπάρχει βελτίωση πέραν του μοντέλου βάσης. R^2 = 1 σημαίνει ένα τέλειο μοντέλο πρόβλεψης
Συμπεραίνουμε ότι υπάρχει πολύ μικρή προστιθέμενη αξία με την προσθήκη της δεύτερης ανεξάρτητης μεταβλητής. Δεν υπάρχει ιδιαίτερη βελτίωση από το πρώτο μοντέλο στο δεύτερο.