Raport

Tamara Lipiejko, Daria Lessnau, Amelia Sørensen, Adrianna Ceynowa

2025-02-02

Wprowadzenie

Celem tego raportu jest analiza zestawu danych, w tym czyszczenie danych, wizualizacja, analiza opisowa oraz wnioskowanie statystyczne.

Obiektem analizy był zbiór danych, będący jedną z historycznych sprzedaży firmy supermarketów Biedronka, która została zarejestrowana w 3 różnych oddziałach przez 3 miesiące, od stycznia 2019 r. do marca 2019 r.

Dane jakie zostały zebrane są następujące

  • Invoice id - Numer identyfikacyjny faktury sprzedaży wygenerowany komputerowo

  • Branch - Oddział supercentrum

  • City - Lokalizacja supercentrów

  • Customer type - Typ klientów, zarejestrowany przez członków dla klientów korzystających z karty członkowskiej i normalny dla klientów bez karty członkowskiej

  • Gender - Płeć klienta

  • Product line - Ogólne grupy kategoryzacji przedmiotów - akcesoria elektroniczne, akcesoria modowe, żywność i napoje, zdrowie i uroda, dom i styl życia, sport i podróże

  • Unit price - Cena każdego produktu w $

  • Quantity - Liczba produktów zakupionych przez klienta

  • Tax - Opłata podatkowa w wysokości 5% dla klienta dokonującego zakupu

  • Date - Data zakupu

  • Time - Czas zakupu

  • Payment - Sposób płatności klienta - gotówka, karta kredytowa i portfel elektroniczny

  • COGS - Koszt sprzedawanych towarów

  • Gross margin percentage - Procentowa marża brutto

  • Gross income - Dochód brutto

  • Rating - Ocena satysfakcji klientów dotycząca ich ogólnego doświadczenia zakupowego

Data Cleansing i Wrangling

Wczytanie danych

# Wczytanie danych
library(readr)
supermarket_new <- read_csv("supermarket_new.csv")

# Podstawowa charakterystyka danych
summary(supermarket_new)
##   Invoice ID           Branch              City           Customer type     
##  Length:1000        Length:1000        Length:1000        Length:1000       
##  Class :character   Class :character   Class :character   Class :character  
##  Mode  :character   Mode  :character   Mode  :character   Mode  :character  
##                                                                             
##                                                                             
##                                                                             
##                                                                             
##     Gender          Product line         Unit price       Quantity    
##  Length:1000        Length:1000        Min.   :10.08   Min.   : 1.00  
##  Class :character   Class :character   1st Qu.:32.88   1st Qu.: 3.00  
##  Mode  :character   Mode  :character   Median :55.23   Median : 5.00  
##                                        Mean   :55.67   Mean   : 5.51  
##                                        3rd Qu.:77.94   3rd Qu.: 8.00  
##                                        Max.   :99.96   Max.   :10.00  
##                                                                       
##      Tax 5%            Total             Date               Time         
##  Min.   : 0.5085   Min.   :  10.68   Length:1000        Length:1000      
##  1st Qu.: 5.9249   1st Qu.: 124.42   Class :character   Class1:hms       
##  Median :12.0880   Median : 253.85   Mode  :character   Class2:difftime  
##  Mean   :15.3794   Mean   : 322.97                      Mode  :numeric   
##  3rd Qu.:22.4453   3rd Qu.: 471.35                                       
##  Max.   :49.6500   Max.   :1042.65                                       
##                                                                          
##    Payment               cogs        gross margin percentage  gross income    
##  Length:1000        Min.   : 10.17   Min.   :4.762           Min.   : 0.5085  
##  Class :character   1st Qu.:118.50   1st Qu.:4.762           1st Qu.: 5.9861  
##  Mode  :character   Median :241.76   Median :4.762           Median :12.1508  
##                     Mean   :307.59   Mean   :4.762           Mean   :15.4374  
##                     3rd Qu.:448.90   3rd Qu.:4.762           3rd Qu.:22.4295  
##                     Max.   :993.00   Max.   :4.762           Max.   :49.6500  
##                                                              NA's   :150      
##      Rating      
##  Min.   : 4.000  
##  1st Qu.: 5.600  
##  Median : 7.000  
##  Mean   : 6.996  
##  3rd Qu.: 8.500  
##  Max.   :10.000  
##  NA's   :150

