Το dataset περιλαμβάνει πληροφορίες για 45.000 πελάτες που έχουν αιτηθεί για προσωπικά δάνεια. Περιλαμβάνει χαρακτηριστικά όπως ηλικία, εισόδημα, σκοπός δανείου, εμπειρία, ιστορικό πίστωσης, και αν ο πελάτης αποπλήρωσε ή όχι το δάνειό του.
Πηγή: Το dataset διατίθεται από το Kaggle.
Η πρόβλεψη πιθανής καθυστέρησης πληρωμής ενός δανείου είναι κρίσιμη για τα χρηματοπιστωτικά ιδρύματα. Μέσω αυτής της ανάλυσης, μπορούμε να εντοπίσουμε προφίλ πελατών με αυξημένο ρίσκο, να διαμορφώσουμε καλύτερες πολιτικές αξιολόγησης και να βελτιώσουμε τις διαδικασίες έγκρισης δανείων.
Πιθανά Επιχειρηματικά Ερωτήματα
| Μεταβλητή | Τύπος |
|---|---|
| person_age | Αριθμητικό |
| person_gender | Κατηγορική |
| person_education | Κατηγορική |
| person_income | Αριθμητικό |
| person_emp_exp | Αριθμητικό |
| person_home_ownership | Κατηγορική |
| loan_amnt | Αριθμητικό |
| loan_intent | Κατηγορική |
| loan_int_rate | Αριθμητικό |
| loan_percent_income | Αριθμητικό |
| cb_person_cred_hist_length | Αριθμητικό |
| credit_score | Αριθμητικό |
| previous_loan_defaults_on_file | Κατηγορική |
| loan_status | Δυαδικό |
## person_age person_gender person_education person_income
## Min. : 20.00 Length:45000 Length:45000 Min. : 8000
## 1st Qu.: 24.00 Class :character Class :character 1st Qu.: 47204
## Median : 26.00 Mode :character Mode :character Median : 67048
## Mean : 27.76 Mean : 80319
## 3rd Qu.: 30.00 3rd Qu.: 95789
## Max. :144.00 Max. :7200766
## person_emp_exp person_home_ownership loan_amnt loan_intent
## Min. : 0.00 Length:45000 Min. : 500 Length:45000
## 1st Qu.: 1.00 Class :character 1st Qu.: 5000 Class :character
## Median : 4.00 Mode :character Median : 8000 Mode :character
## Mean : 5.41 Mean : 9583
## 3rd Qu.: 8.00 3rd Qu.:12237
## Max. :125.00 Max. :35000
## loan_int_rate loan_percent_income cb_person_cred_hist_length credit_score
## Min. : 5.42 Min. :0.0000 Min. : 2.000 Min. :390.0
## 1st Qu.: 8.59 1st Qu.:0.0700 1st Qu.: 3.000 1st Qu.:601.0
## Median :11.01 Median :0.1200 Median : 4.000 Median :640.0
## Mean :11.01 Mean :0.1397 Mean : 5.867 Mean :632.6
## 3rd Qu.:12.99 3rd Qu.:0.1900 3rd Qu.: 8.000 3rd Qu.:670.0
## Max. :20.00 Max. :0.6600 Max. :30.000 Max. :850.0
## previous_loan_defaults_on_file loan_status
## Length:45000 Min. :0.0000
## Class :character 1st Qu.:0.0000
## Mode :character Median :0.0000
## Mean :0.2222
## 3rd Qu.:0.0000
## Max. :1.0000
Βλέπουμε μερικά πολύ σημαντικά outliers στο σύνολο δεδομένων μας.Είναι σημαντικό να αφαιρεθούν ώστε να μην επηρεαστούν αρνητικά οι προβλέψεις μας.
ggplot(loan_data_clean, aes(x = person_age, y = person_emp_exp, color = factor(loan_status))) +
geom_jitter(alpha = 0.5, width = 0.3, height = 0.3) +
labs(title = "Years of Experience vs. Age (Colored by Loan Status)",
x = "Age", y = "Employment Experience",
color = "Loan Status\n(0 = No Default, 1 = Defaulted)") +
scale_color_manual(values = c("red", "blue"),
labels = c("No Default", "Defaulted")) +
theme_minimal()Διάγραμμα 1. Σχέση Ηλικίας και Εμπειρίας ανά Κατάσταση Δανείου.
Σχόλιο: Οι περισσότερες καθυστερήσεις συμβαίνουν σε άτομα με χαμηλή εμπειρία και ηλικία.
ggplot(loan_data_clean, aes(x = person_home_ownership, y = loan_amnt, fill = factor(loan_status))) +
geom_boxplot() +
labs(title = "Loan Amount by Home Ownership",
x = "Home Ownership", y = "Loan Amount ($)",
fill = "Loan Status") +
theme_minimal()Διάγραμμα 2. Ποσό Δανείου ανά Κατοχή Κατοικίας.
Σχόλιο: Οι ιδιοκτήτες κατοικίας φαίνεται να λαμβάνουν μικρότερα δάνεια με λιγότερες καθυστερήσεις, ενώ οι ενοικιαστές εμφανίζουν μεγαλύτερη διακύμανση και υψηλότερο ρίσκο καθυστέρησης.
ggplot(loan_data_clean, aes(x = person_income, fill = factor(loan_status))) +
geom_histogram(position = "identity", alpha = 0.6, bins = 50) +
labs(title = "Income Distribution by Loan Status",
x = "Income", y = "Count", fill = "Loan Status") +
theme_minimal()Διάγραμμα 3. Κατανομή Εισοδήματος με βάση την Κατάσταση Δανείου.
Σχόλιο: Οι χαμηλότεροι μισθοί σχετίζονται με υψηλότερο ποσοστό καθυστέρησης.
ggplot(loan_data_clean, aes(x = person_education, fill = factor(loan_status))) +
geom_bar(position = "dodge", color = "black") +
labs(title = "Loan Status by Person Education",
x = "Education Level", y = "Count",
fill = "Loan Status\n(0 = No Default, 1 = Defaulted)") +
theme_light()Διάγραμμα 4. Κατάσταση Δανείου ως προς την Εκπαίδευση.
Σχόλιο: Οι δανειολήπτες με υψηλότερη εκπαίδευση φαίνεται να έχουν μικρότερα ποσοστά καθυστέρησης.
Για λόγους απλότητας, και εύκολης αντίληψης των διαγραμμάτων, ανάμεσα σε όλες τις αριθμητικές μεταβλητές, θα επιλεχθούν δύο. Ποιες όμως αποτελούν την καλύτερη επιλογή; Για αυτήν την απάντηση θα χρησιμοποιήσουμε την διασπορά και την συσχέτηση των μεταβλητών.
Train <- loan_data_clean
# Επιλογή αριθμητικών στηλών
numeric_vars <- Train[, sapply(Train, is.numeric)]
# Υπολογισμός διασποράς κάθε μεταβλητής
variances <- sapply(numeric_vars, var, na.rm = TRUE)
# Εμφάνιση διασποράς σε φθήνουσα σειρά
variances_sorted <- sort(variances, decreasing = TRUE)
print(variances_sorted)## person_income loan_amnt
## 4.009726e+09 3.987741e+07
## credit_score person_emp_exp
## 2.540021e+03 3.502119e+01
## person_age cb_person_cred_hist_length
## 3.482821e+01 1.502283e+01
## loan_int_rate loan_status
## 8.874551e+00 1.728653e-01
## loan_percent_income
## 7.605037e-03
# bar plot
barplot(variances_sorted, las = 2, col = "skyblue",
main = "Διασπορά μεταβλητών", ylab = "Variance")
Η διασπορά μάς δίνει πληροφορίες για το πόσο διαφορετικές είναι οι τιμές
μιας μεταβλητής από τον μέσο όρο της — δηλαδή, πόση πληροφορία (ή
ποικιλία) κουβαλάει η κάθε μεταβλητή.
Όπως φαίνεται στο παραπάνω διάγραμμα, η μεταβλητή person_income έχει πολύ υψηλότερη διασπορά σε σύγκριση με όλες τις υπόλοιπες. Αυτό σημαίνει ότι περιέχει σημαντική διαφοροποίηση στις τιμές της και επομένως μπορεί να προσφέρει ουσιαστικό διαχωρισμό μεταξύ των παρατηρήσεων. Οι υπόλοιπες μεταβλητές εμφανίζουν σχετικά χαμηλή διασπορά, γεγονός που τις καθιστά λιγότερο χρήσιμες για τον σχηματισμό διακριτών ομάδων.
Επομένως, η person_income είναι ισχυρή υποψήφια μεταβλητή για να χρησιμοποιηθεί στη διαδικασία συσταδοποίησης.
Αφού βρήκαμε ποιες μεταβλητές έχουν σημαντική διασπορά (variance), πρέπει τώρα να ελέγξουμε ποιες από αυτές δεν είναι πολύ συσχετισμένες μεταξύ τους. Αν δύο μεταβλητές έχουν πολύ υψηλή συσχέτιση (π.χ. > 0.85), σημαίνει ότι “μεταφέρουν” την ίδια πληροφορία. Στη συσταδοποίηση, αυτό μπορεί να προκαλέσει παραμόρφωση και επαναλαμβανόμενη πληροφορία.
# Επιλογή μόνο αριθμητικών μεταβλητών
numeric_vars <- loan_data_clean[, sapply(loan_data_clean, is.numeric)]
# Υπολογισμός πίνακα συσχέτισης (χωρίς NAs)
cor_matrix <- cor(numeric_vars, use = "complete.obs")
# Προβολή πίνακα
print(round(cor_matrix, 2))## person_age person_income person_emp_exp loan_amnt
## person_age 1.00 0.15 0.95 0.05
## person_income 0.15 1.00 0.14 0.31
## person_emp_exp 0.95 0.14 1.00 0.05
## loan_amnt 0.05 0.31 0.05 1.00
## loan_int_rate 0.01 0.00 0.02 0.15
## loan_percent_income -0.04 -0.29 -0.04 0.59
## cb_person_cred_hist_length 0.88 0.13 0.84 0.04
## credit_score 0.17 0.03 0.18 0.01
## loan_status -0.02 -0.17 -0.02 0.11
## loan_int_rate loan_percent_income
## person_age 0.01 -0.04
## person_income 0.00 -0.29
## person_emp_exp 0.02 -0.04
## loan_amnt 0.15 0.59
## loan_int_rate 1.00 0.13
## loan_percent_income 0.13 1.00
## cb_person_cred_hist_length 0.02 -0.03
## credit_score 0.01 -0.01
## loan_status 0.33 0.38
## cb_person_cred_hist_length credit_score loan_status
## person_age 0.88 0.17 -0.02
## person_income 0.13 0.03 -0.17
## person_emp_exp 0.84 0.18 -0.02
## loan_amnt 0.04 0.01 0.11
## loan_int_rate 0.02 0.01 0.33
## loan_percent_income -0.03 -0.01 0.38
## cb_person_cred_hist_length 1.00 0.15 -0.01
## credit_score 0.15 1.00 -0.01
## loan_status -0.01 -0.01 1.00
## corrplot 0.95 loaded
corrplot(cor_matrix, method = "color", type = "upper",
tl.col = "black", tl.cex = 0.8, order = "hclust",
title = "Πίνακας Συσχέτισης Αριθμητικών Μεταβλητών")
Από τον πίνακα συσχέτισης προκύπτει ότι ορισμένες μεταβλητές
παρουσιάζουν υψηλή μεταξύ τους συσχέτιση, όπως οι person_age και
person_emp_exp, ή loan_amnt και person_income. Αυτό καθιστά ανεπιθύμητη
την κοινή χρήση τους στη συσταδοποίηση, καθώς θα μεταφέρουν παρόμοια
πληροφορία. Αντίθετα, οι μεταβλητές loan_percent_income, loan_int_rate
και credit_score εμφανίζουν χαμηλή μεταξύ τους συσχέτιση και διαφορετική
πληροφορία, γεγονός που τις καθιστά πιο κατάλληλες για χρήση σε
clustering.
Για την εφαρμογή συσταδοποίησης (clustering), θα επιλεχθούν λοιπόν οι μεταβλητές person_income και loan_int_rate. Η person_income παρουσιάζει τη μεγαλύτερη διασπορά ανάμεσα στις αριθμητικές μεταβλητές, άρα προσφέρει πλούσια πληροφορία και συμβάλλει ουσιαστικά στον διαχωρισμό των ομάδων. Από την άλλη, η loan_int_rate εμφανίζει χαμηλή συσχέτιση με το εισόδημα, συνεπώς προσθέτει ανεξάρτητη πληροφορία στο μοντέλο και ενισχύει τη διακριτική ικανότητα του clustering. Η επιλογή αυτών των δύο μεταβλητών εξασφαλίζει καλύτερη ποιότητα συσταδοποίησης και πιο ερμηνεύσιμα αποτελέσματα.
# Δημιουργία νέου dataset με τις επιλεγμένες μεταβλητές
cluster_data <- loan_data_clean %>%
select(person_income, loan_int_rate)
# Κανονικοποίηση
scaled_data <- scale(cluster_data)Η κανονικοποίηση είναι απαραίτητη επειδή το person_income έχει πολύ μεγαλύτερη κλίμακα από το loan_int_rate, και αυτό θα επηρεάσει άδικα τους υπολογισμούς απόστασης.
set.seed(123)
sample_data <- scaled_data[sample(1:nrow(scaled_data), 2000), ] # δείγμα 2000 γραμμών
# υπολογισμός αποστάσεων και συσταδοποίηση
dist_matrix <- dist(sample_data, method = "euclidean")
hc_model <- hclust(dist_matrix, method = "ward.D2")
plot(hc_model, labels = FALSE, main = "Ιεραρχική Συσταδοποίηση (Δείγμα 2000)")
Λόγω του μεγάλου μεγέθους του dataset (45.000 παρατηρήσεις), η ιεραρχική
συσταδοποίηση δεν μπορεί να εφαρμοστεί σε όλα τα δεδομένα, καθώς απαιτεί
τεράστια μνήμη RAM για να υπολογίσει τον πίνακα αποστάσεων. Για τον λόγο
αυτό, χρησιμοποιήθηκε ένα τυχαίο υποσύνολο 2000 παρατηρήσεων, το οποίο
είναι επαρκές για να παρατηρηθεί η δομή των συστάδων και η γενική εικόνα
του δενδρογράμματος.
Το δενδρόγραμμα που προέκυψε από την ιεραρχική συσταδοποίηση με τη μέθοδο Ward.D2 απεικονίζει τη σταδιακή συγχώνευση παρατηρήσεων και ομάδων βάσει της μεταξύ τους ομοιότητας. Παρατηρείται ότι οι συστάδες σχηματίζονται με σαφήνεια σε δύο ή τρεις βασικούς κλάδους, κάτι που υποδηλώνει την ύπαρξη φυσικού διαχωρισμού στο δείγμα.
## clusters_hc
## 1 2 3
## 1378 619 3
Η συσταδοποίηση σε 3 ομάδες αποκάλυψε μία πολύ μικρή ομάδα (3 παρατηρήσεις), η οποία πιθανότατα αντιπροσωπεύει ακραίες τιμές (outliers), δηλαδή άτομα με ιδιαίτερα υψηλό εισόδημα ή πολύ διαφορετικά χαρακτηριστικά από το υπόλοιπο δείγμα. Οι δύο βασικές συστάδες περιλαμβάνουν τον κύριο όγκο των πελατών, διαχωρίζοντας πιθανώς μεταξύ μεσαίου/χαμηλού εισοδήματος και συγκριτικά υψηλότερου. Η παρουσία της πολύ μικρής συστάδας δείχνει ότι η ιεραρχική συσταδοποίηση μπορεί να ανιχνεύσει υποσύνολα σπάνιων περιπτώσεων, ενισχύοντας τη δυνατότητα στοχευμένης ανάλυσης σε μελλοντική επιχειρησιακή στρατηγική.
Επιλέγουμε k=3, καθώς από την ιεραρχική συσταδοποίηση φάνηκε να γίνεται ένας καλός διαχωρισμός.
# Εκπαίδευση K-means με 3 συστάδες
set.seed(123)
kmeans_model_3 <- kmeans(scaled_data, centers = 3, nstart = 25)
# Προσθήκη cluster labels
cluster_data$cluster3 <- factor(kmeans_model_3$cluster)
# Μέγεθος συστάδων
table(cluster_data$cluster3)##
## 1 2 3
## 25802 17282 1908
ggplot(cluster_data, aes(x = person_income, y = loan_int_rate, color = cluster3)) +
geom_point(alpha = 0.6) +
labs(title = "K-Means με 3 Συστάδες",
x = "Εισόδημα", y = "Επιτόκιο",
color = "Συστάδα") +
theme_minimal()
Το παραπάνω διάγραμμα παρουσιάζει την οπτική αναπαράσταση των 3 συστάδων
που προέκυψαν με τον αλγόριθμο K-Means, βάσει των μεταβλητών εισόδημα
(person_income) και επιτόκιο δανείου (loan_int_rate). Οι συστάδες
φαίνεται να διαφοροποιούνται κυρίως ως προς το εισόδημα:
Η πρώτη συστάδα (κόκκινη) συγκεντρώνει άτομα με πολύ χαμηλό εισόδημα και υψηλά επιτόκια.
Η δεύτερη συστάδα (πράσινη) περιλαμβάνει πελάτες με μέτριο εισόδημα και μέτρια επιτόκια.
Η τρίτη συστάδα (μπλε) περιλαμβάνει άτομα με πολύ υψηλά εισοδήματα, ανεξαρτήτως επιτοκίου — πιθανότατα πρόκειται για outliers.
Η ταξινόμηση των παρατηρήσεων είναι εύλογη και αποκαλύπτει χρήσιμες ομάδες πελατών. Η διαφοροποίηση με βάση το εισόδημα είναι κυρίαρχη, ενώ το επιτόκιο λειτουργεί επικουρικά στον σχηματισμό των ομάδων. Το γεγονός ότι η τρίτη συστάδα είναι διακριτή και μικρή, επιβεβαιώνει την παρουσία μιας ομάδας πελατών με ιδιαίτερο οικονομικό προφίλ.
# Elbow Method για εύρεση βέλτιστου αριθμού συστάδων
set.seed(123)
# Υπολογισμός WCSS (Within Cluster Sum of Squares) για 1 έως 10 συστάδες
wcss <- numeric(10)
for (k in 1:10) {
kmeans_model <- kmeans(scaled_data, centers = k, nstart = 20)
wcss[k] <- kmeans_model$tot.withinss
}## Warning: did not converge in 10 iterations
## Warning: did not converge in 10 iterations
## Warning: Quick-TRANSfer stage steps exceeded maximum (= 2249600)
## Warning: Quick-TRANSfer stage steps exceeded maximum (= 2249600)
# Διάγραμμα Elbow
plot(1:10, wcss, type = "b", pch = 19, col = "steelblue",
xlab = "Αριθμός Συστάδων (k)",
ylab = "WCSS (Συνολικό Σφάλμα Εντός Συστάδων)",
main = "Elbow Method για Επιλογή k")
Σύμφωνα με τη μέθοδο “Elbow”, η βέλτιστη τιμή του k εντοπίζεται γύρω στο
3, καθώς από εκεί και πέρα η μείωση στο WCSS γίνεται πιο ήπια. Το
αποτέλεσμα αυτό επιβεβαιώνει την ανάλυση της ιεραρχικής συσταδοποίησης,
όπου παρατηρήθηκαν 2 βασικές ομάδες και μία τρίτη μικρή (πιθανώς
αποτελούμενη από outliers). Συνεπώς, η επιλογή 3 συστάδων στον αλγόριθμο
K-Means θεωρείται αιτιολογημένη και στατιστικά ορθή.