Εντοπίζοντας πιθανούς ενδιαφερόμενους πελάτες

Κατασκευή μοντέλων μηχανικής μάθησης (χρησιμοποιώντας LightGBM & XGBoost) με σκοπό την ταξινόμηση των ανθρώπων με βάση το ενδεχόμενο ενδιαφέρον τους να δημιουργήσουν ένα τραπεζικό λογαριασμό προσθεσμιακής κατάθεσης.

R
Ταξινόμηση
Tidymodels
Συγγραφέας

stesiam

Δημοσιευμένο

24 Νοεμβρίου 2022

Εισαγωγή

Σε αυτό το άρθρο θα κατασκευάσω ένα μοντέλο μηχανικής μάθησης για να προβλέψω ποιοι από τους πελάτες μίας τράπεζας ενδιαφέρονται να ανοίξουν έναν λογαριασμό προθεσμικής κατάθεσης. Για το σκοπό αυτό θα χρησιμοποιήσουμε μοντέλα Boosting (XGBoost και LightGBM) για να ταξινομήσουμε τις περιπτώσεις πιθανές αποκρίσεις σε ενδιαφερόμενους και μη ενδιαφερόμενους. Τα δεδομένα προέρχονται από την ιστοσελίδα «UCI Machine Learning Repository» (Dua & Graff, 2017) και χρησιμοποίησα τη βάση δεδομένων που τιτλοφορείται ως Bank Marketing (Moro, Cortez, & Rita, 2014).

Πριν ξεκινήσουμε την ανάλυσή μας, ας κάνουμε μία νύξη σε κάποιους βασικούς όρους.

Τι είναι η προθεσμιακή κατάθεση;

Όταν θέλουμε να καταθέσουμε χρήματα στη τράπεζα συνήθως οι περισσότεροι έχουν έναν απλό λογαριασμό ταμιευτηρίου ή αποταμίευσης. Ένα διαφορετικό είδος λογαριασμού είναι ο προθεσμιακός, όπου σε αυτή τη περίπτωση δεσμεύεται ο πελάτης της τράπεζας ότι δεν θα κάνει ανάληψη στον λογαριασμό για ένα προκαθορισμένο χρονικό διάστημα (π.χ. για ένα έτος δεν θα κάνει ανάληψη).

Και για ποιο λόγο να επιλέξουμε έναν τέτοιο λογαριασμό;

Είναι προφανές ότι οι προθεσμιακές καταθέσεις έχουν ένα βασικό μειονέκτημα έναντι των τυπικών λογαριασμών σε όρους πρόσβασης στα κεφάλαιά μας. Φυσικά, κανένας δεν θα έκανε κάποια τέτοια κίνηση αν δεν έχει κάποιο αντάλλαγμα. Έτσι λοιπόν οι τράπεζες συνήθως σε αυτά τα προγράμματα προσφέρουν υψηλότερα επιτόκια σε σχέση με αυτά των λογαριασμών ταμιευτηρίου / αποταμίευσης. Αξίζει να δώσουμε μερικά παραδείγματα τραπεζών, συγκρίνοντας τα τραπεζικά επιτόκια των τυπικών και προθεσμιακών λογιαριασμών.

  • Η Πειραιώς, μία εκ των συστημικών τραπεζών της χώρας μας, προσφέρει διπλάσιο επιτόκιο στους προθεσμιακούς λογαριασμούς της.

  • Η Eurobank, προσφέρει μηδενικό επιτόκιο σε λογαριασμούς ταμιευτηρίου, 0.01% μέχρι και 0.35% σε λογαριασμού αποταμίευσης και στις προθεσμιακές ποικίλει αναλόγως του προγράμματος και του ύψους της κατάθεσης από 0.1% μέχρι και 1%.

  • Γενικότερα, σύμφωνα με την πρόσφατη έκθεση της Τράπεζας της Ελλάδας, τα επιτόκια των προθεσμιακών κυμαίνονται από 1.2% με 1.4%, ενώ οι τυπικοί λογαριασμοί για τα νοικοκυριά είναι στο 0.03%.

Με βάση τα παραπάνω μπορούμε να υποθέσουμε ότι δεν θα είναι όλοι κατάλληλοι για αυτά τα προϊόντα. Με βάση τη λογική, το κατάλληλο προφίλ των ατ κατάλληλο προφίλ των ατόμων που να βρεθούν άτομα με σημαντικό ύψος καταθέσεων και να μην έχουν άλλα σημαντικά βάρη, όπως δάνεια ή χρέη σε τρίτους.

Προαπαιτούμενα

Εισαγωγή βιβλιοθηκών