Dane zawierają informacje o sprzedaży, takie jak lokalizacja sklepów, ceny jednostkowe, ilości zakupionych produktów, rodzaj płatności i oceny klientów.

Czyszczenie danych

Sprawdzenie braków danych

Braki danych mogą wskazywać na problemy w procesie zbierania informacji. Sprawdzamy, które zmienne są najbardziej narażone na niekompletność.

# Liczba braków danych
n_miss(supermarket_new)
## [1] 400
pct_miss(supermarket_new)
## [1] 2.352941
miss_var_summary(supermarket_new)
## # A tibble: 17 × 3
##    variable                n_miss pct_miss
##    <chr>                    <int>    <num>
##  1 gross income               150       15
##  2 Rating                     150       15
##  3 City                       100       10
##  4 Invoice ID                   0        0
##  5 Branch                       0        0
##  6 Customer type                0        0
##  7 Gender                       0        0
##  8 Product line                 0        0
##  9 Unit price                   0        0
## 10 Quantity                     0        0
## 11 Tax 5%                       0        0
## 12 Total                        0        0
## 13 Date                         0        0
## 14 Time                         0        0
## 15 Payment                      0        0
## 16 cogs                         0        0
## 17 gross margin percentage      0        0

Usuwanie wartości specjalnych i zastosowanie reguł walidacji

Reguły walidacji pomagają w wykrywaniu i eliminowaniu błędnych wartości, co poprawia jakość analizowanych danych.

is.special <- function(x) {
  if (is.numeric(x)) !is.finite(x) else is.na(x)
}
for (n in colnames(supermarket_new)) {
  is.na(supermarket_new[[n]]) <- is.special(supermarket_new[[n]])
}

# Reguły walidacji
rules <- validator(
  `Unit price` > 0,
  Total <= `Unit price` * Quantity + `Tax 5%`,
  Rating >= 1 & Rating <= 10
)

# Zastosowanie reguł
validation_results <- confront(supermarket_new, rules)
summary(validation_results)
##   name items passes fails nNA error warning
## 1   V1  1000   1000     0   0 FALSE   FALSE
## 2   V2  1000    843   157   0 FALSE   FALSE
## 3   V3  1000    850     0 150 FALSE   FALSE
##                                    expression
## 1                            `Unit price` > 0
## 2 Total <= `Unit price` * Quantity + `Tax 5%`
## 3 Rating - 1 >= -1e-08 & Rating - 10 <= 1e-08
czyste_dane <-
  supermarket_new %>%
  replace_errors(rules)

errors_removed(czyste_dane)
## call:  locate_errors(data, x, ref, ..., cl = cl, Ncpus = Ncpus) 
## located  0  error(s).
## located  400  missing value(s).
## Use 'summary', 'values', '$errors' or '$weight', to explore and retrieve the errors.

Wizualizacja Danych

Braki danych

Wykrezy wizualizujące braki danych pomagają określić, które zmienne najczęściej zawierają braki.

# Mapa braków danych
vis_miss(supermarket_new)

# UpSet plot dla współwystępowania braków
library(naniar)
gg_miss_upset(supermarket_new, nsets = 3)

Na podstawie wykresów można stwierdzić, że braki danych występują w kolumnach City, Gross income oraz Rating. Najczęściej brakuje danych w pojedynczych kolumnach, co może sugerować niezależne mechanizmy ich utraty. Najwięcej braków występuje w kolumnie City (116), następnie Rating (113), a potem gross income (20).

Wykresy zależności

