Εισαγωγή
Σε αυτό το άρθρο θα κατασκευάσω ένα μοντέλο μηχανικής μάθησης για να προβλέψω ποιοι από τους πελάτες μίας τράπεζας ενδιαφέρονται να ανοίξουν έναν λογαριασμό προθεσμικής κατάθεσης. Για το σκοπό αυτό θα χρησιμοποιήσουμε μοντέλα 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) κρίνεται απαραίτητη.
Εισαγωγή δεδομένων
Αφού φορτώσουμε τις αναγκαίες βιβλιοθήκες, θα φορτώσουμε τα δεδομένα μας. Η βάση των δεδομένων μου έχει αρκετές εκδόσεις των ίδιων δεδομένων, μία μεγαλύτερη και μία πιο συνοπτική έκδοση, η διαφορά τους έγκειται μόνο στον αριθμό των παρατηρήσεων. Για το συγκεκριμένο άρθρο θα επιλέξω τη πιο συνοπτική μορφή μιας και η προσαρμογή 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"
)
)
)
Προτού κάνουμε οποιαδήποτε ανάλυση είναι καλό να προσδιορίσουμε το τύπο των δεδομένων που έχουμε διαθέσιμα. Ως επί το πλεείστον αυτό μπορούμε να το μάθουμε κοιτώντας τις τιμές που λαμβάνει μία μεταβλητή. Γενικότερα, οι μεταβλητές μπορούν να ταξινομηθούν με βάση τις τιμές που λαμβάνουν ως εξής:
graph TD; A(Τύπος μεταβλητών) --> B(Ποσοτική) A(Τύπος μεταβλητών) --> C(Ποιοτική) B --> D(Διακριτή) B --> E(Συνεχής) C --> J(Κατηγορική) C --> G(Διατάξιμη)
Μεταβλητή | Τύπος μεταβλητής | Περιγραφή |
---|---|---|
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.
Περιγραφική Ανάλυση
Ελλειπούσες τιμές
Στα δοσμένα δεδομένα υπάρχουν συνολικά 0 ελλειπούσες τιμές. Αυτή βέβαια είναι μία σπάνια - ιδανική περίπτωση. Σε διαφορετική περίπτωση θα έπρεπε να γεμίσουμε τις κενές τιμές με κάποια μέθοδο εκτίμησης.
Μονομεταβλητή ανάλυση
Δείξε τον κώδικα
univariateQualitativePlot(bank_dataset, job,
title = "Τομέας απασχόλησης του ερωτώμενων",
subtitle = "Καθαρός αριθμός και ποσοστό (%) επί όλων των πελατών")
Δείξε τον κώδικα
univariateQualitativePlot(bank_dataset, marital,
title = "Ποια είναι η οικογενειακή σου κατάσταση;",
subtitle = "Οι περισσότεροι είναι παντρεμένοι.",
"pie")
Δείξε τον κώδικα
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) είναι αναγκαίο ώστε να ελέγξουμε την ακρίβεια του μοντέλου που προέκυψε από το πρώτο υποσύνολο.
graph TD; A(Σύνολο δεδομένων <br> 4521 παρατηρήσεις) --> B(Σύνολο εκπαίδευσης <br> 3390 παρατηρήσεις) A(Σύνολο δεδομένων <br> 4521 παρατηρήσεις) --> C(Σύνολο αξιολόγησης <br> 1131 παρατηρήσεις)
Στο δικό μας παράδειγμα, έχουμε όπως αναφέραμε προηγούμενως 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")
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")
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)
Ας ρίξουμε τώρα μία ματιά στο σύνολο δεδομένων, αφού κάναμε κάποια βασική επεξεργασία των δεδομένων:
Δείξε τον κώδικα
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")
Αναφορές
Αναφορά
@online{2022,
author = {, stesiam},
title = {Εντοπίζοντας πιθανούς ενδιαφερόμενους πελάτες},
date = {2022-11-24},
url = {https://stesiam.com/el/posts/predict-possible-clients/},
langid = {el}
}