Για αυτή την ανάλυση θα χρειαστούμε τυπικές βιβλιοθήκες της R για την εισαγωγή των δεδομένων, μέσω του readr πακέτου (Wickham, Hester, & Bryan, 2024), και τη μορφοποίηση αυτών με το dplyr πακέτο (Wickham, François, Henry, Müller, & Vaughan, 2023). Το kableExtra πακέτο (Zhu, 2024) αποτελεί σημαντική προσθήκη ώστε να τυπώσω τα αποτελέσματά μου σε μία μορφή πίνακα. Ένα σημαντικό κομμάτι που θα πρέπει να αποφασίσω πώς να λύσω είναι αυτό της οπτικοποίησης των δεδομένων. Αρχικά χρησιμοποιούσα το πακέτο ggplot2 προκειμένου να δημιουργήσω τα όποια διαγράμματα, πράγμα που είναι αρκετά περιοριστικό για μία ιστοσελίδα καθώς το ggplot2 δημιουργεί στατικά διαγράμματα. Έτσι λοιπόν για τα άρθρα μου χρησιμοποιώ το πακέτο highcharter (Kunst, 2022) όπου είναι ένα R πακέτο που δίνει τη δυνατότητα διαγραμμάτων φιλικό για όλους τους τύπους των οθονών. Τέλος, αυτή η ανάλυση έχει ως στόχο να ταξινομήσει τους πελάτες της τράπεζας, επομένως θα κατασκευάσω ένα μοντέλο ταξινόμησης, και η χρήση του πακέτου tidymodels (Kuhn & Wickham, 2025) κρίνεται απαραίτητη.

Δείξε τον κώδικα
library(readr)
library(dplyr)
library(forcats)
library(kableExtra)
library(highcharter)
library(glue)
library(reactable)

# Build ML models

library(tidymodels)
library(bonsai)
library(themis)

# Other settings
options(digits=4) # print only 4 decimals
options(warn = -1)

Εισαγωγή δεδομένων

Αφού φορτώσουμε τις αναγκαίες βιβλιοθήκες, θα φορτώσουμε τα δεδομένα μας. Η βάση των δεδομένων μου έχει αρκετές εκδόσεις των ίδιων δεδομένων, μία μεγαλύτερη και μία πιο συνοπτική έκδοση, η διαφορά τους έγκειται μόνο στον αριθμό των παρατηρήσεων. Για το συγκεκριμένο άρθρο θα επιλέξω τη πιο συνοπτική μορφή μιας και η προσαρμογή Boosting μοντέλων είναι αρκετά χρονοβόρα σε σύγκριση με τη κατασκευή πιο απλώς μοντέλων ταξινόμησης (π.χ. Λογιστική Παλινδρόμηση, k Πλησιέστερων Γειτόνων).

Δείξε τον κώδικα
bank_dataset <- read_delim("bank_dataset_files/bank.csv",  delim = ";", escape_double = FALSE, trim_ws = TRUE)

bank_dataset = bank_dataset %>% tibble::rowid_to_column("ID")

Προεπισκόπηση δεδομένων

Here we can see a small chunk of my dataset (first 10 rows / observations) just to understand the dataset’s structure and type of variables.

Δείξε τον κώδικα
preview_bank_dataset = head(bank_dataset, 6)
reactable(
  preview_bank_dataset,
  bordered = FALSE,     # No borders (booktabs style)
  striped = FALSE,      # No stripes for a clean look
  highlight = FALSE,    # No hover highlighting
  defaultColDef = colDef(align = "center"),
  style = list(fontSize = "14px", border = "none"),
  theme = reactableTheme(
    borderColor = "transparent", # Remove border
    cellStyle = list(
      borderBottom = "transparent"  # Subtle line between rows
    ),
    headerStyle = list(
      borderBottom = "2px solid rgb(117, 117, 117)", # Thick top rule
      borderTop = "2px solid rgb(117, 117, 117)",
      fontWeight = "bold"
    )
  )
)
Πίνακας 1: Προεπισκόπηση δεδομένων (πρώτες 6 παρατηρήσεις)

Προτού κάνουμε οποιαδήποτε ανάλυση είναι καλό να προσδιορίσουμε το τύπο των δεδομένων που έχουμε διαθέσιμα. Ως επί το πλεείστον αυτό μπορούμε να το μάθουμε κοιτώντας τις τιμές που λαμβάνει μία μεταβλητή. Γενικότερα, οι μεταβλητές μπορούν να ταξινομηθούν με βάση τις τιμές που λαμβάνουν ως εξής:

graph TD;
  A(Τύπος μεταβλητών) --> B(Ποσοτική)
  A(Τύπος μεταβλητών) --> C(Ποιοτική)
  B --> D(Διακριτή)
  B --> E(Συνεχής)
  C --> J(Κατηγορική)
  C --> G(Διατάξιμη)