Analiza pokazuje, czy oceny klientów mają związek z dochodem brutto oraz czy różnią się w zależności od lokalizacji sklepu. Brak wyraźnej zależności między dochodem brutto a oceną – punkty są rozrzucone losowo, co sugeruje brak silnej korelacji. Oznacza to, że wyższy dochód brutto niekoniecznie prowadzi do wyższej oceny.

# Zależność między Rating a Gross Income
ggplot(supermarket_new, aes(x = `gross income`, y = Rating)) +
  geom_point(aes(color = City), size = 2) +
  theme_minimal()

# Zależność między Rating a City
ggplot(supermarket_new, aes(x = Rating, y = City)) +
  geom_point(color = "darkorange", size = 2) +
  theme_minimal()

Rozkład punktów sugeruje, że oceny są podobne we wszystkich miastach – brak wyraźnych trendów wskazujących, że w jednym mieście oceny są wyższe lub niższe.

czyste_dane <- hotdeck(supermarket_new)

# Remove all *_imp columns
czyste_dane <- czyste_dane[, !grepl("_imp$", names(czyste_dane))]

Wykresy podsumowujące sprzedaż

Wykres przedstawia procentowy podział całkowitej sprzedaży (w tysiącach) w trzech miastach: Mandalay, Naypyitaw i Yangon. Yangon osiągnął najwyższy udział w sprzedaży (34,2%), następnie Naypyitaw (33,1%), a Mandalay ma najniższy wynik (32,7%). Różnice między miastami są niewielkie, co wskazuje na stosunkowo równomierny rozkład sprzedaży.

Wykres przedstawia procentowy rozkład zakupów według płci w różnych liniach produktów. Kobiety (oznaczone kolorem czerwonym) dominują w większości kategorii zakupowych, zwłaszcza w „Fashion accessories” i „Health and beauty”. Mężczyźni (oznaczeni kolorem niebieskim) mają większy udział w zakupach „Electronic accessories” oraz „Sports and travel”. W innych kategoriach, takich jak „Food and beverages” oraz „Home and lifestyle”, podział jest bardziej zrównoważony.

Wykres przedstawia zależność między liczbą zakupionych produktów a całkowitą ceną z podatkiem. Widoczna jest rosnąca tendencja – im więcej produktów kupiono, tym wyższa była łączna cena. Boxploty wskazują na zmienność cen dla różnych ilości zakupionych produktów, a zakresy wartości sugerują, że ceny mogą się różnić w zależności od rodzaju produktów.


Analiza Opisowa

Statystyki opisowe dla wybranych zmiennych

Przedstawione statystyki porównują różne cechy klientów pod względem płci (kobiety i mężczyźni) oraz analizują różnice w ich zachowaniach zakupowych. Nie stwierdzono istotnych statystycznie różnic między kobietami a mężczyznami pod względem miejsca zamieszkania (p = 0,14). Podział klientów na członków programu lojalnościowego i klientów zwykłych nie wykazuje istotnych różnic między płciami (p = 0,2). Wybory dotyczące kategorii produktów są porównywalne między kobietami a mężczyznami (p = 0,3). Średnia ocena zakupów jest zbliżona w obu grupach i wynosi 7,10 (kobiety) oraz 6,90 (mężczyźni), bez istotnej statystycznie różnicy (p > 0,9). Natomiast ilość kupowanych produktów różni się znacząco (p = 0,020). Kobiety kupują średnio więcej (mediana 6,00) niż mężczyźni (mediana 5,00). Nie zaobserwowano znaczących różnic w strukturze demograficznej klientów ani w wyborze kategorii produktów. Jednak kobiety kupują średnio większe ilości produktów niż mężczyźni, co jest jedyną istotną różnicą statystyczną w analizowanych danych.

czyste_dane %>%
  select(City, Gender, `Customer type`, `Product line`, Total, Rating, Quantity) %>%
  tbl_summary(by = Gender) %>%
  add_p() %>%
  bold_labels()
