Το σύνολο δεδομένων που αναλύεται είναι το IBM HR Analytics Employee Attrition & Performance, το οποίο αντλήθηκε από την πλατφόρμα Kaggle.
Αποτελείται από 1470 εγγραφές και 35 μεταβλητές, που σχετίζονται με δημογραφικά στοιχεία, την απόδοση και την εργασιακή ικανοποίηση και κυρίως αν έχουν Αποχωρήσει από την εταιρεία ή όχι.
Η επιλογή του συγκεκριμένου dataset έγινε, διότι ο συνδυασμός των ποσοτικών και ποιοτικών δεδομένων, που προσφέρει σχετικά με το τμήμα του Ανθρωπίνου Δυναμικού στα πλαίσια της Επιχειρηματικής Αναλυτικής επιτρέπει την χρήση στατιστικών εργαλείων για τη λήψη αποφάσεων, που αφορούν τη διακράτηση του προσωπικού και τη βελτίωση του εργασιακού περιβάλλοντος.
| Μεταβλητή | Τύπος | Εύρος Τιμών | Μονάδες Μέτρησης |
|---|---|---|---|
| Age | Διακριτή | 18 - 60 | Έτη |
| DailyRate | Διακριτή | 102 - 1499 | Νομισματικές Μονάδες (π.χ. Ευρώ) |
| DistanceFromHome | Διακριτή | 1 - 29 | Απόσταση (συνήθως Μίλια) |
| HourlyRate | Διακριτή | 30 - 100 | Νομισματικές Μονάδες ανά ώρα |
| MonthlyIncome | Συνεχής | 1.009 - 19.999 | Νομισματικές Μονάδες ανά μήνα |
| MonthlyRate | Διακριτή | 2.094 - 26.999 | Νομισματικές Μονάδες |
| NumCompaniesWorked | Διακριτή | 0 - 9 | Αριθμός εταιρειών |
| PercentSalaryHike | Διακριτή | 11 - 25 | Ποσοστό (%) |
| TotalWorkingYears | Διακριτή | 0 - 40 | Έτη |
| TrainingTimesLastYear | Διακριτή | 0 - 6 | Αριθμός εκπαιδεύσεων |
| YearsAtCompany | Διακριτή | 0 - 40 | Έτη |
| YearsInCurrentRole | Διακριτή | 0 - 18 | Έτη |
| YearsSinceLastPromotion | Διακριτή | 0 - 15 | Έτη |
| YearsWithCurrManager | Διακριτή | 0 - 17 | Έτη |
| Μεταβλητή | Περιγραφή / Τιμές |
|---|---|
| Attrition | Εγκατάλειψη εργασίας (Yes, No) |
| BusinessTravel | Συχνότητα ταξιδιών (Non-Travel, Travel_Rarely, Travel_Frequently) |
| Department | Τμήμα (Sales, Research & Development, Human Resources) |
| EducationField | Τομέας εκπαίδευσης (Life Sciences, Medical, Marketing, κ.α.) |
| Gender | Φύλο (Female, Male) |
| JobRole | Ρόλος εργασίας (Manager, Sales Executive, Laboratory Technician, κ.α.) |
| MaritalStatus | Οικογενειακή κατάσταση (Single, Married, Divorced) |
| OverTime | Υπερωρίες (Yes, No) |
| Μεταβλητή | Εύρος (Κλίμακα) | Περιγραφή |
|---|---|---|
| Education | 1 - 5 | Επίπεδο εκπαίδευσης (1: Χαμηλό, 5: Υψηλό) |
| EnvironmentSatisfaction | 1 - 4 | Ικανοποίηση από το περιβάλλον εργασίας |
| JobInvolvement | 1 - 4 | Βαθμός εμπλοκής στην εργασία |
| JobLevel | 1 - 5 | Ιεραρχικό επίπεδο θέσης |
| JobSatisfaction | 1 - 4 | Ικανοποίηση από την εργασία |
| PerformanceRating | 3 - 4 | Αξιολόγηση απόδοσης |
| RelationshipSatisfaction | 1 - 4 | Ικανοποίηση από τις σχέσεις στην εργασία |
| StockOptionLevel | 0 - 3 | Επίπεδο δικαιωμάτων προαίρεσης μετοχών |
| WorkLifeBalance | 1 - 4 | Ισορροπία επαγγελματικής/προσωπικής ζωής |
##* Φόρτωση Δεδομένων*
# Φόρτωση των δεδομένων
hr_data <- read.csv("WA_Fn-UseC_-HR-Employee-Attrition.csv", stringsAsFactors = TRUE)
# Έλεγχος των πρώτων γραμμών για να δούμε αν φορτώθηκαν σωστά
head(hr_data)
## Age Attrition BusinessTravel DailyRate Department
## 1 41 Yes Travel_Rarely 1102 Sales
## 2 49 No Travel_Frequently 279 Research & Development
## 3 37 Yes Travel_Rarely 1373 Research & Development
## 4 33 No Travel_Frequently 1392 Research & Development
## 5 27 No Travel_Rarely 591 Research & Development
## 6 32 No Travel_Frequently 1005 Research & Development
## DistanceFromHome Education EducationField EmployeeCount EmployeeNumber
## 1 1 2 Life Sciences 1 1
## 2 8 1 Life Sciences 1 2
## 3 2 2 Other 1 4
## 4 3 4 Life Sciences 1 5
## 5 2 1 Medical 1 7
## 6 2 2 Life Sciences 1 8
## EnvironmentSatisfaction Gender HourlyRate JobInvolvement JobLevel
## 1 2 Female 94 3 2
## 2 3 Male 61 2 2
## 3 4 Male 92 2 1
## 4 4 Female 56 3 1
## 5 1 Male 40 3 1
## 6 4 Male 79 3 1
## JobRole JobSatisfaction MaritalStatus MonthlyIncome MonthlyRate
## 1 Sales Executive 4 Single 5993 19479
## 2 Research Scientist 2 Married 5130 24907
## 3 Laboratory Technician 3 Single 2090 2396
## 4 Research Scientist 3 Married 2909 23159
## 5 Laboratory Technician 2 Married 3468 16632
## 6 Laboratory Technician 4 Single 3068 11864
## NumCompaniesWorked Over18 OverTime PercentSalaryHike PerformanceRating
## 1 8 Y Yes 11 3
## 2 1 Y No 23 4
## 3 6 Y Yes 15 3
## 4 1 Y Yes 11 3
## 5 9 Y No 12 3
## 6 0 Y No 13 3
## RelationshipSatisfaction StandardHours StockOptionLevel TotalWorkingYears
## 1 1 80 0 8
## 2 4 80 1 10
## 3 2 80 0 7
## 4 3 80 0 8
## 5 4 80 1 6
## 6 3 80 0 8
## TrainingTimesLastYear WorkLifeBalance YearsAtCompany YearsInCurrentRole
## 1 0 1 6 4
## 2 3 3 10 7
## 3 3 3 0 0
## 4 3 3 8 7
## 5 3 3 2 2
## 6 2 2 7 7
## YearsSinceLastPromotion YearsWithCurrManager
## 1 0 5
## 2 1 7
## 3 0 0
## 4 3 0
## 5 2 2
## 6 3 6
#Ορισμός σταθεράς
set.seed(971)
#Διαχωρισμός training set 65%
split <- sample.split(hr_data$Attrition, SplitRatio = 0.65)
train = subset(hr_data, split == TRUE)
test = subset(hr_data, split == FALSE)
nrow(train) # 955 παρατηρήσεις στο σετ
## [1] 955
nrow(test) # 515 παρατηρήσεις στο σετ
## [1] 515
# Δημιουργία του δέντρου απόφασης
modelTree <- rpart(Attrition ~ .,
data = train,
method = "class",
minbucket = 25)
#Οπτικοποίηση του δέντρου
prp(modelTree)
summary(modelTree)
## Call:
## rpart(formula = Attrition ~ ., data = train, method = "class",
## minbucket = 25)
## n= 955
##
## CP nsplit rel error xerror xstd
## 1 0.01948052 0 1.0000000 1.000000 0.07379963
## 2 0.01000000 5 0.8636364 1.064935 0.07568116
##
## Variable importance
## TotalWorkingYears MonthlyIncome MaritalStatus
## 21 18 11
## OverTime JobRole StockOptionLevel
## 11 10 9
## Department Age EducationField
## 6 4 2
## EnvironmentSatisfaction JobLevel EmployeeNumber
## 2 1 1
## NumCompaniesWorked PercentSalaryHike
## 1 1
##
## Node number 1: 955 observations, complexity param=0.01948052
## predicted class=No expected loss=0.1612565 P(node) =1
## class counts: 801 154
## probabilities: 0.839 0.161
## left son=2 (891 obs) right son=3 (64 obs)
## Primary splits:
## TotalWorkingYears < 1.5 to the right, improve=17.22843, (0 missing)
## YearsWithCurrManager < 0.5 to the right, improve=15.03562, (0 missing)
## OverTime splits as LR, improve=13.72871, (0 missing)
## YearsAtCompany < 1.5 to the right, improve=13.54575, (0 missing)
## MonthlyIncome < 2489.5 to the right, improve=13.51039, (0 missing)
## Surrogate splits:
## MonthlyIncome < 1952.5 to the right, agree=0.956, adj=0.344, (0 split)
## Age < 19.5 to the right, agree=0.945, adj=0.172, (0 split)
##
## Node number 2: 891 observations, complexity param=0.01948052
## predicted class=No expected loss=0.1358025 P(node) =0.9329843
## class counts: 770 121
## probabilities: 0.864 0.136
## left son=4 (642 obs) right son=5 (249 obs)
## Primary splits:
## OverTime splits as LR, improve=10.156900, (0 missing)
## StockOptionLevel < 0.5 to the right, improve= 7.195703, (0 missing)
## JobRole splits as LRRLLLRRR, improve= 5.523535, (0 missing)
## MonthlyIncome < 2366.5 to the right, improve= 5.283238, (0 missing)
## JobLevel < 1.5 to the right, improve= 5.175377, (0 missing)
## Surrogate splits:
## EmployeeNumber < 6 to the right, agree=0.722, adj=0.004, (0 split)
## MonthlyRate < 26923.5 to the left, agree=0.722, adj=0.004, (0 split)
##
## Node number 3: 64 observations
## predicted class=Yes expected loss=0.484375 P(node) =0.06701571
## class counts: 31 33
## probabilities: 0.484 0.516
##
## Node number 4: 642 observations
## predicted class=No expected loss=0.08878505 P(node) =0.6722513
## class counts: 585 57
## probabilities: 0.911 0.089
##
## Node number 5: 249 observations, complexity param=0.01948052
## predicted class=No expected loss=0.2570281 P(node) =0.260733
## class counts: 185 64
## probabilities: 0.743 0.257
## left son=10 (218 obs) right son=11 (31 obs)
## Primary splits:
## MonthlyIncome < 2469.5 to the right, improve=8.968706, (0 missing)
## JobRole splits as LRRLLLRRR, improve=8.497992, (0 missing)
## JobLevel < 1.5 to the right, improve=8.346915, (0 missing)
## TotalWorkingYears < 8.5 to the right, improve=7.526620, (0 missing)
## StockOptionLevel < 0.5 to the right, improve=7.152651, (0 missing)
## Surrogate splits:
## Age < 21.5 to the right, agree=0.888, adj=0.097, (0 split)
## JobRole splits as LLLLLLLLR, agree=0.884, adj=0.065, (0 split)
## TotalWorkingYears < 2.5 to the right, agree=0.880, adj=0.032, (0 split)
##
## Node number 10: 218 observations, complexity param=0.01948052
## predicted class=No expected loss=0.206422 P(node) =0.2282723
## class counts: 173 45
## probabilities: 0.794 0.206
## left son=20 (121 obs) right son=21 (97 obs)
## Primary splits:
## JobRole splits as LLRLLLLRR, improve=8.332643, (0 missing)
## MaritalStatus splits as LLR, improve=6.148074, (0 missing)
## StockOptionLevel < 0.5 to the right, improve=5.546788, (0 missing)
## Age < 35.5 to the right, improve=4.110907, (0 missing)
## Department splits as LLR, improve=4.037134, (0 missing)
## Surrogate splits:
## Department splits as LLR, agree=0.835, adj=0.629, (0 split)
## EducationField splits as LLRLLL, agree=0.670, adj=0.258, (0 split)
## MonthlyIncome < 10574 to the right, agree=0.642, adj=0.196, (0 split)
## TotalWorkingYears < 13.5 to the right, agree=0.628, adj=0.165, (0 split)
## JobLevel < 2.5 to the right, agree=0.624, adj=0.155, (0 split)
##
## Node number 11: 31 observations
## predicted class=Yes expected loss=0.3870968 P(node) =0.03246073
## class counts: 12 19
## probabilities: 0.387 0.613
##
## Node number 20: 121 observations
## predicted class=No expected loss=0.08264463 P(node) =0.1267016
## class counts: 111 10
## probabilities: 0.917 0.083
##
## Node number 21: 97 observations, complexity param=0.01948052
## predicted class=No expected loss=0.3608247 P(node) =0.1015707
## class counts: 62 35
## probabilities: 0.639 0.361
## left son=42 (65 obs) right son=43 (32 obs)
## Primary splits:
## MaritalStatus splits as LLR, improve=10.192270, (0 missing)
## StockOptionLevel < 0.5 to the right, improve= 7.787882, (0 missing)
## EnvironmentSatisfaction < 2.5 to the right, improve= 4.341539, (0 missing)
## YearsAtCompany < 8.5 to the right, improve= 3.384596, (0 missing)
## JobSatisfaction < 3.5 to the right, improve= 2.832591, (0 missing)
## Surrogate splits:
## StockOptionLevel < 0.5 to the right, agree=0.918, adj=0.750, (0 split)
## EnvironmentSatisfaction < 1.5 to the right, agree=0.722, adj=0.156, (0 split)
## EmployeeNumber < 66.5 to the right, agree=0.701, adj=0.094, (0 split)
## NumCompaniesWorked < 7.5 to the left, agree=0.701, adj=0.094, (0 split)
## PercentSalaryHike < 22.5 to the left, agree=0.701, adj=0.094, (0 split)
##
## Node number 42: 65 observations
## predicted class=No expected loss=0.2 P(node) =0.06806283
## class counts: 52 13
## probabilities: 0.800 0.200
##
## Node number 43: 32 observations
## predicted class=Yes expected loss=0.3125 P(node) =0.03350785
## class counts: 10 22
## probabilities: 0.312 0.688
###Ερμηνεία του Δέντρου CART
Αν κάποιος έχει λιγότερα από 2 χρόνια συνολικής προϋπηρεσίας (δεξιά διαδρομή), το μοντέλο προβλέπει άμεσα ότι θα αποχωρήσει (Yes).
Αν δεν κάνουν υπερωρίες (αριστερά), το μοντέλο προβλέπει ότι θα μείνουν (No).
3.Μηνιαίο Εισόδημα (MonthlyIncome >= 2470): Αν κάνουν υπερωρίες, το εισόδημα παίζει ρόλο.
Αν ο μισθός είναι χαμηλότερος από 2470 (δεξιά), προβλέπεται αποχώρηση (Yes).
# Πραγματοποίηση προβλέψεων στο test set
predictCART <- predict(modelTree, newdata = test, type = "class")
# Δημιουργία του Confusion Matrix (πίνακας ταξινόμησης)
conf_matrix_tree <- table(test$Attrition, predictCART)
print(conf_matrix_tree)
## predictCART
## No Yes
## No 402 30
## Yes 51 32
# Υπολογισμός Ακρίβειας του CART
accuracy_tree <- sum(diag(conf_matrix_tree)) / sum(conf_matrix_tree)
print(paste("Accuracy Δέντρου Απόφασης:", round(accuracy_tree, 4)))
## [1] "Accuracy Δέντρου Απόφασης: 0.8427"
# Υπολογισμός Ακρίβειας Baseline Model
baseline_acc <- max(table(test$Attrition)) / nrow(test)
print(paste("Accuracy Baseline Model:", round(baseline_acc, 4)))
## [1] "Accuracy Baseline Model: 0.8388"
# Προβλέψεις πιθανοτήτων (χωρίς το type="class") για την καμπύλη ROC
predictROC_tree <- predict(modelTree, newdata = test)
# Επιλέγουμε τη δεύτερη στήλη που αντιστοιχεί στην πιθανότητα "Yes"
library(ROCR)
pred_tree <- prediction(predictROC_tree[,2], test$Attrition)
perf_tree <- performance(pred_tree, "tpr", "fpr")
# Σχεδίαση Καμπύλης ROC
plot(perf_tree, colorize = TRUE, main = "ROC Curve for CART Model")
# Υπολογισμός AUC
auc_tree <- as.numeric(performance(pred_tree, "auc")@y.values)
print(paste("AUC Δέντρου Απόφασης:", round(auc_tree, 4)))
## [1] "AUC Δέντρου Απόφασης: 0.6562"
Κάποια συμπεράσματα, τα οποία προέκυψαν από τη σύγκριση των δύο μεθόδων στο ίδιο dataset, αποτελούν:
Λογιστική Παλινδρόμηση: Παρέχει συντελεστές που δείχνουν τη στατιστική σημαντικότητα και τη φορά της συσχέτισης (θετική/αρνητική), αλλά είναι δύσκολο να εξηγηθεί πώς συνδυάζονται οι μεταβλητές για μια συγκεκριμένη απόφαση. Δέντρα CART : Προσφέρουν υψηλή ερμηνευσιμότητα μέσω οπτικών κανόνων “Αν-Τότε” (If-Then rules). Η ιεραρχική δομή επιτρέπει σε μη ειδικούς να κατανοήσουν τη διαδρομή που οδηγεί στην πρόβλεψη.
Λογιστική Παλινδρόμηση: Απαιτεί προσεκτική προετοιμασία, όπως την
αφαίρεση μεταβλητών με μία μόνο τιμή (σταθερές) για να αποφευχθούν
σφάλματα στον κώδικα (π.χ. contrasts error).
Δέντρα CART: Είναι πιο ανθεκτικά σε ακραίες τιμές (outliers) και ελλιπή
δεδομένα. Επιπλέον, εντοπίζουν αυτόματα μη γραμμικές σχέσεις και
αλληλεπιδράσεις μεταξύ μεταβλητών χωρίς επιπλέον παραμετροποίηση.
Λογιστική Παλινδρόμηση: Συχνά επιτυγχάνει ελαφρώς υψηλότερη ακρίβεια
(Accuracy) και μεγαλύτερη περιοχή κάτω από την καμπύλη ROC (AUC) σε
σύγκριση με ένα απλό δέντρο CART.
Δέντρα CART: Παρόλο που μπορεί να υστερούν ελαφρώς σε απόλυτα νούμερα
ακρίβειας, η απόδοσή τους παραμένει ανταγωνιστική και σημαντικά ανώτερη
από το Baseline μοντέλο.
Επιλέγουμε τη Λογιστική Παλινδρόμηση όταν ο στόχος είναι η μέγιστη δυνατή ακρίβεια πρόβλεψης.Επιλέγουμε το CART όταν προτεραιότητα είναι η λήψη αποφάσεων βάσει κατανοητών κανόνων και η επικοινωνία των αποτελεσμάτων στη διοίκηση (HR management).