Πίνακας 2: Σύνοψη μεταβλητών δεδομένων
Μεταβλητή Τύπος μεταβλητής Περιγραφή
Age ποσοτική
(συνεχής)
Ηλικία ατόμου
Job ποιοτική
(κατηγορική)
Κλάδος απασχόλησης ατόμου
Marital ποιοτική
(κατηγορική)
Οικογενειακή κατάσ
Education ποιοτική
(διατάξιμη)
Υψηλότερη βαθμίδα εκπαίδευσης
Default ποιοτική
(κατηγορική)
has credit in default?
Balance ποσοτική
(συνεχής)
Average yearly balance, in euros
Housing ποιοτική
(κατηγορική)
Έχει στεγαστικό δάνειο;
Loan ποιοτική
(κατηγορική)
Έχει προσωπικό δάνειο;
Contact ποιοτική
(κατηγορική)
Μέσο επικοινωνίας
Month ποιοτική
(διατάξιμη)
Last contact day of the month
Duration quantitative
(continuous)
Last contact duration, in seconds (numeric)
Campaign quantitative Number of contacts performed during this campaign and for this client
pdays quantitative Αριθμός ημερών που μεσολάβησαν από τελευταία ενημέρωση
pprevious quantitative Αριθμός προσεγγίσεων του πελάτη
poutcome qualitative (nominal) Αποτέλεσμα πορηγούμενης προωθητικής καμπάνιας
Deposit qualitative
(nominal)
Has the client subscribed a term deposit?

Το δείγμα μου αποτελείται από 18 μεταβλητές (στήλες), εκ των οποίων οι 7 είναι ποσοτικές και οι υπόλοιπες 10 ποιοτικές. Όσον αφορά τις ποιοτικές μεταβλητές, 8 από αυτές είναι κατηγορικές και μόλις δύο είναι διατάξιμες (Μήνας προώθησης και Επίπεδο εκπαίδευσης).

Ορισμός συναρτήσεων

Οκ, είδαμε κάποια βασικά στοιχεία των δεδομένων μου και τη δομή αυτών. Μπορώ τώρα να ξεκινήσω την ανάλυσή μου;

Εξαρτάται. Σε περίπτωση που θέλεις να πάρεις μία γρήγορη ανάλυση προκειμένου να λάβεις ένα συκγκεκριμένο αποτέλεσμα πιθανότατα να είναι εντάξει. Βέβαια, τις περισσότερες φορές απαιτείται προσεκτικότερος σχεδιασμός της μελέτης. Ένας αρκετά συχνό λάθος στο οποίο έχω υποπέσει και εγώ στο παρελθόν είναι ο κίνδυνος της επαναληψιμότητας ορισμένων διαδικασιών. Προκειμένου να αποτρέψουμε να γράφουμε τα ίδια πράγματα πολλές φορές κρίνεται απαραίτητη η συγγραφή ορισμένων συναρτήσεων. Για παράδειγμα στη συγκεκριμένη άσκηση παρατηρώ ότι έχω αρκετές μεταβλητές του ίδιου τύπου, τόσο ποιοτικές όσο και ποσοτικές. Για ποιο λόγο λοιπόν να γράψω 10 φορές παρόμοιο κώδικα όταν μπορώ να εσωκλείσω τα βασικά χαρακτηριστικά σε μία συνάρτηση.

Έτσι λοιπόν έχω ορίσει δύο μεταβλητές. Αρχικά την univariateQualitativePlot η οποία χρησιμοποιείται για τη κατασκευή κυκλικών διαγραμμάτων για τις ποιοτικές μεταβλητές μου.

Δείξε τον κώδικα
univariateQualitativePlot <- function(data, column, title, subtitle, chart_type = "bar") {

  # Compute frequency table
  freq_table <- data %>%
    count({{ column }}, name = "Frequency") %>%
    arrange(desc(Frequency)) %>%
    rename(Variable = {{ column }})

  # Define common chart properties
  hc <- highchart() %>%
    hc_title(text = title) %>%
    hc_subtitle(text = subtitle) %>%
    hc_tooltip(pointFormat = "{point.name}: {point.y}") %>%
    hc_legend(enabled = chart_type == "pie")  # Enable legend only for pie chart

  # Choose chart type
  hc <- if (chart_type == "bar") {
    hc %>%
      hc_chart(type = "bar") %>%
      hc_xAxis(categories = freq_table$Variable, title = list(text = "Job Category")) %>%
      hc_yAxis(title = list(text = "Frequency")) %>%
      hc_series(list(name = "Frequency", data = freq_table$Frequency))
  } else if (chart_type == "pie") {
    pie_data <- lapply(1:nrow(freq_table), function(i) {
      list(name = freq_table$Variable[i], y = freq_table$Frequency[i])
    })
    
    hc %>%
      hc_chart(type = "pie") %>%
      hc_series(list(name = "Frequency", data = pie_data))
  } else {
    stop("Invalid chart type. Use 'bar' or 'pie'.")
  }

  return(hc)
}

Αντίστοιχα, θα ορίσω και τη συνάρτηση univariateQuantitativePlot για τη κατασκευή ραβδογραμμάτων για τις ποσοτικές μεταβλητές μου. Και οι δύο συναρτήσεις βασίζονται και κατασκευάσουν διαγράμματα χρησιμοποιώντας το πακέτο highcharter.

Περιγραφική Ανάλυση

Ελλειπούσες τιμές

Δείξε τον κώδικα
how_many_nas = sum(is.na(bank_dataset))