Characteristic Female
N = 501
1
Male
N = 499
1
p-value2
City

0.14
    Mandalay 163 (33%) 170 (34%)
    Naypyitaw 176 (35%) 147 (29%)
    Yangon 162 (32%) 182 (36%)
Customer type

0.2
    Member 261 (52%) 240 (48%)
    Normal 240 (48%) 259 (52%)
Product line

0.3
    Electronic accessories 84 (17%) 86 (17%)
    Fashion accessories 96 (19%) 82 (16%)
    Food and beverages 90 (18%) 84 (17%)
    Health and beauty 64 (13%) 88 (18%)
    Home and lifestyle 79 (16%) 81 (16%)
    Sports and travel 88 (18%) 78 (16%)
Total 273 (133, 486) 244 (118, 457) 0.10
Rating 7.10 (5.50, 8.50) 6.90 (5.60, 8.50) >0.9
Quantity 6.00 (3.00, 8.00) 5.00 (3.00, 8.00) 0.020
1 n (%); Median (Q1, Q3)
2 Pearson’s Chi-squared test; Wilcoxon rank sum test

Macierz korelacji

Macierz korelacji przedstawia zależności między czterema zmiennymi: cena jednostkowa (Unit price), ilość (Quantity), łączna wartość (Total) oraz podatek 5% (Tax 5%).

Cena jednostkowa (Unit price) nie wykazuje istotnej korelacji z ilością (Quantity), co oznacza, że liczba kupowanych produktów nie zależy od ceny jednostkowej. Jest dodatnio skorelowana z całkowitą wartością zakupu (Total) oraz podatkiem 5% (Tax 5%), co jest logiczne, ponieważ wyższa cena jednostkowa wpływa na wzrost wartości zakupu i podatku.

Ilość (Quantity) nie jest skorelowana z ceną jednostkową, co sugeruje, że klienci kupują podobne ilości produktów niezależnie od ich ceny. Jest silnie dodatnio skorelowana z całkowitą wartością zakupu (Total), co oznacza, że im większa liczba zakupionych jednostek, tym wyższa wartość transakcji.

Łączna wartość (Total) jest dodatnio skorelowana zarówno z ilością, jak i ceną jednostkową, co potwierdza, że wzrost któregokolwiek z tych czynników prowadzi do wzrostu całkowitej wartości transakcji. Wykazuje silną dodatnią korelację z podatkiem 5% (Tax 5%), ponieważ podatek jest naliczany jako stały procent od wartości zakupu.

Podatek 5% (Tax 5%) jest w pełni skorelowany z łączną wartością zakupu (Total), co wynika z faktu, że jest on obliczany jako stały procent od tej wartości.

# Obliczanie korelacji
numeric_data <- czyste_dane %>% select(`Unit price`, Quantity, Total, `Tax 5%`)
corr_matrix <- cor(numeric_data, use = "complete.obs")

# Wizualizacja macierzy korelacji
corrplot(corr_matrix, method = "color")


Wnioskowanie Statystyczne

Porównanie cen jednostkowych między liniami produktów

Wykorzystano test Welcha ANOVA, który jest stosowany, gdy wariancje między grupami mogą się różnić. Wynik testu wskazuje wartość F(5, 462.07) = 0.44, z p = 0.82, co oznacza, że różnice w cenach jednostkowych między kategoriami produktów nie są istotne statystycznie.

Electronic accessories: średnia cena = 53.55 Fashion accessories: średnia cena = 57.15 Food and beverages: średnia cena = 56.01 Health and beauty: średnia cena = 54.85 Home and lifestyle: średnia cena = 55.32 Sports and travel: średnia cena = 56.99 Wartości średnie są bardzo zbliżone, co dodatkowo potwierdza brak istotnych różnic między liniami produktowymi.

Przeprowadzona analiza wykazała, że ceny jednostkowe produktów w różnych kategoriach nie różnią się znacząco. Wartość p = 0.82 sugeruje, że wszelkie zaobserwowane różnice mogą wynikać z losowej zmienności, a nie rzeczywistych rozbieżności w cenach

