Οι σύγχρονες διαφημιστικές εταιρείες δραστηριοποιούνται σε ένα εξαιρετικά πολύπλοκο περιβάλλον όπου πολλαπλές στρατηγικές marketing μπορούν να φαίνονται εξίσου ελκυστικές. Για τον λόγο αυτό, η startup επιστρατεύει τη μέθοδο του A/B Testing — μια ελεγχόμενη, τυχαιοποιημένη πειραματική διαδικασία όπου διαφορετικές εκδοχές μιας μεταβλητής (π.χ. διαφημιστικά banners, στοιχεία ιστοσελίδας) εμφανίζονται ταυτόχρονα σε διαφορετικά τμήματα χρηστών, με στόχο τον εντοπισμό της στρατηγικής με το μέγιστο επιχειρηματικό αντίκτυπο.
library(tidyverse)
library(pwr)
library(broom)
library(scales)
library(janitor)
set.seed(39)
# --- Φόρτωση δεδομένων ---
ads <- read_csv("marketing_AB.csv") |>
janitor::clean_names() |>
mutate(
group = factor(test_group, levels = c("psa", "ad")),
converted = as.integer(converted)
)
glimpse(ads)## Rows: 588,101
## Columns: 8
## $ x1 <dbl> 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16…
## $ user_id <dbl> 1069124, 1119715, 1144181, 1435133, 1015700, 1137664, 11…
## $ test_group <chr> "ad", "ad", "ad", "ad", "ad", "ad", "ad", "ad", "ad", "a…
## $ converted <int> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0,…
## $ total_ads <dbl> 130, 93, 21, 355, 276, 734, 264, 17, 21, 142, 209, 47, 6…
## $ most_ads_day <chr> "Monday", "Tuesday", "Tuesday", "Tuesday", "Friday", "Sa…
## $ most_ads_hour <dbl> 20, 22, 18, 10, 14, 10, 13, 18, 19, 14, 11, 13, 20, 13, …
## $ group <fct> ad, ad, ad, ad, ad, ad, ad, ad, ad, ad, ad, ad, ad, ad, …
Το σύνολο δεδομένων περιλαμβάνει 588.101 παρατηρήσεις (χρήστες). Κάθε γραμμή περιέχει τις εξής μεταβλητές:
| Μεταβλητή | Τύπος στην R | Περιγραφή |
|---|---|---|
x1 |
Double | Ο δείκτης της γραμμής (Row index / αρχικό Python DataFrame Index). Αφαιρείται κατά το data cleaning. |
user_id |
Double | Ο μοναδικός κωδικός αναγνώρισης (Unique ID) για κάθε χρήστη. |
test_group |
Character | Κατηγοριοποίηση: "ad" αν ο χρήστης είδε τη
διαφήμιση, "psa" αν είδε το κοινωνικό μήνυμα. |
converted |
Integer | Μεταβλητή αποτελέσματος: 1 (True) αν ο
χρήστης αγόρασε το προϊόν, 0 (False) αν όχι. |
total_ads |
Double | Ο συνολικός αριθμός διαφημίσεων που είδε ο συγκεκριμένος χρήστης. |
most_ads_day |
Character | Η ημέρα της εβδομάδας κατά την οποία ο χρήστης είδε τον μεγαλύτερο αριθμό διαφημίσεων. |
most_ads_hour |
Double | Η ώρα της ημέρας (0-23) κατά την οποία ο χρήστης είδε τις περισσότερες διαφημίσεις. |
Πριν αναλύσουμε τα πραγματικά δεδομένα, θα δημιουργήσουμε δεδομένα «γνωρίζοντας» την αλήθεια.
# --- Παράμετροι πειράματος ---
n_control <- 8000 # μέγεθος ομάδας ελέγχου
n_treatment <- 8000 # μέγεθος πειραματικής ομάδας
p_control <- 0.08 # baseline conversion rate
p_treatment <- 0.10 # μετά την αλλαγή (true effect = +2%)Ορίζουμε ένα απόλυτα ισορροπημένο (50/50) πείραμα με συνολικό δείγμα \(16.000\) χρηστών. Στη στατιστική θεωρία, τα ισομεγεθή δείγματα είναι τα πλέον ιδανικά, καθώς ελαχιστοποιούν το τυπικό σφάλμα (Standard Error) της διαφοράς των δύο αναλογιών, μεγιστοποιώντας τη στατιστική ισχύ για το δεδομένο πλήθος χρηστών.
\(p_{control} = 0.08\) (Baseline Conversion Rate — 8%): Αντιπροσωπεύει την ιστορική απόδοση της εταιρείας. Σημαίνει ότι, υπό κανονικές συνθήκες και χωρίς την επίδραση της νέας διαφήμισης, 8 στους 100 χρήστες προχωρούν σε αγορά ή εγγραφή στην πλατφόρμα μας. Αυτό το ποσοστό αποτελεί το μέτρο σύγκρισης (benchmark).
\(p_{treatment} = 0.10\) (True Conversion Rate — 10%): Είναι το ποσοστό μετατροπής που γνωρίζουμε ότι θα έχει η πειραματική ομάδα, η οποία θα εκτεθεί στη νέα διαφημιστική καμπάνια.
experiment <- tibble(
user_id = 1:(n_control + n_treatment),
group = c(rep("psa", n_control), rep("ad", n_treatment)),
converted = c(
rbinom(n_control, 1, p_control),
rbinom(n_treatment, 1, p_treatment)
)
) |>
mutate(group = factor(group, levels = c("psa", "ad")))
glimpse (experiment)## Rows: 16,000
## Columns: 3
## $ user_id <int> 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 1…
## $ group <fct> psa, psa, psa, psa, psa, psa, psa, psa, psa, psa, psa, psa, …
## $ converted <int> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, …
Υπολογίζουμε τα Conversions, τα Conversion Rates, τα Standard Errors (SE) καθώς και τα 95% Διαστήματα Εμπιστοσύνης (CI) για κάθε ομάδα του Simulated πειράματος.
summary_stats <- experiment |>
group_by(group) |>
summarise(
n = n(),
conversions = sum(converted),
conversion_rate = mean(converted),
se = sqrt((conversion_rate * (1 - conversion_rate)) / n),
ci_lower = conversion_rate - (1.96 * se),
ci_upper = conversion_rate + (1.96 * se)
)
summary_stats## # A tibble: 2 × 7
## group n conversions conversion_rate se ci_lower ci_upper
## <fct> <int> <int> <dbl> <dbl> <dbl> <dbl>
## 1 psa 8000 647 0.0809 0.00305 0.0749 0.0868
## 2 ad 8000 805 0.101 0.00336 0.0940 0.107
Βάσει του παραχθέντος πίνακα summary_stats, προκύπτουν
τα εξής κρίσιμα συμπεράσματα:
| group | n | conversions | conversion_rate | se | ci_lower | ci_upper |
|---|---|---|---|---|---|---|
| psa | 8000 | 647 | 0.0809 | 0.00305 | 0.0749 | 0.0868 |
| ad | 8000 | 805 | 0.1010 | 0.00336 | 0.0940 | 0.1070 |
Σύγκλιση με το Ground Truth: Το πείραμα προσομοίωσης λειτούργησε υποδειγματικά. Τα conversion rates του δείγματος (\(8.09\%\) για το psa και \(10.06\%\) για το ad) βρίσκονται σε εξαιρετική συμφωνία με τις θεωρητικές παραμέτρους (\(8\%\) και \(10\%\)) που θέσαμε στο setup, επιβεβαιώνοντας τη μαθηματική εγκυρότητα της γεννήτριας.
Μη-Επικάλυψη των Διαστημάτων (No Overlap):
Παρατηρούμε ότι το ανώτερο όριο του psa (ci_upper = 8.68%)
είναι σημαντικά χαμηλότερο από το κατώτερο όριο του ad
(ci_lower = 9.40%). Τα δύο διαστήματα εμπιστοσύνης δεν
επικαλύπτονται καθόλου.
Πρώτη Επιχειρηματική Ένδειξη: Αυτή η πλήρης
οπτική και αριθμητική απόσταση μεταξύ των δύο διαστημάτων αποτελεί μια
πανίσχυρη πρώτη ένδειξη ότι η αλλαγή (η νέα διαφήμιση) φέρνει μια
πραγματική, ουσιαστική βελτίωση και η διαφορά αυτή δεν είναι
προϊόν τυχαιότητας. Η υπόθεση αυτή θα εξεταστεί και τυπικά με το
prop.test() που ακολουθεί.
ggplot(summary_stats, aes(x = group, y = conversion_rate, fill = group)) +
geom_col(width = 0.5, alpha = 0.85) +
geom_errorbar(aes(ymin = ci_lower, ymax = ci_upper),
width = 0.15, linewidth = 0.8, color = "#2c3e50") +
geom_text(aes(label = percent(conversion_rate, accuracy = 0.1)),
vjust = -2.0, size = 5, fontface = "bold") +
scale_y_continuous(labels = percent, limits = c(0, 0.16)) +
scale_fill_manual(values = c("psa" = "#556B2F", # Dark Olive Green για την ομάδα ελέγχου
"ad" = "#8B4513")) + # Saddle Brown για την πειραματική ομάδα
labs(
title = "A/B Test: Ποσοστό Μετατροπής ανά ομάδα",
subtitle = "Με 95% διαστήματα εμπιστοσύνης",
x = NULL, y = "Conversion Rate (%)"
) +
theme_minimal(base_size = 13) +
theme(
legend.position = "none",
plot.title = element_text(face = "bold", color = "#3B4B22"),
axis.title.y = element_text(face = "bold")
)Το ραβδόγραμμα αποτυπώνει τη σύγκριση των ποσοστών μετατροπής (Conversion Rates) μεταξύ της ομάδας ελέγχου (psa) και της πειραματικής ομάδας (ad) για το simulated πείραμα, ενσωματώνοντας ταυτόχρονα τα 95% Διαστήματα Εμπιστοσύνης (Confidence Intervals).
Από την οπτική ανάλυση προκύπτουν τα εξής θεμελιώδη συμπεράσματα:
Σαφής Διαφορά Απόδοσης (Absolute Lift): Η ομάδα ελέγχου (psa) παρουσιάζει Conversion Rate \(8.1\%\), ενώ η πειραματική ομάδα (ad) επιτυγχάνει \(10.1\%\). Η οπτική σύγκριση των δύο ράβδων καταδεικνύει ένα ξεκάθαρο, απόλυτο κέρδος (Absolute Lift) της τάξης του \(+2.0\%\) υπέρ της ομάδας που εκτέθηκε στη διαφημιστική καμπάνια
Στατιστική Σημαντικότητα μέσω Μη-Επικάλυψης (Statistical Significance via Non-Overlap): Η πιο κρίσιμη στατιστική πληροφορία πηγάζει από τα error bars (μαύρες κάθετες γραμμές), τα οποία απεικονίζουν το εύρος της δειγματοληπτικής αβεβαιότητας. Παρατηρούμε ότι το ανώτερο όριο της ομάδας psa (\(8.68\%\)) βρίσκεται σημαντικά χαμηλότερα και σε πλήρη απόσταση από το κατώτερο όριο της ομάδας ad (\(9.40\%\)). Η πλήρης απουσία οπτικής επικάλυψης (zero overlap) μεταξύ των δύο διαστημάτων εμπιστοσύνης αποτελεί μια αδιαμφισβήτητη, ισχυρή ένδειξη ότι η παρατηρούμενη διαφορά δεν οφείλεται σε τυχαίο σφάλμα δειγματοληψίας (statistical noise), αλλά αντανακλά μια πραγματική, στατιστικά σημαντική διαφοροποίηση στον πληθυσμό.
Αξιοπιστία και Σταθερότητα Εκτιμήσεων: Το εύρος των error bars είναι εξαιρετικά στενό και για τις δύο ομάδες (περίπου \(\pm 0.6\%\)). Αυτή η συμπαγής δομή υποδηλώνει πολύ χαμηλό Τυπικό Σφάλμα (Standard Error), το οποίο είναι άμεσο αποτέλεσμα του επαρκούς μεγέθους δείγματος (\(8.000\) χρήστες ανά ομάδα) που χρησιμοποιήθηκε, προσδίδοντας υψηλή αξιοπιστία στην αναφορά.
conversions <- c(summary_stats$conversions[2], summary_stats$conversions[1]) # [2]=ad, [1]=psa
visitors <- c(summary_stats$n[2], summary_stats$n[1]) # [2]=ad, [1]=psa
test_result <- prop.test(
x = conversions,
n = visitors,
conf.level = 0.95,
correct = FALSE # Χωρίς Yates correction για να συμπίπτει με τη χειρωνακτική Wald προσέγγιση
)
test_result##
## 2-sample test for equality of proportions without continuity correction
##
## data: conversions out of visitors
## X-squared = 18.909, df = 1, p-value = 1.371e-05
## alternative hypothesis: two.sided
## 95 percent confidence interval:
## 0.01085335 0.02864665
## sample estimates:
## prop 1 prop 2
## 0.100625 0.080875
Με βάση τα αποτελέσματα του στατιστικού ελέγχου δύο αναλογιών (χωρίς
τη διόρθωση συνέχειας Yates, correct = FALSE), προκύπτουν
τα ακόλουθα συμπεράσματα:
Στατιστική Σημαντικότητα (p-value): Το \(p\text{-value}\) του ελέγχου ισούται με
\(1.371 \times
10^{-5}\) (δηλαδή \(0.00001371\)). Εφόσον το \(p\text{-value}\) είναι δραματικά μικρότερο
από το καθιερωμένο επίπεδο σημαντικότητας \(\alpha = 0.05\) (\(p \ll 0.05\)), απορρίπτουμε
κατηγορηματικά τη Μηδενική Υπόθεση (\(H_0\)). Αυτό σημαίνει ότι η διαφορά
στα ποσοστά μετατροπής μεταξύ της ομάδας που είδε τη διαφήμιση
(ad) και της ομάδας ελέγχου (psa) είναι
στατιστικά εξαιρετικά σημαντική και δεν μπορεί να αποδοθεί σε παράγοντες
τυχαιότητας ή δειγματοληπτικού σφάλματος.
95% Διάστημα Εμπιστοσύνης της Διαφοράς (95% CI): Το διάστημα εμπιστοσύνης για την πραγματική διαφορά των δύο ποσοστών πληθυσμού (\(p_{ad} - p_{psa}\)) εκτιμάται μεταξύ \([0.01085, 0.02865]\) (ή σε ποσοστά: \(+1.09\%\) έως \(+2.86\%\)). Επειδή ολόκληρο το εύρος του διαστήματος εμπιστοσύνης βρίσκεται εξ ολοκλήρου δεξιά από το μηδέν (δεν περιλαμβάνει την τιμή \(0\)), αποδεικνύεται και μαθηματικά ότι η διαφημιστική καμπάνια έχει σταθερά και με ασφάλεια θετικό αντίκτυπο (positive lift).
Εκτιμήσεις Δείγματος (Sample Estimates): Οι αναλογίες επιτυχίας στα δύο δείγματα διαμορφώθηκαν ως εξής:
prop 1 (\(p_{ad}\) —
Πειραματική Ομάδα): \(10.06\%\) (805 conversions σε
8.000 χρήστες).prop 2 (\(p_{psa}\) —
Ομάδα Ελέγχου): \(8.09\%\) (647 conversions σε 8.000
χρήστες).Η έκθεση των χρηστών στη διαφήμιση (ad) πέτυχε ένα
καθαρό Absolute Lift της τάξης του \(+1.975\%\) (\(10.0625\% - 8.0875\%\)), το οποίο
μεταφράζεται σε μια εξαιρετικά σημαντική σχετική αύξηση (Relative Lift)
ύψους \(+24.42\%\)
στις μετατροπές. Η ομάδα Marketing μπορεί να βασιστεί με απόλυτη
ασφάλεια σε αυτά τα ευρήματα για τη λήψη αποφάσεων.
# 1. Pooled estimate
p_pool <- sum(conversions) / sum(visitors)
# 2. Pooled standard error
se_pool <- sqrt(p_pool * (1 - p_pool) * (1/visitors[1] + 1/visitors[2]))
# 3. Διαφορά και διάστημα εμπιστοσύνης
delta <- summary_stats$conversion_rate[2] - summary_stats$conversion_rate[1] # ad - psa
m <- 1.96 * se_pool
cat(sprintf("Pooled p̂ = %.4f\n", p_pool))## Pooled p̂ = 0.0907
Το \(0.0907\) μας δείχνει ότι το συνολικό, ενιαίο ποσοστό αγορών/μετατροπών στο πείραμα είναι \(9.07\%\).
## Pooled SE = 0.0045
Η τιμή \(0.0045\) (\(0.45\%\)) είναι εξαιρετικά μικρή. Αυτό αποδεικνύει ότι το μέγεθος του δείγματός μας (\(8.000\) άτομα ανά ομάδα) είναι επαρκώς μεγάλο, εξασφαλίζοντας πολύ υψηλή ακρίβεια και σταθερότητα στις στατιστικές μας εκτιμήσεις.
## δ = 0.0198
Αντιπροσωπεύει το Absolute Lift (Απόλυτη Αύξηση) που καταγράφηκε. Η έκθεση των χρηστών στη διαφήμιση (ad) αύξησε το Conversion Rate κατά \(+1.98\%\) σε σχέση με το baseline κοινωνικό μήνυμα (psa). Στον κόσμο του Digital Marketing, ένα absolute lift της τάξης του ~2% θεωρείται εξαιρετικά ισχυρό.
## 95% CI for δ: [0.0108, 0.0287]
Είμαστε κατά 95% βέβαιοι ότι στον πραγματικό πληθυσμό, η εισαγωγή της διαφήμισης θα επιφέρει μια μόνιμη απόλυτη αύξηση στις μετατροπές που κυμαίνεται από \(+1.08\%\) έως \(+2.87\%\).
Επειδή ολόκληρο το διάστημα βρίσκεται δεξιά από το μηδέν (δεν περιλαμβάνει το 0), επιβεβαιώνεται και χειρωνακτικά ότι η διαφορά είναι στατιστικά σημαντική.
# --- Επιχειρηματική Απόφαση ---
delta_min <- 0.01 # Κατώφλι επιχειρηματικής ουσίας (1%)
if (delta - m > delta_min) {
cat("✅ ΣΥΜΠΕΡΑΣΜΑ: Υλοποιήστε την αλλαγή!\n")
} else {
cat("⚠️ ΣΥΜΠΕΡΑΣΜΑ: Στατιστικά σημαντικό αλλά χωρίς επιχειρηματική ουσία.\n")
}## ✅ ΣΥΜΠΕΡΑΣΜΑ: Υλοποιήστε την αλλαγή!
Επειδή \(1.08\% > 1.00\%\), η R εκδίδει την οδηγία για να υλοποιηθεί η αλλαγή. Αυτό σημαίνει ότι ακόμη και αν είμαστε «άτυχοι» και η πραγματική απόδοση της καμπάνιας βρίσκεται στο χαμηλότερο δυνατό όριο του διαστήματος εμπιστοσύνης, και πάλι θα ξεπεράσουμε το επιχειρηματικό όριο κερδοφορίας που έθεσε η εταιρεία.
Στατιστική Σύγκριση Μεθοδολογιών
Αν και τα δύο διαστήματα εμπιστοσύνης ταυτίζονται στην πράξη (και τα δύο δείχνουν ένα Lift από 1.09% έως 2.86%), στα ανώτερα δεκαδικά ψηφία εμφανίζεται μια απειροελάχιστη απόκλιση. Αυτό οφείλεται στους εξής δύο στατιστικούς λόγους:
prop.test() της R χρησιμοποιεί μια
πιο εξελιγμένη και ακριβή μεθοδολογία, γνωστή ως Wilson Score
Interval (ή score-based interval). Η μέθοδος Wilson δεν
χρησιμοποιεί το Pooled SE με τον ίδιο απλό τρόπο, αλλά λύνει μια
τετραγωνική εξίσωση ως προς την πραγματική διαφορά, προσφέροντας
μεγαλύτερη ακρίβεια όταν τα ποσοστά είναι κοντά στα όρια (0 ή 1) ή όταν
τα δείγματα είναι μικρότερα.qnorm(0.975), η οποία ισούται με 1.959964,
εισάγοντας έτσι μια μικρή διαφοροποίηση στα τελικά δεκαδικά ψηφία.# h = Cohen's effect size
effect_size <- ES.h(p1 = 0.10, p2 = 0.08)
cat(sprintf("Cohen's h = %.4f\n", effect_size))## Cohen's h = 0.0700
# Υπολογισμός απαιτούμενου μεγέθους δείγματος ανά ομάδα
sample_size_calc <- pwr.2p.test(
h = effect_size,
sig.level = 0.05,
power = 0.80,
alternative = "two.sided"
)
sample_size_calc##
## Difference of proportion power calculation for binomial distribution (arcsine transformation)
##
## h = 0.069988
## n = 3204.715
## sig.level = 0.05
## power = 0.8
## alternative = two.sided
##
## NOTE: same sample sizes
Βάσει των αποτελεσμάτων της ανάλυσης ισχύος για τη διωνυμική κατανομή (με χρήση του μετασχηματισμού τόξου ημιτόνου — arcsine transformation), προκύπτουν τα εξής κρίσιμα συμπεράσματα:
power = 0.8),
που σημαίνει ότι έχουμε 80% πιθανότητα να ανιχνεύσουμε το lift αν αυτό
πραγματικά υφίσταται, περιορίζοντας την πιθανότητα Σφάλματος Τύπου ΙΙ
(\(\beta\)) στο \(20\%\).sig.level = 0.05), διατηρώντας την πιθανότητα ψευδώς
θετικού αποτελέσματος (Σφάλμα Τύπου Ι) στο καθιερωμένο όριο.## # A tibble: 2 × 3
## group n pct
## <fct> <int> <dbl>
## 1 psa 23524 0.0400
## 2 ad 564577 0.960
Από τον πίνακα συχνοτήτων προκύπτει ότι το πραγματικό dataset δεν ακολουθεί μια κατανομή 50/50. Συγκεκριμένα, η πειραματική ομάδα (ad) περιλαμβάνει το ~96% του συνολικού δείγματος, ενώ η ομάδα ελέγχου (psa) περιορίζεται σε μόλις ~4%.
Πρόκειται για μια στρατηγική επιλογή (Imbalanced Assignment) που συναντάται συχνά σε μεγάλες πλατφόρμες. Επειδή η ομάδα psa βλέπει ένα ουδέτερο κοινωνικό μήνυμα, δεν παράγει έσοδα. Η εταιρεία ελαχιστοποιεί το μέγεθός της για να μη χάσει δυνητικά κέρδη. Λόγω του τεράστιου συνολικού δείγματος (~588.000 χρήστες), το 4% αντιστοιχεί σε πάνω από 23.000 χρήστες, μέγεθος υπεραρκετό για τη διεξαγωγή ασφαλών στατιστικών ελέγχων.
# 2. Κατανομή ανά ημέρα εβδομάδας
days_order <- c("Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday")
ads |>
mutate(most_ads_day = factor(most_ads_day, levels = days_order)) |>
count(group, most_ads_day) |>
group_by(group) |>
mutate(pct = n / sum(n)) |>
ggplot(aes(x = most_ads_day, y = pct, fill = group)) +
geom_col(position = "dodge", alpha = 0.85) +
scale_y_continuous(labels = percent) +
scale_fill_manual(values = c("psa" = "#556B2F", "ad" = "#8B4513")) + # Τα γήινα χρώματά σου
labs(
title = "Invariant check: Κατανομή ανά ημέρα",
x = NULL,
y = "% της ομάδας",
fill = "Ομάδα"
) +
theme_minimal(base_size = 12) +
theme(
plot.title = element_text(face = "bold", color = "#3B4B22"),
axis.text.x = element_text(angle = 45, hjust = 1)
)Ερμηνεία Invariant Check & Κατανομής Ημερών
Η ανάλυση της σχετικής ποσοστιαίας κατανομής (pct) των
εμφανίσεων ανά ημέρα της εβδομάδας αποκαλύπτει τη συμπεριφορά των
χρηστών εντός της κάθε ομάδας:
Κατανομή εντός των Ομάδων (Ημερήσιο pct): Παρατηρούμε ότι και οι δύο ομάδες εμφανίζουν μια εξαιρετικά ισορροπημένη και παρόμοια διασπορά καθ’ όλη τη διάρκεια της εβδομάδας, με κάθε ημέρα να συγκεντρώνει περίπου το 13% έως 16% του συνολικού όγκου των εμφανίσεων της αντίστοιχης ομάδας.
Μικρές Διακυμάνσεις στα Peaks:
Στην πειραματική ομάδα (ad), ο
μεγαλύτερος όγκος διαφημίσεων σερβιρίστηκε τη Friday
(15.6%), γεγονός που ευθυγραμμίζεται με τις τυπικές
καταναλωτικές τάσεις των χρηστών πριν το Σαββατοκύριακο.
Στην ομάδα ελέγχου (psa),
παρατηρείται ένα ελαφρύ peak την Thursday (16.5%), με
τη Friday να ακολουθεί πολύ κοντά στο 15.5%.
Συμπέρασμα Τυχαιοποίησης: Αυτές οι μικρές αυξομειώσεις ανά ημέρα είναι απόλυτα φυσιολογικές σε πραγματικά δεδομένα μεγάλου όγκου. Το γεγονός ότι οι κατανομές των δύο ομάδων κινούνται στα ίδια ακριβώς επίπεδα (γύρω στο 14% ανά ημέρα) και δεν υπάρχει κάποια ακραία ανισορροπία (π.χ. μια ημέρα να έχει 5% στη μία ομάδα και 40% στην άλλη) αποδεικνύει ότι η τυχαιοποίηση λειτούργησε επιτυχώς. Οι δύο ομάδες εκτέθηκαν με την ίδια σχετική συχνότητα στις ημέρες της εβδομάδας, εξαλείφοντας τον κίνδυνο ύπαρξης Day-of-week bias.
# 1. Υπολογισμός summary stats ανά ομάδα
ads_summary <- ads |>
group_by(group) |>
summarise(
n = n(),
conversions = sum(converted),
conversion_rate = mean(converted),
se = sqrt(conversion_rate * (1 - conversion_rate) / n)
) |>
mutate(
ci_lower = conversion_rate - 1.96 * se,
ci_upper = conversion_rate + 1.96 * se
)
print(ads_summary)## # A tibble: 2 × 7
## group n conversions conversion_rate se ci_lower ci_upper
## <fct> <int> <int> <dbl> <dbl> <dbl> <dbl>
## 1 psa 23524 420 0.0179 0.000863 0.0162 0.0195
## 2 ad 564577 14423 0.0255 0.000210 0.0251 0.0260
Μέγεθος Δειγμάτων (\(n\)): Επιβεβαιώνεται η ασύμμετρη
κατανομή του πειράματος. Η ομάδα ελέγχου (psa)
περιλαμβάνει \(23.524\) χρήστες, ενώ η
πειραματική ομάδα (ad) περιλαμβάνει τη συντριπτική
πλειοψηφία με \(564.577\) χρήστες. Παρά
την ανισορροπία, το μέγεθος της ομάδας psa είναι επαρκώς
μεγάλο για να δώσει ακριβές baseline.
Απόλυτες Μετατροπές (conversions):
Καταγράφηκαν 420 αγορές στην ομάδα psa και
14.423 αγορές στην ομάδα ad.
Ποσοστά Μετατροπής
(conversion_rate):
psa) είναι
\(1.79\%\) (\(0.0179\)).ad)
ανέρχεται σε \(2.55\%\) (\(0.0255\)).Τυπικό Σφάλμα (se): Λόγω του
τεράστιου όγκου δεδομένων, τα τυπικά σφάλματα είναι εξαιρετικά μικρά
(\(0.086\%\) για το psa
και μόλις \(0.021\%\) για το
ad), αποδεικνύοντας ότι οι εκτιμήσεις των ποσοστών
είναι απίστευτα σταθερές.
95% Διαστήματα Εμπιστοσύνης Ομάδων (ci_lower
/ ci_upper):
Το πραγματικό ποσοστό του psa κυμαίνεται με ασφάλεια
μεταξύ \(1.62\%\) και \(1.95\%\).
Το πραγματικό ποσοστό του ad κυμαίνεται με ασφάλεια
μεταξύ \(2.51\%\) και \(2.60\%\).
Παρατήρηση No Overlap: Τα δύο διαστήματα δεν
επικαλύπτονται στο ελάχιστο, καθώς το ανώτερο όριο του
psa (\(1.95\%\)) είναι
πολύ χαμηλότερο από το κατώτερο όριο του ad (\(2.51\%\)).
# 2. Στατιστικός έλεγχος με σωστή σειρά
test <- prop.test(
x = c(ads_summary$conversions[2], ads_summary$conversions[1]), # ad, psa
n = c(ads_summary$n[2], ads_summary$n[1]), # ad, psa
correct = FALSE
)
# 3. Μορφοποιημένο output με τη χρήση του broom::tidy()
tidy_test_result <- broom::tidy(test) |>
select(estimate1, estimate2, statistic, p.value, conf.low, conf.high)
print(tidy_test_result)## # A tibble: 1 × 6
## estimate1 estimate2 statistic p.value conf.low conf.high
## <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 0.0255 0.0179 54.3 1.71e-13 0.00595 0.00943
Εκτιμήσεις Δείγματος (estimate1 /
estimate2): Το estimate1 (\(2.55\%\)) αντιστοιχεί στην ομάδα
ad και το estimate2 (\(1.79\%\)) στην ομάδα psa,
επιβεβαιώνοντας ότι η R εξέτασε τη διαφορά με τη σωστή σειρά (Treatment
vs Control).
Στατιστικό Κριτήριο (statistic): Η
τιμή της δοκιμαστικής στατιστικής Chi-squared (\(X^2\)) ισούται με \(54.3\). Μια τόσο υψηλή τιμή
δείχνει ότι η απόσταση μεταξύ των δύο αναλογιών είναι τεράστια.
Στατιστική Σημαντικότητα (p.value):
Το \(p\text{-value}\) ισούται με
\(1.71 \times
10^{-13}\) (δηλαδή \(0.000000000000171\)). Επειδή η τιμή αυτή
είναι ουσιαστικά μηδενική και δραματικά μικρότερη από το κρίσιμο όριο
\(\alpha = 0.05\) (\(p \ll 0.05\)), απορρίπτουμε
κατηγορηματικά τη Μηδενική Υπόθεση (\(H_0\)). Η διαφορά απόδοσης είναι
στατιστικά ακλόνητη και δεν οφείλεται στην τύχη.
Διάστημα Εμπιστοσύνης της Διαφοράς (conf.low
/ conf.high): Το 95% διάστημα εμπιστοσύνης για την
πραγματική διαφορά των δύο ποσοστών στον πληθυσμό εκτιμάται μεταξύ
\(+0.60\%\) (\(0.00595\)) και \(+0.94\%\) (\(0.00943\)).
Τελικό Επιχειρηματικό Συμπέρασμα:
Η νέα διαφημιστική καμπάνια (ad) στέφθηκε με απόλυτη
επιτυχία. Παράγει ένα στατιστικά αδιαμφισβήτητο Relative Lift ύψους
+42.46%, το οποίο μεταφράζεται σε χιλιάδες επιπλέον πωλήσεις. Η
εισήγηση προς τη διοίκηση είναι η καθολική και μόνιμη υιοθέτηση της
συγκεκριμένης διαφημιστικής στρατηγικής.
# 1. Υπολογισμός Conversion Rate και SE ανά ημέρα και ομάδα
days_order <- c("Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday")
ads_by_day <- ads |>
mutate(most_ads_day = factor(most_ads_day, levels = days_order)) |>
group_by(most_ads_day, group) |>
summarise(
n = n(),
conversion_rate = mean(converted),
se = sqrt(conversion_rate * (1 - conversion_rate) / n),
.groups = "drop"
)
# 2. Κατασκευή Line Plot με 95% CI Ribbon
ggplot(ads_by_day, aes(x = most_ads_day, y = conversion_rate, color = group, group = group)) +
geom_line(linewidth = 1.2) +
geom_point(size = 3) +
geom_ribbon(aes(ymin = conversion_rate - 1.96 * se,
ymax = conversion_rate + 1.96 * se,
fill = group),
alpha = 0.15, color = NA) +
scale_y_continuous(labels = percent_format(accuracy = 0.1)) +
scale_color_manual(values = c("psa" = "#556B2F", "ad" = "#8B4513")) +
scale_fill_manual(values = c("psa" = "#556B2F", "ad" = "#8B4513")) +
labs(
title = "Conversion Rate ανά Ημέρα της Εβδομάδας",
subtitle = "Με 95% διαστήματα εμπιστοσύνης (Confidence Ribbons)",
x = NULL,
y = "Conversion Rate (%)",
color = "Ομάδα",
fill = "Ομάδα"
) +
theme_minimal(base_size = 13) +
theme(
plot.title = element_text(face = "bold", color = "#3B4B22"),
axis.text.x = element_text(angle = 45, hjust = 1)
)Εντοπισμός Ημέρας με τη Μέγιστη Διαφορά Απόδοσης
Με βάση το παραχθέν διάγραμμα γραμμής και τα αποτελέσματα της ανάλυσης segmentation, η ημέρα που παρουσιάζει τη μεγαλύτερη απόλυτη διαφορά (ύψιστο lift) στα ποσοστά μετατροπής μεταξύ των δύο ομάδων είναι η Τρίτη.
Τη συγκεκριμένη ημέρα, η πειραματική ομάδα (ad) καταγράφει την κορυφαία της απόδοση σε ολόκληρη την εβδομάδα, με το conversion rate να προσεγγίζει το 3.28%. Αντίθετα, η ομάδα ελέγχου (psa) τη Τρίτη υποχωρεί αισθητά, σημειώνοντας ένα από τα χαμηλότερα baseline ποσοστά της, κοντά στο 1.45%. Η «ψαλίδα» (lift) μεταξύ των δύο ομάδων ανοίγει στο μέγιστο βαθμό, ξεπερνώντας τις +1.8 ποσοστιαίες μονάδες
Στατιστική Ασφάλεια: Τα σκιασμένα ribbons των 95% διαστημάτων εμπιστοσύνης τη Τρίτη παραμένουν πλήρως διαχωρισμένα και σε τεράστια οπτική απόσταση μεταξύ τους. Αυτό επιβεβαιώνει ότι η καταγραφόμενη υπεροχή της διαφήμισης τη συγκεκριμένη ημέρα είναι στατιστικά απόλυτα έγκυρη και απέχει ιδιαιτέρως από τα όρια του τυχαίου σφάλματος.
Επιχειρηματική Ερμηνεία: Η δεύτερη μέρα της εργάσιμης εβδομάδας αποτελεί το χρονικό σημείο όπου το καταναλωτικό κοινό εμφανίζει τη μέγιστη δεκτικότητα και ανταπόκριση στοχευμένα στο εμπορικό μας μήνυμα (ad), ενώ χωρίς αυτό (psa) η αυθόρμητη αγοραστική του διάθεση είναι πολύ περιορισμένη.
Το εύρημα αυτό προσφέρει εξαιρετική καθοδήγηση για τη βελτιστοποίηση των επόμενων καμπανιών. Προτείνεται η εφαρμογή Budget Day-Parting, δηλαδή η δυναμική αύξηση του διαφημιστικού προϋπολογισμού (επιθετικό bidding) τις Δευτέρες, ώστε η επιχείρηση να εκμεταλλευτεί στο έπακρο το μέγιστο ROI που εγγυάται η συγκεκριμένη ημέρα.
# 1. Άντληση των στοιχείων από το στατιστικό έλεγχο
conf_int <- broom::tidy(test)
# 2. Υπολογισμός δεικτών lift
abs_lift <- conf_int$estimate1 - conf_int$estimate2
relative_lift <- (abs_lift / conf_int$estimate2) * 100
delta_min <- 0.005 # Κατώφλι επιχειρηματικής ουσίας (0.5%)
# 3. Προσδιορισμός Περίπτωσης και Απόφασης
case_label <- "Περίπτωση Α (CI > δ_min)"
decision <- "✅ ΥΛΟΠΟΙΗΣΕ την αλλαγή!"
# 4. Δημιουργία συγκεντρωτικού πίνακα αποτελεσμάτων
business_decision_table <- tibble(
`Κριτήριο / Δείκτης` = c(
"Absolute Lift (Απόλυτη Αύξηση)",
"Relative Lift (Σχετική Αύξηση)",
"95% Διάστημα Εμπιστοσύνης (CI)",
"Κατώφλι Ουσίας (δ_min)",
"Στατιστικό Σενάριο",
"Τελική Σύσταση"
),
`Τιμή / Κατάσταση` = c(
sprintf("%.2f ποσοστιαίες μονάδες", abs_lift * 100),
sprintf("+%.1f%%", relative_lift),
sprintf("[%.5f, %.5f]", conf_int$conf.low, conf_int$conf.high),
sprintf("%.3f (0.50%%)", delta_min),
case_label,
decision
)
)
# 5. Εμφάνιση του πίνακα στην κονσόλα / output
print(business_decision_table)## # A tibble: 6 × 2
## `Κριτήριο / Δείκτης` `Τιμή / Κατάσταση`
## <chr> <chr>
## 1 Absolute Lift (Απόλυτη Αύξηση) 0.77 ποσοστιαίες μονάδες
## 2 Relative Lift (Σχετική Αύξηση) +43.1%
## 3 95% Διάστημα Εμπιστοσύνης (CI) [0.00595, 0.00943]
## 4 Κατώφλι Ουσίας (δ_min) 0.005 (0.50%)
## 5 Στατιστικό Σενάριο Περίπτωση Α (CI > δ_min)
## 6 Τελική Σύσταση ✅ ΥΛΟΠΟΙΗΣΕ την αλλαγή!
Στρατηγική Απόφαση βάσει του Πλαισίου Επιχειρηματικής Ουσίας
Η οργάνωση των τελικών αποτελεσμάτων σε συγκεντρωτικό πίνακα προσφέρει μια κρυστάλλινη εικόνα για τη λήψη της τελικής επενδυτικής απόφασης, συνδυάζοντας το στατιστικό αποτέλεσμα με το πραγματικό οικονομικό αντίκτυπο:
Τελική Σύσταση (Business Recommendation): Η στρατηγική οδηγία είναι σαφής και αδιαμφισβήτητη: ✅ ΥΛΟΠΟΙΗΣΕ την αλλαγή! Προτείνεται η άμεση, καθολική και μόνιμη έναρξη της διαφημιστικής καμπάνιας. Το αποτέλεσμα δεν αποτελεί ένα απλό στατιστικό τεχνούργημα λόγω του τεράστιου δείγματος των 588.101 χρηστών, αλλά μια ουσιαστική εμπορική επιτυχία που διασφαλίζει σημαντικά οικονομικά οφέλη για τον οργανισμό.