Στα δοσμένα δεδομένα υπάρχουν συνολικά 0 ελλειπούσες τιμές. Αυτή βέβαια είναι μία σπάνια - ιδανική περίπτωση. Σε διαφορετική περίπτωση θα έπρεπε να γεμίσουμε τις κενές τιμές με κάποια μέθοδο εκτίμησης.

Μονομεταβλητή ανάλυση

Δείξε τον κώδικα
univariateQualitativePlot(bank_dataset, job, 
                          title = "Τομέας απασχόλησης του ερωτώμενων", 
                          subtitle = "Καθαρός αριθμός και ποσοστό (%) επί όλων των πελατών")
Σχήμα 1: Ραβδόγραμμα κλάδων απασχόλης πελατών της τράπεζας
Δείξε τον κώδικα
univariateQualitativePlot(bank_dataset, marital, 
                          title = "Ποια είναι η οικογενειακή σου κατάσταση;", 
                          subtitle = "Οι περισσότεροι είναι παντρεμένοι.",
                          "pie")
Σχήμα 2: Κυκλικό διάγραμμα οικογενειακής κατάστασης πελατών τράπεζας
Δείξε τον κώδικα
univariateQualitativePlot(bank_dataset, 
                          education, 
                          title = "Υψηλότερο επίπεδο εκπαίδευσης",
                          subtitle = "")
Δείξε τον κώδικα
univariateQualitativePlot(bank_dataset, default, 
                          title = "Έχετε μη εξυπηρετούμενες οφειλές;", 
                          subtitle = "Ποσοστό (%) ατόμων που δεν έχουν εκπληρώσει τις πιστωτικές τους υποχρεώσεις",  
                          "pie")
Δείξε τον κώδικα
univariateQualitativePlot(bank_dataset, housing, 
                          title = "Έχετε λάβει στεγαστικό δάνειο;", 
                          subtitle = "Ποσοστό (%) ατόμων που έχει λάβει στεγαστικό δάνειο",                            "pie")
Δείξε τον κώδικα
univariateQualitativePlot(bank_dataset, loan, 
                          title = "Έχετε λάβει καταναλωτικό δάνειο;", 
                          subtitle = "Ποσοστό (%) ατόμων που έχει λάβει προσωπικό - καταναλωτικό δάνειο",                            "pie")
Δείξε τον κώδικα
univariateQualitativePlot(bank_dataset, contact, 
                          title = "Μέσο επικοινωνίας", 
                          subtitle = "Η προώθηση μέσω κινητού είναι πιο εκτεταμένη σε σχέση με το σταθερό",
                          "pie")
Δείξε τον κώδικα
univariateQualitativePlot(bank_dataset, poutcome, 
                          title = "Ποιο ήταν το αποτέλεσμα προηγούμενης προσέγγισης?", 
                          subtitle = "For every five failed approaches there was one succussful.", "pie")
Δείξε τον κώδικα
univariateQualitativePlot(bank_dataset, y, 
                          title = "Πόσοι αποφάσισαν να φτιάξουν προθεσμιακό λογαριασμό;", 
                          subtitle = "Ποσοστό πελατών που αποφάσισαν να ανοίξουν
                          έναν προθεσμιακό λογαριασμό ως αποτέλεσμα της τωρινής καμπάνιας.",
                          "pie")

Ποσοτικές μεταβλητές

Δείξε τον κώδικα
hchart(bank_dataset$age) %>%
    hc_title(text = "Κατανομή ηλικιών") %>%
    hc_subtitle(text = glue("Η διάμεση ηλικία είναι τα <b>{median(bank_dataset$age)}</b> έτη.")) %>%
    hc_caption(text = "Bank Marketing Dataset from UCI") %>%
    hc_tooltip(pointFormat = "{point.name}: {point.y}") %>%
    hc_legend(enabled = FALSE)
Δείξε τον κώδικα
hchart(bank_dataset$balance) %>%
    hc_title(text = "Κατανομή καταθέσεων") %>%
    hc_subtitle(text = glue("Οι περισσότερες καταθέσεις κυμαίνονται μεταξύ των 0$ και 200$ δολαρίων. Το διάμεσο υπόλοιπο λογαριασμού είναι {median(bank_dataset$balance)} $. Το 75ο τεταρτημόριο είναι τα 1480$, άρα το ένα τέταρτο των πελατών έχει καταθέσεις υψηλότερες αυτού του ποσού. Τα ύψη των λογαριασμών κυμαίνονται από {min(bank_dataset$balance)} μέχρι και τα {max(bank_dataset$balance)} $")) %>%
    hc_caption(text = "Bank Marketing Dataset from UCI") %>%
    hc_tooltip(pointFormat = "{point.name}: {point.y}") %>%
    hc_legend(enabled = FALSE) %>%
    hc_xAxis(
    title = list(text = "Ύψος καταθέσεων σε δολαρια ΗΠΑ $"),
      max = 10000
)
Δείξε τον κώδικα
ggplot(bank_dataset, aes(x=duration, fill=duration)) + 
  geom_histogram( ) +
  scale_fill_hue(c = 40) +
  theme_bw() +
  labs(
    title = "How many people made a deposit account ?",
    caption = "Data from the 1974 Motor Trend US magazine.",
    x = "Response",
    y = "Observations"
  ) +
  theme_classic() +
  theme(legend.position = "none")
