---
title: "PROJEKT BADAWCZY – Metody Probabilistyczne"
author: "Grupa7_45244_47633_45702_2371_ProjektStatystyka"
date: "2026-06-05"
output: 
  html_document:
    toc: true
    toc_float: true
---



## Część I: Metryczka i Dane

### 1. Skład grupy i podział ról

| Imię i nazwisko | Nr indeksu | Rola w projekcie |
| --- | --- | --- |
| **Jakub Dyba** | 45244 | **Osoba A** – Pozyskanie i wczytanie danych z Kaggle, czyszczenie i konwersja typów, przygotowanie definicji zmiennych (Część I). Analiza parametrów opisowych i rozkładu dla wagi paczki z wnioskami (Część II). |
| **Martyna Bulanda** | 47633 | **Osoba B** – Prawdopodobieństwo (Część III). Zdefiniowanie zdarzeń (czas dostawy, ocena klienta), obliczenie prawdopodobieństw, sprawdzanie niezależności oraz wizualizacje z biznesową interpretacją. |
| **Krystian Adamelak** | 45702 | **Osoba C** – Wnioskowanie statystyczne (Część IV). Wyznaczenie przedziałów ufności oraz weryfikacja hipotez statystycznych (t-Studenta, ANOVA, Chi-kwadrat) wraz ze sprawdzaniem założeń i interpretacją p-value. |
| **Piotr Czajkowski** | 2371 | **Osoba D** – Korelacja, regresja i skład (Część V). Wykonanie macierzy korelacji, zbudowanie modelu regresji liniowej dla wagi, interpretacja R² i współczynników oraz ostateczny skład całego raportu HTML/PDF. |

### 2. Opis zbioru danych