czyste_dane %>%
  ggbetweenstats(
    x = `Product line`,
    y = `Unit price`,
    pairwise.comparisons = TRUE,
    p.adjust.method = "bonferroni",
    ggtheme = theme_minimal()
  )

Porównanie cen jednostkowych według typu klienta

Wykres przedstawia porównanie cen jednostkowych produktów w zależności od typu klienta – członków programu lojalnościowego („Member”) oraz klientów zwykłych („Normal”). Średnia cena jednostkowa dla klientów „Member” wynosi 56,21, a dla klientów „Normal” 55,14. Różnica między grupami jest niewielka i nieistotna statystycznie. Test t-Studenta dla prób o niejednakowych wariancjach (t_Welch) dał wynik t(997.8) = 0.64, p = 0.52, co oznacza, że nie ma istotnej różnicy między grupami na poziomie istotności 0.05. Wartość efektu Hedgesa (g_Hedges) wynosi 0.04, co wskazuje na bardzo mały efekt.

Przedział ufności dla różnicy średnich wynosi [-0.08, 0.16], co oznacza, że rzeczywista różnica może być bliska zeru, a nawet działać w przeciwnym kierunku. Bayesowski współczynnik wiarygodności (log_BF10 = 2.45) sugeruje, że nie ma silnych dowodów na różnicę między grupami.

Ogólnie rzecz biorąc, analiza pokazuje, że ceny jednostkowe produktów nie różnią się istotnie między członkami programu lojalnościowego a klientami zwykłymi.

czyste_dane %>%
  ggbetweenstats(
    x = `Customer type`,
    y = `Unit price`,
    pairwise.comparisons = TRUE,
    p.adjust.method = "bonferroni",
    ggtheme = theme_minimal()
  )


Podsumowanie i Wnioski

Przeprowadzona analiza danych sprzedażowych supermarketów Biedronka pozwoliła na wyciągnięcie kilku istotnych wniosków.

Jakość danych – Zidentyfikowano brakujące wartości w zmiennych City, Gross income oraz Rating. Po przeprowadzeniu czyszczenia danych i imputacji braków możliwe było przeprowadzenie dalszej analizy bez istotnych zakłóceń.

Struktura sprzedaży – Sprzedaż była równomiernie rozłożona pomiędzy trzy oddziały, bez wyraźnych różnic w generowanych przychodach.

Profil klientów – Kobiety częściej kupowały produkty z kategorii Fashion accessories oraz Health and beauty, podczas gdy mężczyźni częściej wybierali Electronic accessories i Sports and travel. Różnice te jednak nie miały dużego wpływu na ogólną wartość sprzedaży.

Zachowania zakupowe – Kobiety kupowały średnio więcej produktów niż mężczyźni, co było jedyną istotną różnicą statystyczną w analizowanych danych. Nie stwierdzono istotnych różnic w wyborze sposobu płatności ani w ocenach satysfakcji klientów w zależności od płci.

Ceny jednostkowe produktów – Testy statystyczne nie wykazały istotnych różnic w cenach jednostkowych pomiędzy poszczególnymi kategoriami produktów. Oznacza to, że różne linie produktowe mają zbliżone ceny, co może wynikać z polityki cenowej firmy.

Ocena klientów a dochód brutto – Nie zaobserwowano istotnej korelacji między dochodem brutto a oceną klientów. Oznacza to, że wysokość zarobków klientów nie wpływa znacząco na ich poziom satysfakcji z zakupów.

Podsumowując, analiza wykazała, że sprzedaż w badanym okresie była stabilna i nie występowały duże różnice w zachowaniach zakupowych klientów w zależności od lokalizacji czy płci. Wyniki te mogą być przydatne w optymalizacji oferty oraz strategii marketingowej supermarketów Biedronka, szczególnie w kontekście docelowych grup klientów oraz polityki cenowej.