`stat_bin()` using `bins = 30`. Pick better value with `binwidth`.

Δείξε τον κώδικα
ggplot(bank_dataset, aes(x= campaign, fill=campaign )) + 
  geom_bar() +
  scale_fill_hue(c = 40) +
  theme_bw() +
  labs(
    title = "Number of Approaches to a specific person",
    x = "# of Approaches",
    y = "Observations"
  ) + 
  theme_classic()

Κατασκευή μοντέλου

Στην R υπάρχουν υπάρχουν δύο αρκετά διαδεδομένοι τρόποι για τη κατασκευή μοντέλων, το caret και το tidymodels. Από τη μία μεριά, το πακέτο caret είναι αρκετά εύκολο στη χρήση, υπάρχουν αρκετά άρθα σχετικά με αυτό όπως οδηγοί - tutorials, επεξηγηματικά βίντεο - άρθρα. Από την άλλη μεριά, το tidymodels είναι μία <> λύση μιας και αποτελεί ένα μεταπακέτο, δηλαδή μία συλλογή πακέτων, που προσπαθεί να δώσει , ωστόσο υπάρχει λιγότερη τεκμηρίωση και άρθρα μιας και έχει δημιουργηθεί αρκετά πρόσφατα.

Διαχωρισμός συνόλου δεδομένων

Το πρώτο βήμα είναι να χωρίσουμε το αρχικό σύνολο δεδομένων σε δύο μέρη, όπου το καθένα θα χρησιμοποιηθεί για ένα ξεχωιρστό σκοπό. Το πρώτο υποσύνολο χρησιμοποιείται για να εκπαιδεύσω - κατασκευάσω το μοντέλο μου, ενώ το δεύτερο μέρος (test dataset) είναι αναγκαίο ώστε να ελέγξουμε την ακρίβεια του μοντέλου που προέκυψε από το πρώτο υποσύνολο.

Δείξε τον κώδικα
set.seed(123)
bank_dataset_split <- initial_split(bank_dataset,
                                prop = 0.75,
                                strata = y)

# Create training data
bank_train <- bank_dataset_split %>%
                    training()

# Create testing data
bank_test <- bank_dataset_split %>%
                    testing()
graph TD;
  A(Σύνολο δεδομένων <br> 4521 παρατηρήσεις) --> B(Σύνολο εκπαίδευσης <br> 3390 παρατηρήσεις)
  A(Σύνολο δεδομένων <br> 4521 παρατηρήσεις) --> C(Σύνολο αξιολόγησης <br> 1131 παρατηρήσεις)
Σχήμα 3: Τεστ

Στο δικό μας παράδειγμα, έχουμε όπως αναφέραμε προηγούμενως 4521 παρατηρήσεις. Η πιο συνήθης είναι ο διαχωρισμός να γίνεται σε ένα ποσοστό 75% (80%) για να εκπαιδεύσω το μοντέλο μου και το άλλο 25% (20%) για την αξιολόγηση αυτού. Έτσι λοιπόν, καταλήγω με δύο νέα υποσύνολα με τον ίδιο αριθμό μεταβλητών, και το σύνολο εκπαίδευσης του μοντέλου αποτελείται από 3390 παρατηρήσεις και το σύνολο για την αξιολόγησή του αποτελείται από 1131.

Train dataset

Δείξε τον κώδικα
head(bank_train) %>%
  kbl(toprule = T,align = 'c',booktabs = T)  %>%
  kable_styling(full_width = F, position = "center", html_font = "Cambria") 
Πίνακας 3: Προεπισκόπηση υποσυνόλου δεδομένων εκπαίδευσης μοντέλου (train dataset)
ID age job marital education default balance housing loan contact day month duration campaign pdays previous poutcome y
31 68 συνταξιούχος διαζευγμένο δευτεροβάθμια όχι 4189 όχι όχι κινητό 14 Ιούλιο 897 2 -1 0 άγνωστο ναι
34 32 διευθυντικό στέλεχος ανύπαντρο τριτοβάθμια όχι 2536 ναι όχι σταθερό 26 Αύγουστο 958 6 -1 0 άγνωστο ναι
35 49 τεχνικός παντρεμένο τριτοβάθμια όχι 1235 όχι όχι σταθερό 13 Αύγουστο 354 3 -1 0 άγνωστο ναι
37 78 συνταξιούχος διαζευγμένο πρωτοβάθμια όχι 229 όχι όχι κινητό 22 Οκτώβριος 97 1 -1 0 άγνωστο ναι
39 33 διευθυντικό στέλεχος παντρεμένο δευτεροβάθμια όχι 3935 ναι όχι σταθερό 6 Μάιο 765 1 342 2 αποτυχία ναι
54 34 τεχνικός παντρεμένο τριτοβάθμια όχι 1539 ναι όχι σταθερό 15 Ιούνιο 441 1 56 1 άλλο ναι