* **Pochodzenie:** Zbiór danych *"E-Commerce Shipping Dataset"* pochodzi z ogólnodostępnej platformy Kaggle i dotyczy branży e-commerce (wysyłka i logistyka).
* **Link do źródła:** [https://www.kaggle.com/datasets/prachi13/customer-analytics](https://www.kaggle.com/datasets/prachi13/customer-analytics)
* **Wielkość zbioru:** Zbiór zawiera 10 999 obserwacji oraz 12 zmiennych (jakościowych i ilościowych).

**Definicje zmiennych:**

1. `ID`: Unikalny numer identyfikujący klienta/zamówienie (numeryczna).
2. `Warehouse_block`: Blok magazynowy firmy (jakościowa: A, B, C, D, E, F).
3. `Mode_of_Shipment`: Tryb transportu przesyłki (jakościowa: Flight, Road, Ship).
4. `Customer_care_calls`: Liczba wykonanych połączeń do biura obsługi klienta (ilościowa dyskretna).
5. `Customer_rating`: Ocena wystawiona przez klienta w skali od 1 do 5 (porządkowa).
6. `Cost_of_the_Product`: Koszt zakupionego produktu w USD (ilościowa).
7. `Prior_purchases`: Liczba wcześniejszych zakupów (ilościowa dyskretna).
8. `Product_importance`: Kategoryzacja ważności produktu (jakościowa: low, medium, high).
9. `Gender`: Płeć klienta (jakościowa: F - Kobieta, M - Mężczyzna).
10. `Discount_offered`: Wartość zaproponowanego rabatu (ilościowa).
11. `Weight_in_gms`: Waga paczki w gramach (ilościowa ciągła).
12. `Reached.on.Time_Y.N`: Informacja, czy dostawa była zrealizowana na czas (jakościowa binarna, 1/0).

### 3. Wczytanie i czyszczenie danych


``` r
dane <- fread("Train.xls - Train.xls.csv")

liczba_brakow <- sum(is.na(dane))
print(paste("Całkowita liczba braków danych w zbiorze wynosi:", liczba_brakow))
## [1] "Całkowita liczba braków danych w zbiorze wynosi: 0"
dane[, Warehouse_block := as.factor(Warehouse_block)]
dane[, Mode_of_Shipment := as.factor(Mode_of_Shipment)]
dane[, Product_importance := factor(Product_importance, levels = c("low", "medium", "high"))]
dane[, Gender := as.factor(Gender)]
dane[, Reached.on.Time_Y.N := as.factor(Reached.on.Time_Y.N)]

str(dane)
## Classes 'data.table' and 'data.frame':   10999 obs. of  12 variables:
##  $ ID                 : int  1 2 3 4 5 6 7 8 9 10 ...
##  $ Warehouse_block    : Factor w/ 5 levels "A","B","C","D",..: 4 5 1 2 3 5 4 5 1 2 ...
##  $ Mode_of_Shipment   : Factor w/ 3 levels "Flight","Road",..: 1 1 1 1 1 1 1 1 1 1 ...
##  $ Customer_care_calls: int  4 4 2 3 2 3 3 4 3 3 ...
##  $ Customer_rating    : int  2 5 2 3 2 1 4 1 4 2 ...
##  $ Cost_of_the_Product: int  177 216 183 176 184 162 250 233 150 164 ...
##  $ Prior_purchases    : int  3 2 4 4 3 3 3 2 3 3 ...
##  $ Product_importance : Factor w/ 3 levels "low","medium",..: 1 1 1 2 2 2 1 1 1 2 ...
##  $ Gender             : Factor w/ 2 levels "F","M": 1 2 2 2 1 1 1 1 1 1 ...
##  $ Discount_offered   : int  44 59 48 10 46 12 3 48 11 29 ...
##  $ Weight_in_gms      : int  1233 3088 3374 1177 2484 1417 2371 2804 1861 1187 ...
##  $ Reached.on.Time_Y.N: Factor w/ 2 levels "0","1": 2 2 2 2 2 2 2 2 2 2 ...
##  - attr(*, ".internal.selfref")=<externalptr>

Część II: Parametry i Rozkłady (Zmienne Jednowymiarowe)

1. Analiza opisowa zmiennej Weight_in_gms

waga <- dane$Weight_in_gms
n <- length(waga)

srednia <- mean(waga)
mediana <- median(waga)
odchylenie_std <- sd(waga)

m2 <- sum((waga - srednia)^2) / n
m3 <- sum((waga - srednia)^3) / n
m4 <- sum((waga - srednia)^4) / n

skosnosc <- m3 / (m2^(3/2))
kurtoza <- m4 / (m2^2)

parametry <- data.frame(
  Średnia = round(srednia, 2),
  Mediana = mediana,
  Odchylenie_Std = round(odchylenie_std, 2),
  Skośność = round(skosnosc, 4),
  Kurtoza = round(kurtoza, 4)
)

print(parametry)
##   Średnia Mediana Odchylenie_Std Skośność Kurtoza
## 1 3634.02    4149        1635.38  -0.2497  1.5524

2. Dopasowanie modelu (Histogram i krzywa gęstości)

ggplot(dane, aes(x = Weight_in_gms)) +
  geom_histogram(aes(y = after_stat(density)), bins = 40, fill = "lightblue", color = "darkblue", alpha = 0.7) +
  stat_function(fun = dnorm, args = list(mean = srednia, sd = odchylenie_std), color = "red", linewidth = 1.2) +
  labs(
    title = "Histogram wagi paczek (Weight_in_gms) z krzywą rozkładu normalnego",
    x = "Waga paczki [g]",
    y = "Gęstość (Density)"
  ) +
  theme_minimal()

3. Wniosek: Interpretacja modelu rozkładu

Na podstawie obliczonych parametrów oraz wizualizacji stwierdza się, że rozkład normalny nie pasuje do danych dotyczących wagi paczek.

  1. Skośność i przesunięcie: Średnia waga (3634 g) jest niższa niż mediana (4149 g), co oznacza asymetrię lewostronną (skośność = -0.25). Rozkład normalny musiałby być idealnie symetryczny.
  2. Kurtoza: Wynik na poziomie 1.55 świadczy o tym, że rozkład jest platykurtyczny (spłaszczony). W rozkładzie normalnym kurtoza wynosi dokładnie 3.
  3. Bimodalność: Histogram ewidentnie ukazuje dwa osobne skupiska danych (tzw. rozkład bimodalny) – jedno dla lżejszych paczek (ok. 1000–2000 g) i drugie dla cięższych (ok. 4000–6000 g). Krzywa rozkładu normalnego (czerwona linia) nie jest w stanie opisać dwóch takich szczytów jednocześnie.

Część III: Prawdopodobieństwo

1. Definicja zdarzeń

W analizie zdefiniowano dwa zdarzenia:

  • Zdarzenie A = „dostawa była na czas” → kolumna Reached.on.Time_Y.N == 1
  • Zdarzenie B = „klient dał wysoką ocenę” → kolumna Customer_rating >= 4
# Upewniamy się, że kolumna jest numeryczna do obliczeń
dane_num <- copy(dane)
dane_num[, Reached.on.Time_Y.N_num := as.numeric(as.character(Reached.on.Time_Y.N))]

n_total <- nrow(dane_num)

# Zdarzenie A: dostawa na czas
A <- dane_num$Reached.on.Time_Y.N_num == 1

# Zdarzenie B: wysoka ocena klienta (>= 4)
B <- dane_num$Customer_rating >= 4

2. Obliczenie prawdopodobieństw

P_A     <- mean(A)
P_B     <- mean(B)
P_AiB   <- mean(A & B)
P_A_B   <- P_AiB / P_B   # P(A|B) = P(A∩B) / P(B)

cat("P(A)   = P(dostawa na czas)              =", round(P_A,   4), "\n")
## P(A)   = P(dostawa na czas)              = 0.5967
cat("P(B)   = P(wysoka ocena klienta)         =", round(P_B,   4), "\n")
## P(B)   = P(wysoka ocena klienta)         = 0.3964
cat("P(A∩B) = P(dostawa na czas I wysoka ocena) =", round(P_AiB, 4), "\n")
## P(A∩B) = P(dostawa na czas I wysoka ocena) = 0.2382
cat("P(A|B) = P(dostawa na czas | wysoka ocena) =", round(P_A_B, 4), "\n")
## P(A|B) = P(dostawa na czas | wysoka ocena) = 0.6009

3. Sprawdzenie niezależności zdarzeń

Dwa zdarzenia A i B są niezależne, jeśli spełniony jest warunek: \[P(A \cap B) = P(A) \cdot P(B)\] Co jest równoważne: \(P(A|B) = P(A)\)

P_A_times_P_B <- P_A * P_B

cat("P(A) × P(B)     =", round(P_A_times_P_B, 4), "\n")
## P(A) × P(B)     = 0.2365
cat("P(A∩B)          =", round(P_AiB,          4), "\n")
## P(A∩B)          = 0.2382
cat("P(A|B)          =", round(P_A_B,           4), "\n")
## P(A|B)          = 0.6009
cat("P(A)            =", round(P_A,             4), "\n")
## P(A)            = 0.5967
cat("\nRóżnica |P(A|B) - P(A)| =", round(abs(P_A_B - P_A), 4), "\n")
## 
## Różnica |P(A|B) - P(A)| = 0.0042
if (abs(P_A_B - P_A) < 0.01) {
  cat("Wniosek: Zdarzenia A i B są NIEZALEŻNE (różnica < 0.01)\n")
} else {
  cat("Wniosek: Zdarzenia A i B NIE są niezależne (różnica >= 0.01)\n")
}
## Wniosek: Zdarzenia A i B są NIEZALEŻNE (różnica < 0.01)

Wniosek dotyczący niezależności:

Wartość \(P(A|B) \approx\) 0.6009 jest zbliżona do \(P(A) \approx\) 0.5967. Różnica wynosi 0.0042, co oznacza, że zdarzenia A i B są praktycznie niezależne — wysoka ocena klienta nie ma istotnego wpływu na to, czy dostawa była na czas.

4. Tabela kontyngencji

tab <- table(
  "Dostawa na czas (A)" = factor(A, labels = c("Nie (A=0)", "Tak (A=1)")),
  "Wysoka ocena (B)"    = factor(B, labels = c("Nie (B=0)", "Tak (B=1)"))
)

print(tab)
##                    Wysoka ocena (B)
## Dostawa na czas (A) Nie (B=0) Tak (B=1)
##           Nie (A=0)      2696      1740
##           Tak (A=1)      3943      2620
cat("\nTabela z udziałami procentowymi:\n")
## 
## Tabela z udziałami procentowymi:
print(round(prop.table(tab) * 100, 2))
##                    Wysoka ocena (B)
## Dostawa na czas (A) Nie (B=0) Tak (B=1)
##           Nie (A=0)     24.51     15.82
##           Tak (A=1)     35.85     23.82

5. Wizualizacja wyników

library(ggplot2)

# --- Wykres 1: Słupkowy grouped – rozkład terminowości wg oceny klienta ---
dane_plot <- dane_num[, .(
  Terminowosc = ifelse(Reached.on.Time_Y.N_num == 1, "Na czas", "Spóźniona"),
  Ocena_kat   = ifelse(Customer_rating >= 4, "Wysoka ocena (≥4)", "Niska ocena (<4)")
)]

df_prop <- as.data.frame(prop.table(table(dane_plot$Ocena_kat, dane_plot$Terminowosc), margin = 1) * 100)
colnames(df_prop) <- c("Ocena", "Terminowosc", "Procent")

p1 <- ggplot(df_prop, aes(x = Ocena, y = Procent, fill = Terminowosc)) +
  geom_bar(stat = "identity", position = "dodge", width = 0.6) +
  geom_text(aes(label = paste0(round(Procent, 1), "%")),
            position = position_dodge(width = 0.6), vjust = -0.4, size = 3.5) +
  scale_fill_manual(values = c("Na czas" = "#2ecc71", "Spóźniona" = "#e74c3c")) +
  labs(
    title    = "Terminowość dostawy w zależności od oceny klienta",
    subtitle = "Udział procentowy w obrębie każdej grupy ocen",
    x        = "Kategoria oceny klienta",
    y        = "Udział [%]",
    fill     = "Terminowość dostawy"
  ) +
  theme_minimal(base_size = 12) +
  theme(legend.position = "top")

# --- Wykres 2: Wizualizacja prawdopodobieństw P(A), P(B), P(A∩B), P(A|B) ---
prob_df <- data.frame(
  Prawdopodobienstwo = c("P(A)\nDostawa na czas",
                         "P(B)\nWysoka ocena",
                         "P(A∩B)\nOba zdarzenia",
                         "P(A|B)\nDostawa na czas\n| wysoka ocena"),
  Wartosc = c(P_A, P_B, P_AiB, P_A_B)
)

p2 <- ggplot(prob_df, aes(x = Prawdopodobienstwo, y = Wartosc, fill = Prawdopodobienstwo)) +
  geom_bar(stat = "identity", width = 0.55, show.legend = FALSE) +
  geom_text(aes(label = round(Wartosc, 4)), vjust = -0.4, size = 4) +
  scale_fill_brewer(palette = "Set2") +
  scale_y_continuous(limits = c(0, 0.75)) +
  labs(
    title    = "Zestawienie obliczonych prawdopodobieństw",
    subtitle = "A = dostawa na czas, B = wysoka ocena klienta (≥4)",
    x        = NULL,
    y        = "Prawdopodobieństwo"
  ) +
  theme_minimal(base_size = 12)

print(p1)

print(p2)

6. Interpretacja biznesowa

Na podstawie przeprowadzonej analizy probabilistycznej można sformułować następujące wnioski:

  1. P(A) = 0.5967 – około 59.7% wszystkich dostaw nie dotarło na czas (wartość 1 w kolumnie Reached.on.Time_Y.N oznacza opóźnienie zgodnie z opisem zbioru).

  2. P(B) = 0.3964 – około 39.6% klientów wystawiło wysoką ocenę (≥ 4).

  3. P(A|B) ≈ P(A) – Prawdopodobieństwo opóźnienia dostawy wśród klientów z wysoką oceną (0.6009) jest niemal identyczne jak ogólne prawdopodobieństwo opóźnienia (0.5967). Różnica wynosi jedynie 0.0042.

  4. Wniosek biznesowy: Wyniki wskazują, że ocena klienta i terminowość dostawy są od siebie niezależne. Oznacza to, że klienci wystawiają wysokie oceny niezależnie od tego, czy ich paczka dotarła na czas. Może to sugerować, że na satysfakcję klienta wpływają inne czynniki (np. jakość produktu, obsługa klienta, cena), a sama terminowość dostawy nie jest decydującym wyznacznikiem oceny. Z perspektywy operacyjnej firma powinna zbadać, co faktycznie kształtuje pozytywne oceny — same usprawnienia logistyczne mogą nie przełożyć się bezpośrednio na wyższe noty od klientów.