Esempi di Business Analytics/Scorte di magazzino
Caricamento librerie
[modifica | modifica sorgente]library(dplyr)
library(ggplot2)
Parte 1: Dati
[modifica | modifica sorgente]Si tratta di un dataset transnazionale scaricabile da qui : https://archive.ics.uci.edu/ml/datasets/online+retail che contiene tutte le transazioni avvenute tra il 01/12/2010 e il 09/12/2011 per una vendita al dettaglio online non registrata, con sede nel Regno Unito. L'azienda vende principalmente regali unici per tutte le occasioni. Molti clienti dell'azienda sono grossisti.
Informazioni sulle variabili:
- InvoiceNo: numero della fattura. Nominale, un numero integrale di 6 cifre assegnato in modo univoco a ciascuna transazione. Se questo codice inizia con la lettera 'c', indica una cancellazione.
- StockCode: Codice prodotto (articolo). Nominale, un numero integrale di 5 cifre assegnato in modo univoco a ciascun prodotto distinto.
- Description: nome del prodotto (articolo). Nominale.
- Quantity: le quantità di ciascun prodotto (articolo) per transazione. Numerico.
- InvoiceDate: Data e ora della fattura. Numerico, il giorno e l'ora in cui è stata generata ciascuna transazione.
- UnitPrice: prezzo unitario. Numerico, prezzo del prodotto per unità in sterline.
- CustomerID: numero cliente. Nominale, un numero integrale di 5 cifre assegnato in modo univoco a ciascun cliente.
- Country: nome del paese. Nominale, il nome del paese in cui risiede ciascun cliente.
Caricamento dati:
data <- read.csv("data.csv")
Parte 2: Domanda di ricerca
[modifica | modifica sorgente]Si vogliono selezionare i prodotti che conviene tenere in magazzinoin modo da accorciare i tempi di distribuzione della merce. Inoltre si vogliono conoscere i prodotti più redditizi in modo da valutare il modo in cui gestirli.
Parte 3 : Esplorazione dei dati
[modifica | modifica sorgente]Ci sono 135.080 clienti non identificati nel dataset attraverso l'ID. Presumo che siano stati venduti prodotti senza identificare il cliente quindi non li elimino dal dataset.
colSums(is.na(data))
Creo la variabile amount pari al prodotto della quantità per il prezzo relativamente ad ogni articolo ed elimino dal dataset i valori negativi di questa variabile...
data$amount <- data$Quantity*data$UnitPrice
data <- data[which(data$amount>0),]
Creo la variabile media delle vendite relativamente ad ogni articolo:
df<-data %>%
group_by(StockCode) %>%
summarise(mean_sales = mean(amount))
cat("Numero prodotti venduti =",nrow(df))
Il coefficiente di variazione CV misura la variabilità delle vendite degli articoli misurata tramite la deviazione standard sd in relazione alla media delle vendite . Maggiore sarà CV maggiore sarà la variabilità delle vendite per cui non sarebbe utile mettere i prodotti in magazzino. Se invece la variabilità delle vendite è bassa conviene tenere i prodotti in magazzino.
df1<-data %>%
group_by(StockCode) %>%
summarise(CV = sd(amount)/mean(amount))
df <- cbind(df,CV=df1$CV )
df<- df[which(df$CV>0),]
df %>%
ggplot(aes(CV, mean_sales))+
geom_point()
Valuto gli outliers dello scatterplot relativamente alla media delle vendite per tenerli in magazzino
data %>%
filter(StockCode%in%df$StockCode[df$mean_sales>1000]) %>%
group_by(Description) %>%
summarise(media=mean(amount),CV=sd(amount)/mean(amount)) %>%
arrange(desc(media))
# A tibble: 2 x 3 Description media CV <chr> <dbl> <dbl> 1 "AMAZON FEE" 6881. 1.37 2 "TEA TIME TEA TOWELS " 3022. 0.137
df<- df[which(df$mean_sales<1000),]
df<- df[which(df$CV<10),]
Traccio nuovamente lo scatterplot eliminando gli outliers
df %>%
ggplot(aes(CV, mean_sales))+
geom_point()
Creo 3 clusters dei prodotti in base al coefficiente di variazione CV e alla media delle vendite...:
- prodotti_da_magazzino : vendite elevate e bassa variabilità
- prodotti_da_valutare : vendite elevate e alta variabilità
- prodotti_su_richiesta : vendite basse
df$groups <- ifelse(df$mean_sales<20,"prodotti_su_richiesta",ifelse(df$CV<0.8 ,"prodotti_da_magazzino","prodotti_da_valutare"))
df %>%
ggplot(aes(CV, mean_sales, colour=groups))+
geom_point()
Si visualizzano i 94 prodotti da magazzino ordinati in base alla media delle vendite:
df3<-data %>%
filter(StockCode%in%df$StockCode[df$groups=="prodotti_da_magazzino"]) %>%
group_by(Description) %>%
summarise(media=mean(amount),CV=sd(amount)/mean(amount)) %>%
arrange(desc(media))
write.csv(df3,"table1.csv" , row.names = F)
# A tibble: 94 x 3 Description media CV <chr> <dbl> <dbl> 1 "REGENCY MIRROR WITH SHUTTERS" 219. 0.306 2 "VINTAGE RED KITCHEN CABINET" 214. 0.325 3 "CHEST NATURAL WOOD 20 DRAWERS" 211. 0.565 4 "RUSTIC SEVENTEEN DRAWER SIDEBOARD" 208. 0.291 5 "VINTAGE BLUE KITCHEN CABINET" 184. 0.424 6 "LOVE SEAT ANTIQUE WHITE METAL" 151. 0.598 7 "SCHOOL DESK AND CHAIR " 92.3 0.550 8 "DECORATIVE HANGING SHELVING UNIT" 71.9 0.373 9 "IVORY EMBROIDERED QUILT " 65.7 0.545 10 "RED 3 PIECE RETROSPOT CUTLERY SET" 63.8 0.708 # … with 84 more rows
Si visualizzano i prodotti più redditizi con profitto totale, CV e cluster di appartenenza:
df2<-data %>%
group_by(StockCode,Description) %>%
summarise(sales = sum(amount)) %>%
arrange(desc(sales))
df2<- merge(df2,df, by.x = "StockCode")
df2 %>%
arrange(desc(sales))
write.csv(df2,"table2.csv" , row.names = F)
StockCode Description sales mean_sales CV groups 1 DOT DOTCOM POSTAGE 206248.77 292.13707 1.2176700 prodotti_da_valutare 2 22423 REGENCY CAKESTAND 3 TIER 174484.74 86.50706 2.0101866 prodotti_da_valutare 3 85123A WHITE HANGING HEART T-LIGHT HOLDER 104340.29 46.14517 4.1881840 prodotti_da_valutare 4 47566 PARTY BUNTING 99504.33 58.32610 2.0100718 prodotti_da_valutare 5 85099B JUMBO BAG RED RETROSPOT 94340.05 44.66858 2.3577622 prodotti_da_valutare 6 M Manual 78110.27 243.33417 2.6653826 prodotti_da_valutare 7 POST POSTAGE 78101.88 69.36224 3.5859787 prodotti_da_valutare 8 23084 RABBIT NIGHT LIGHT 66964.99 64.63802 4.0827920 prodotti_da_valutare 9 22086 PAPER CHAIN KIT 50'S CHRISTMAS 64952.29 54.12691 3.7374062 prodotti_da_valutare 10 84879 ASSORTED COLOUR BIRD ORNAMENT 59094.93 39.68766 3.2604433 prodotti_da_valutare ecc. ecc.