Test dataset

Δείξε τον κώδικα
head(bank_test) %>%
  kbl(toprule = T,align = 'c',booktabs = T)  %>%
  kable_styling(full_width = F, position = "center", html_font = "Cambria") 
Πίνακας 4: Προεπισκόπηση υποσυνόλου δεδομένων αξιολόγησης μοντέλου (test dataset)
ID age job marital education default balance housing loan contact day month duration campaign pdays previous poutcome y
6 35 διευθυντικό στέλεχος ανύπαντρο τριτοβάθμια όχι 747 όχι όχι σταθερό 23 Φεβρουάριο 141 2 176 3 αποτυχία όχι
10 43 παροχή υπηρεσιών παντρεμένο πρωτοβάθμια όχι -88 ναι ναι σταθερό 17 Απρίλιο 313 1 147 2 αποτυχία όχι
14 20 σπουδαστής ανύπαντρο δευτεροβάθμια όχι 502 όχι όχι σταθερό 30 Απρίλιο 261 1 -1 0 άγνωστο ναι
15 31 χειρονακτική εργασία παντρεμένο δευτεροβάθμια όχι 360 ναι ναι σταθερό 29 Ιανουάριο 89 1 241 1 αποτυχία όχι
17 56 τεχνικός παντρεμένο δευτεροβάθμια όχι 4073 όχι όχι σταθερό 27 Αύγουστο 239 5 -1 0 άγνωστο όχι
23 44 παροχή υπηρεσιών ανύπαντρο δευτεροβάθμια όχι 106 όχι όχι άγνωστο 12 Ιούνιο 109 2 -1 0 άγνωστο όχι

Επεξεργασία δεδομένων

Βέβαια η κατασκευή των μοντέλων δεν είναι τόσο εύκολη υπόθεση. Ανάμεσα στο διαχωρισμό του συνόλου δεδομένων και τη κατασκευή των μοντέλων παρεμβάλεται η επεξεργασία των δεδομένων. Τα βήματα αυτού του σταδίου δεν είναι δεδομένα και ποικίλουν αναλόγως το είδος του προβλήματος (ταξινόμησης ή πρόβλεψης τιμής) αλλά και το ποιο μοντέλο θα επιλέξω. Ευτυχώς, για εμάς το πακέτο tidymodels προσφέρει έτοιμες εντολές προκειμένου να κάνει ανάλυσή μας ευκολότερη και ιδιαίτερα εντολές του πακέτου recipes, που αποτελούν μέρος του tidymodels μπορούν να φανούν ιδιαίτερα χρήσιμες σε αυτό το στάδιο. Βέβαια, υπάρχουν και άλλα πακέτα που συμπληρώνουν - λύνουν συνήθη προβλήματα στα δεδομένα. Για παράδειγμα, στα δεδομένα μας αναμένεται και είδαμε και στο παραπάνω σχήμα ότι οι περισσότεροι δεν επιθυμούν να ανοίξουν προθεσμιακό λογιαριασμό. Τα δεδομένα μας χαρακτηρίζονται ως ανισσόροπα (imbalanced) όταν η μεταβλητή την οποία προσπαθώ να προβλέψω δεν έχω επαρκείς τιμές αλλά αρκετά μεγάλη διαφορά (90% δεν επιθυμούν / 10%) Σε αυτή τη περίπτωση μπορώ να χρησιμοποιήσω την εντολή step_smote() από το πακέτο themis, προκειμένου να ισορροπήσω τη μεταβλητή που προσπαθώ να προβλέψω.

Δείξε τον κώδικα
bank_recipe <- recipes::recipe(y~., 
                               data = bank_train) %>%
  step_rm(poutcome, ID) %>%
  step_corr(all_numeric(), threshold = 0.75) %>%
  step_dummy(all_nominal(), -all_outcomes()) %>%
  step_smote(y)

Ας ρίξουμε τώρα μία ματιά στο σύνολο δεδομένων, αφού κάναμε κάποια βασική επεξεργασία των δεδομένων:

Δείξε τον κώδικα
bank_recipe %>%
  prep() %>%
  juice() %>%
  head() %>%
  kbl() %>%
  kable_styling(full_width = F, position = "center", html_font = "Cambria") 
Πίνακας 5: Dataset after recipes
age balance day duration campaign pdays previous job_χειρονακτική.εργασία job_επιχειρηματίας job_οικιακός.βοηθός job_διευθυντικό.στέλεχος job_συνταξιούχος job_αυτοαπασχολούμενος job_παροχή.υπηρεσιών job_σπουδαστής job_τεχνικός job_άνεργος job_άγνωστο marital_παντρεμένο marital_ανύπαντρο education_δευτεροβάθμια education_τριτοβάθμια education_άγνωστο default_ναι housing_ναι loan_ναι contact_κινητό contact_άγνωστο month_Αύγουστο month_Δεκέμβριο month_Φεβρουάριο month_Ιανουάριο month_Ιούλιο month_Ιούνιο month_Μάρτιο month_Μάιο month_Νοέμβριο month_Οκτώβριος month_Σεπτέμβριος y
68 4189 14 897 2 -1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 ναι
32 2536 26 958 6 -1 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 1 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 ναι
49 1235 13 354 3 -1 0 0 0 0 0 0 0 0 0 1 0 0 1 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 ναι
78 229 22 97 1 -1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 ναι
33 3935 6 765 1 342 2 0 0 0 1 0 0 0 0 0 0 0 1 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 ναι
34 1539 15 441 1 56 1 0 0 0 0 0 0 0 0 1 0 0 1 0 0 1 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 ναι

Διασταυρωμένη επικύρωση

Οκ, ήρθε η ώρα να κατασκευάσουμε το μοντέλο μας;

Όχι τόσο γρήγορα. Θεωρητικά θα μπορούσαμε να συνεχίσουμε, ωστόσο η ενδεδειγμένη μέθοδος είναι να μην λαμβάνω απλώς δύο μέρη καθώς η περαιτέρω αξιολογηση βασίζεται ως επί το πλείστον στο πώς έγινε ο διαχωρισμός και ποιες τιμές λήφθηκαν. Για να έχουμε μία πιο ακριβή εκτίμηση της απόδοσης του μοντέλου προτείνετε να κατασκευάσουμε υποσύνολα των δεδομένων μου με σκοπό να βρω τις παραμέτρους οι οποίες οδηγούν συστηματικά, κατά μέσο όρο σε 5 ή 10 υπό-δείγματα σε καλύτερη ακρίβεια.

Δείξε τον κώδικα
#cv_folds <- vfold_cv(v = 5, strata = y)

Κατασκευάζοντας το μοντέλο μου

Στη συνέχεια, με το πακέτο parsnip μπορώ να ορίσω τα χαρακτηριστικά των διάφορων μοντέλων που θέλω να κατασκευάσω. Στη συγκεκριμένη περίπτωση θα ήθελα να ελέγξω διάφορα μοντέλα και αν ελέγξω την απόδοσή τους. Επομένως, θα ορίσω μοντέλα:

  • k Κοντινότερων Γειτόνων (k - Nearest Neighbors)
  • Λογιστική Παλινδρόμηση (Logistic Regression)
  • Naive Bayes
  • Τυχαίου δάσους (Random Forest)
  • LightGBM

Next, parsnip helps us to specify our models. Initially, I will define a LightGBM model,

Δείξε τον κώδικα
lightgbm_model<- parsnip::boost_tree(
 mode = "classification",
 trees = 50,
 min_n = tune(),
 learn_rate = tune(),
 tree_depth = tune()) %>%
set_engine("lightgbm")

Αναφορές

Bray, A., Ismay, C., Chasnovski, E., Couch, S., Baumer, B., & Cetinkaya-Rundel, M. (2025). infer: Tidy Statistical Inference. Ανακτήθηκε από https://github.com/tidymodels/infer
Couch, S. P., Bray, A. P., Ismay, C., Chasnovski, E., Baumer, B. S., & Çetinkaya-Rundel, M. (2021). infer: An R package for tidyverse-friendly statistical inference. Journal of Open Source Software, 6(65), 3661. https://doi.org/10.21105/joss.03661
Dua, D., & Graff, C. (2017). UCI Machine Learning Repository. University of California, Irvine, School of Information; Computer Sciences. Ανακτήθηκε από http://archive.ics.uci.edu/ml
Falbel, D., Damiani, A., Hogervorst, R. M., Kuhn, M., & Couch, S. (2025). bonsai: Model Wrappers for Tree-Based Models. Ανακτήθηκε από https://bonsai.tidymodels.org/
Frick, H., Chow, F., Kuhn, M., Mahoney, M., Silge, J., & Wickham, H. (2025). rsample: General Resampling Infrastructure. Ανακτήθηκε από https://rsample.tidymodels.org
Hester, J., & Bryan, J. (2024). glue: Interpreted String Literals. Ανακτήθηκε από https://glue.tidyverse.org/
Hvitfeldt, E. (2025). themis: Extra Recipes Steps for Dealing with Unbalanced Data. Ανακτήθηκε από https://github.com/tidymodels/themis
Kabacoff, R. (2019). Data visualization with R. URL https://rkabacoff. github. io/datavis.
Kirenz, J. (2021). Classification with Tidymodels, Workflows and Recipes. Ανακτήθηκε 22 Νοέμβριος 2022, από https://www.kirenz.com/post/2021-02-17-r-classification-tidymodels/#data-preparation
Kuhn, M. (2024). modeldata: Data Sets Useful for Modeling Examples. Ανακτήθηκε από https://modeldata.tidymodels.org
Kuhn, M. (2025). tune: Tidy Tuning Tools. Ανακτήθηκε από https://tune.tidymodels.org/
Kuhn, M., & Couch, S. (2024). workflowsets: Create a Collection of tidymodels Workflows. Ανακτήθηκε από https://github.com/tidymodels/workflowsets
Kuhn, M., & Frick, H. (2025). dials: Tools for Creating Tuning Parameter Values. Ανακτήθηκε από https://dials.tidymodels.org
Kuhn, M., & Vaughan, D. (2025). parsnip: A Common API to Modeling and Analysis Functions. Ανακτήθηκε από https://github.com/tidymodels/parsnip
Kuhn, M., Vaughan, D., & Hvitfeldt, E. (2025). yardstick: Tidy Characterizations of Model Performance. Ανακτήθηκε από https://github.com/tidymodels/yardstick
Kuhn, M., & Wickham, H. (2020). Tidymodels: a collection of packages for modeling and machine learning using tidyverse principles. Ανακτήθηκε από https://www.tidymodels.org
Kuhn, M., & Wickham, H. (2025). tidymodels: Easily Install and Load the Tidymodels Packages. Ανακτήθηκε από https://tidymodels.tidymodels.org
Kuhn, M., Wickham, H., & Hvitfeldt, E. (2025). recipes: Preprocessing and Feature Engineering Steps for Modeling. Ανακτήθηκε από https://github.com/tidymodels/recipes
Kunst, J. (2022). highcharter: A Wrapper for the Highcharts Library. Ανακτήθηκε από https://jkunst.com/highcharter/
Lin, G. (2023). reactable: Interactive Data Tables for R. Ανακτήθηκε από https://glin.github.io/reactable/
Moro, S., Cortez, P., & Rita, P. (2014). A data-driven approach to predict the success of bank telemarketing. Decision Support Systems, 62, 22–31.
Müller, K., & Wickham, H. (2023). tibble: Simple Data Frames. Ανακτήθηκε από https://tibble.tidyverse.org/
R Core Team. (2025). R: A Language and Environment for Statistical Computing. Vienna, Austria: R Foundation for Statistical Computing. Ανακτήθηκε από https://www.R-project.org/
R-Bloggers. (2017). 5 ways to measure running time of R code. Ανακτήθηκε 20 Νοέμβριος 2022, από https://www.r-bloggers.com/2017/05/5-ways-to-measure-running-time-of-r-code/
R-Bloggers. (2020). How to Use Lightgbm with Tidymodels. Ανακτήθηκε 20 Νοέμβριος 2022, από https://www.r-bloggers.com/2020/08/how-to-use-lightgbm-with-tidymodels/
Robinson, D., Hayes, A., & Couch, S. (2025). broom: Convert Statistical Objects into Tidy Tibbles. Ανακτήθηκε από https://broom.tidymodels.org/
Vaughan, D., & Couch, S. (2025). workflows: Modeling Workflows. Ανακτήθηκε από https://github.com/tidymodels/workflows
Wickham, H. (2016). ggplot2: Elegant Graphics for Data Analysis. Springer-Verlag New York. Ανακτήθηκε από https://ggplot2.tidyverse.org
Wickham, H. (2023). forcats: Tools for Working with Categorical Variables (Factors). Ανακτήθηκε από https://forcats.tidyverse.org/
Wickham, H., Chang, W., Henry, L., Pedersen, T. L., Takahashi, K., Wilke, C., … van den Brand, T. (2025). ggplot2: Create Elegant Data Visualisations Using the Grammar of Graphics. Ανακτήθηκε από https://ggplot2.tidyverse.org
Wickham, H., François, R., Henry, L., Müller, K., & Vaughan, D. (2023). dplyr: A Grammar of Data Manipulation. Ανακτήθηκε από https://dplyr.tidyverse.org
Wickham, H., & Henry, L. (2025). purrr: Functional Programming Tools. Ανακτήθηκε από https://purrr.tidyverse.org/
Wickham, H., Hester, J., & Bryan, J. (2024). readr: Read Rectangular Text Data. Ανακτήθηκε από https://readr.tidyverse.org
Wickham, H., Pedersen, T. L., & Seidel, D. (2025). scales: Scale Functions for Visualization. Ανακτήθηκε από https://scales.r-lib.org
Wickham, H., Vaughan, D., & Girlich, M. (2024). tidyr: Tidy Messy Data. Ανακτήθηκε από https://tidyr.tidyverse.org
Zhu, H. (2024). kableExtra: Construct Complex Table with kable and Pipe Syntax. Ανακτήθηκε από http://haozhu233.github.io/kableExtra/

Αναφορά

Αναφορά BibTeX:
@online{2022,
  author = {, stesiam},
  title = {Εντοπίζοντας πιθανούς ενδιαφερόμενους πελάτες},
  date = {2022-11-24},
  url = {https://stesiam.com/el/posts/predict-possible-clients/},
  langid = {el}
}
Για απόδοση ευγνωμοσύνης, παρακαλούμε αναφερθείτε σε αυτό το έργο ως:
stesiam. (2022, November 24). Εντοπίζοντας πιθανούς ενδιαφερόμενους πελάτες. Retrieved from https://stesiam.com/el/posts/predict-possible-clients/