1 Introduction

1.1 Tujuan Pelatihan

Sebelum mengenal tentang classification, mari sedikit membahas tentang machine learning itu sendiri. Machine Learning adalah suatu bidang ilmiah yang mempelajari tentang algoritma dan model statistik yang digunakan oleh sistem komputer dengan mengandalkan pola. Machine learning atau dalam Bahasa Indonesia Pembelajaran Mesin juga memberikan kemampuan pada sistem untuk secara otomatis belajar dan meningkat dari pengalaman tanpa diprogram secara eksplisit. Pembelajaran mesin berfokus pada pengembangan program komputer yang dapat mengakses data dan menggunakannya untuk belajar sendiri.

Lalu kita masuk kedalam pembahasan apa itu classification? Classification dapat didefinisikan sebagai proses memprediksi kelas atau kategori dari nilai yang diamati atau titik data yang diberikan. Output yang dikategorikan dapat memiliki bentuk seperti “Black” atau “White” atau “spam” atau “no spam”. Secara matematis, classification adalah tugas mendekati fungsi pemetaan (f) dari variabel input (X) ke variabel output (Y). Ini pada dasarnya milik pembelajaran mesin yang diawasi di mana target juga disediakan bersama dengan set data input.

BERBAGAI ALGORITMA CLASSIFICATION

Berikut ini adalah beberapa algoritma classification :

  • Logistic Regression

  • Support Vector Machine (SVM)

  • Decision Tree

  • Naïve Bayes

  • Random Forest

Tujuan utama dari kursus ini adalah untuk memberikan pengenalan yang komprehensif untuk classification in machine learning dengan menggunakan data yang ada.

Mempelajari algoritma klasifikasi dari dasar, menyelidiki dasar matematika yang mendukung algoritma logistic regression dan algoritma nearest neighbors.

2 Explanatory Data Analysis

2.1 Import Library & Data

Load Library

library(dplyr)
library(class)
library(caret)

Load Data

turn_over <- read.csv("turnover_balance.csv")
turn_over

Data turnover terdiri dari 10 kolom dan 7142 baris. Data ini merupakan data Human Resource (HR) yang menunjukkan rekam historis karakteristik karyawan yang telah mengundurkan diri dan yang tidak. Di bawah ini merupakan informasi detail terkait variabel yang terdapat pada dataset:

  • satisfaction_level: tingkat kepuasan karyawan selama bekerja di perusahaan
  • last_evaluation: tingkat kepuasan karyawan pada evaluasi terakhir
  • number_project: jumlah projek yang diterima oleh karyawan
  • average_monthly_hours: rata-rata jam kerja per bulan
  • time_spend_company: lama waktu bekerja di perusahaan (dalam tahun)
  • work_accident: ada atau tidaknya kecelakaan kerja, 0 = tidak ada, 1 = ada
  • promotion_last_5years: apakah karyawan pernah mendapatkan promosi dalam 5 tahun terakhir, 0 = tidak, 1 = ya
  • division: nama divisi atau departemen
  • salary: tingkat pendapatan, dibedakan menjadi low, medium, dan high
  • left: apakah karyawan mengundurkan diri, 0 = tidak, 1 = ya (target)

2.2 Data Wrangling

Kita akan memprediksi kecenderungan karyawan untuk mengundurkan diri atau tidak yang tersimpan dalam kolom left sebagai variabel target. Kita akan ubah tipe data pada kolom Work_accident, promotion_last_5years, division, salary dan left agar menjadi tipe data factor seperti seharusnya.

str(turn_over)
#> 'data.frame':    7142 obs. of  10 variables:
#>  $ satisfaction_level   : num  0.82 0.79 0.73 0.92 0.69 0.98 0.52 0.51 0.88 0.76 ...
#>  $ last_evaluation      : num  0.68 0.67 0.95 0.78 1 0.97 0.9 0.73 0.99 0.85 ...
#>  $ number_project       : int  3 5 3 3 5 3 4 4 3 3 ...
#>  $ average_monthly_hours: int  140 156 149 218 237 209 285 229 190 192 ...
#>  $ time_spend_company   : int  2 2 2 3 3 3 2 3 5 3 ...
#>  $ Work_accident        : int  0 0 0 0 0 0 0 0 0 0 ...
#>  $ promotion_last_5years: int  0 0 0 0 0 0 0 0 0 0 ...
#>  $ division             : chr  "sales" "product_mng" "support" "technical" ...
#>  $ salary               : chr  "low" "low" "low" "low" ...
#>  $ left                 : int  0 0 0 0 0 0 0 0 0 0 ...

Ubah Tipe Data

turn_over_clean <- turn_over %>% 
  mutate(
    Work_accident = as.factor(Work_accident),
    promotion_last_5years = as.factor(promotion_last_5years),
    division = as.factor(division),
    salary = as.factor(salary),
    left = as.factor(left)
  )

str(turn_over_clean)
#> 'data.frame':    7142 obs. of  10 variables:
#>  $ satisfaction_level   : num  0.82 0.79 0.73 0.92 0.69 0.98 0.52 0.51 0.88 0.76 ...
#>  $ last_evaluation      : num  0.68 0.67 0.95 0.78 1 0.97 0.9 0.73 0.99 0.85 ...
#>  $ number_project       : int  3 5 3 3 5 3 4 4 3 3 ...
#>  $ average_monthly_hours: int  140 156 149 218 237 209 285 229 190 192 ...
#>  $ time_spend_company   : int  2 2 2 3 3 3 2 3 5 3 ...
#>  $ Work_accident        : Factor w/ 2 levels "0","1": 1 1 1 1 1 1 1 1 1 1 ...
#>  $ promotion_last_5years: Factor w/ 2 levels "0","1": 1 1 1 1 1 1 1 1 1 1 ...
#>  $ division             : Factor w/ 10 levels "accounting","hr",..: 8 6 9 10 10 9 2 8 10 5 ...
#>  $ salary               : Factor w/ 3 levels "high","low","medium": 2 2 2 2 1 2 2 2 1 2 ...
#>  $ left                 : Factor w/ 2 levels "0","1": 1 1 1 1 1 1 1 1 1 1 ...

Misal, sebagai seorang staff HR, kita diminta untuk menginvestigasi divisi yang memiliki rekam jejak karyawan yang mengundurkan diri berdasarkan rata-rata jam kerja per bulan. Silahkan lakukan agregasi data berdasarkan average_monthly_hours untuk masing-masing divisi. Karena Anda hanya fokus pada karyawan yang mengundurkan diri, Anda harus menyeleksi data berdasarkan kondisi yang dibutuhkan.

avg_hour_agg <- turn_over_clean %>% 
  group_by(division) %>% # mengelompokkan berdasarkan kolom division
  summarise(mean_hour = mean(average_monthly_hours)) %>% # merata2kan untuk setiap channel_title
  ungroup() %>% 
  arrange(desc(mean_hour))

avg_hour_agg

Berdasarkan agregasi data yang telah dibuat, divisi yang merupakan 3 divisi dengan rata-rata jam kerja per bulan tertinggi adalah technical, IT, dan RnD.

2.3 Cek missing value

colSums(is.na(turn_over_clean))
#>    satisfaction_level       last_evaluation        number_project 
#>                     0                     0                     0 
#> average_monthly_hours    time_spend_company         Work_accident 
#>                     0                     0                     0 
#> promotion_last_5years              division                salary 
#>                     0                     0                     0 
#>                  left 
#>                     0

Dataset yang ada sudah baik, karena tidak ada nilai missing value.

2.4 Cek Proporsi Balance

Setelah melakukan eksplorasi data, kita akan melanjutkan pada tahap pre-proses sebelum membangun model klasifikasi. Lihatlah proporsi kelas pada variabel target yaitu kolom left dengan menggunakan fungsi prop.table(table(data)).

prop.table(table(turn_over_clean$left))
#> 
#>   0   1 
#> 0.5 0.5

Variabel target kita terlihat memiliki proporsi kelas yang seimbang.

3 Cross Validation

Sebelum kita membangun model, kita harus memisahkan data menjadi data train dan test agar dapat memvalidasi performa model klasifikasi yang dibuat. Pisahkan data turn_over_clean dengan pembagian proporsi 80% untuk data train dan 20% untuk data test menggunakan fungsi sample(). Gunakan set.seed() dengan besaran 100. Simpan hasil pemisahan data pada objek train dan test.

RNGkind(sample.kind = "Rounding")
set.seed(100)

# index sampling
index <- sample(x = nrow(turn_over_clean), 
                size = nrow(turn_over_clean)*0.8)

# splitting
turn_over_train <- turn_over_clean[index,] # mengambil 80% dari total data untuk digunakan sebagai data train
turn_over_test <- turn_over_clean[-index,] # 20% sisanya digunakan sebagai data test

Mari kita lihat proporsi kelas target pada data train menggunakan fungsi prop.table(table(data)) untuk memastikan data train memiliki proporsi kelas yang seimbang.

round(prop.table(table(turn_over_train$left)), digits = 2)
#> 
#>   0   1 
#> 0.5 0.5

Variabel target kita terlihat memiliki proporsi kelas yang seimbang.

4 Data Pre-Processing

4.1 Model Fitting Logistic Regression

Setelah membagi data menjadi data train dan test, mari kita modelkan variabel left dengan menggunakan seluruh variabel sebagai prediktor dengan regresi logistik.

model_logistic <- glm(formula = left ~ .,
                   data = turn_over_train,
                   family = "binomial")

Berdasarkan model_logistic yang telah dibuat, mari kita lihat ringkasan model menggunakan fungsi summary().

summary(model_logistic)
#> 
#> Call:
#> glm(formula = left ~ ., family = "binomial", data = turn_over_train)
#> 
#> Deviance Residuals: 
#>     Min       1Q   Median       3Q      Max  
#> -3.2893  -0.7749  -0.0707   0.8286   2.8346  
#> 
#> Coefficients:
#>                          Estimate Std. Error z value Pr(>|z|)    
#> (Intercept)            -0.9916588  0.2572100  -3.855 0.000116 ***
#> satisfaction_level     -4.6637026  0.1554522 -30.001  < 2e-16 ***
#> last_evaluation         1.3486580  0.2441434   5.524 3.31e-08 ***
#> number_project         -0.4619596  0.0345888 -13.356  < 2e-16 ***
#> average_monthly_hours   0.0046603  0.0008423   5.533 3.16e-08 ***
#> time_spend_company      0.5433006  0.0302083  17.985  < 2e-16 ***
#> Work_accident1         -1.5683412  0.1248489 -12.562  < 2e-16 ***
#> promotion_last_5years1 -1.8527726  0.3521320  -5.262 1.43e-07 ***
#> divisionhr              0.1506603  0.1944332   0.775 0.438417    
#> divisionIT             -0.1697472  0.1801030  -0.943 0.345936    
#> divisionmanagement     -0.6447231  0.2268468  -2.842 0.004482 ** 
#> divisionmarketing      -0.0871136  0.1933533  -0.451 0.652320    
#> divisionproduct_mng    -0.3322115  0.1877558  -1.769 0.076830 .  
#> divisionRandD          -0.5623727  0.2053928  -2.738 0.006181 ** 
#> divisionsales          -0.1007493  0.1501597  -0.671 0.502254    
#> divisionsupport         0.0185694  0.1599557   0.116 0.907580    
#> divisiontechnical       0.1114474  0.1569055   0.710 0.477528    
#> salarylow               2.0031532  0.1716264  11.672  < 2e-16 ***
#> salarymedium            1.5014787  0.1729044   8.684  < 2e-16 ***
#> ---
#> Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
#> 
#> (Dispersion parameter for binomial family taken to be 1)
#> 
#>     Null deviance: 7919.9  on 5712  degrees of freedom
#> Residual deviance: 5773.6  on 5694  degrees of freedom
#> AIC: 5811.6
#> 
#> Number of Fisher Scoring iterations: 5

Interpretasi:

Mengubah log of odds ke nilai odds

exp(model_logistic$coefficient)
#>            (Intercept)     satisfaction_level        last_evaluation 
#>            0.370960820            0.009431476            3.852252357 
#>         number_project  average_monthly_hours     time_spend_company 
#>            0.630047803            1.004671202            1.721680060 
#>         Work_accident1 promotion_last_5years1             divisionhr 
#>            0.208390582            0.156801811            1.162601623 
#>             divisionIT     divisionmanagement      divisionmarketing 
#>            0.843878131            0.524807857            0.916572975 
#>    divisionproduct_mng          divisionRandD          divisionsales 
#>            0.717335564            0.569855369            0.904159693 
#>        divisionsupport      divisiontechnical              salarylow 
#>            1.018742927            1.117894976            7.412392267 
#>           salarymedium 
#>            4.488320943

Regresi logistik adalah salah satu model yang dapat diinterpretasikan. Kita dapat menjelaskan bagaimana masing-masing variabel memberikan pengaruh pada hasil prediksi. Berdasarkan ringkasan model di atas, beberapa contoh yang dapat diinterpretasikan dari koefisiennya: > - Karyawan yang berada di divisi HR 1.16 kali lebih mungkin untuk mengundurkan diri dibandingkan karyawan di divisi Accounting. - Karyawan yang mendapatkan medium salary 4.48 kali lebih mungkin untuk mengundurkan diri dibandingkan karyawan yang menerima high salary.

4.1.1 Modeling

Sekarang, kita akan membuat model dengan menggunakan feature selection “stepwise-backward”:

# stepwise
model_step1 <- step(object = model_logistic,
                   direction = "backward", 
                   trace = 0)

summary(model_step1)
#> 
#> Call:
#> glm(formula = left ~ satisfaction_level + last_evaluation + number_project + 
#>     average_monthly_hours + time_spend_company + Work_accident + 
#>     promotion_last_5years + division + salary, family = "binomial", 
#>     data = turn_over_train)
#> 
#> Deviance Residuals: 
#>     Min       1Q   Median       3Q      Max  
#> -3.2893  -0.7749  -0.0707   0.8286   2.8346  
#> 
#> Coefficients:
#>                          Estimate Std. Error z value Pr(>|z|)    
#> (Intercept)            -0.9916588  0.2572100  -3.855 0.000116 ***
#> satisfaction_level     -4.6637026  0.1554522 -30.001  < 2e-16 ***
#> last_evaluation         1.3486580  0.2441434   5.524 3.31e-08 ***
#> number_project         -0.4619596  0.0345888 -13.356  < 2e-16 ***
#> average_monthly_hours   0.0046603  0.0008423   5.533 3.16e-08 ***
#> time_spend_company      0.5433006  0.0302083  17.985  < 2e-16 ***
#> Work_accident1         -1.5683412  0.1248489 -12.562  < 2e-16 ***
#> promotion_last_5years1 -1.8527726  0.3521320  -5.262 1.43e-07 ***
#> divisionhr              0.1506603  0.1944332   0.775 0.438417    
#> divisionIT             -0.1697472  0.1801030  -0.943 0.345936    
#> divisionmanagement     -0.6447231  0.2268468  -2.842 0.004482 ** 
#> divisionmarketing      -0.0871136  0.1933533  -0.451 0.652320    
#> divisionproduct_mng    -0.3322115  0.1877558  -1.769 0.076830 .  
#> divisionRandD          -0.5623727  0.2053928  -2.738 0.006181 ** 
#> divisionsales          -0.1007493  0.1501597  -0.671 0.502254    
#> divisionsupport         0.0185694  0.1599557   0.116 0.907580    
#> divisiontechnical       0.1114474  0.1569055   0.710 0.477528    
#> salarylow               2.0031532  0.1716264  11.672  < 2e-16 ***
#> salarymedium            1.5014787  0.1729044   8.684  < 2e-16 ***
#> ---
#> Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
#> 
#> (Dispersion parameter for binomial family taken to be 1)
#> 
#>     Null deviance: 7919.9  on 5712  degrees of freedom
#> Residual deviance: 5773.6  on 5694  degrees of freedom
#> AIC: 5811.6
#> 
#> Number of Fisher Scoring iterations: 5

4.1.2 Predict

Pada bagian ini, cobalah untuk memprediksi data test menggunakan model_logistic untuk menghasilkan nilai probabilitas. Gunakan fungsi predict() dengan mengatur parameter type = "response".

turn_over_test$prob_value <- predict(object = model_step1,
                      newdata = turn_over_test,
                      type = "response")

Karena hasil prediksi pada model regresi logistik berupa probabilitas, kita harus mengubah nilai tersebut menjadi kategori/ kelas target kita. Dengan menggunakan threshold 0.55, cobalah untuk mengklasifikan mana karyawan yang akan mengundurkan diri atau tidak. Silahkan gunakan fungsi `ifelse().

turn_over_test$pred_value <- ifelse(test = turn_over_test$prob_value > 0.55,
                                yes = 1,
                                no = 0)
turn_over_test$pred_value <- as.factor(turn_over_test$pred_value)
# lihat hasil prediksi
turn_over_test %>% 
  select(prob_value,
         pred_value,
         left)

4.1.3 Model Evaluation

table(predict = turn_over_test$pred_value,
      actual = turn_over_test$left)
#>        actual
#> predict   0   1
#>       0 546 171
#>       1 163 549

Pada tahap ini, buatlah confusion matrix dari model regresi logistik menggunakan label aktual dari data test dan hasil prediksi kemudian atur kelas positif yaitu “1” (positive = "1").

confusionMatrix(data = turn_over_test$pred_value, 
                reference = turn_over_test$left,
                positive = "1")
#> Confusion Matrix and Statistics
#> 
#>           Reference
#> Prediction   0   1
#>          0 546 171
#>          1 163 549
#>                                          
#>                Accuracy : 0.7663         
#>                  95% CI : (0.7434, 0.788)
#>     No Information Rate : 0.5038         
#>     P-Value [Acc > NIR] : <2e-16         
#>                                          
#>                   Kappa : 0.5326         
#>                                          
#>  Mcnemar's Test P-Value : 0.7017         
#>                                          
#>             Sensitivity : 0.7625         
#>             Specificity : 0.7701         
#>          Pos Pred Value : 0.7711         
#>          Neg Pred Value : 0.7615         
#>              Prevalence : 0.5038         
#>          Detection Rate : 0.3842         
#>    Detection Prevalence : 0.4983         
#>       Balanced Accuracy : 0.7663         
#>                                          
#>        'Positive' Class : 1              
#> 

left: apakah karyawan mengundurkan diri, 0 = tidak, 1 = ya.

Resiko nya:

  • FN - Recall / Sensitivity - Prediksi stay (0), nyatanya resign (1).

  • FP - Precision / Pos Pred Value - Prediksi resign (1), nyatanya stay (0).

4.2 Model Fitting K-Nearest Neighbor

Sekarang mari kita mengeksplorasi algoritma klasifikasi k-Nearest Neighbor. Pada algoritma k-Nearest Neighbor, kita perlu melakukan satu tahap data pre-proses tambahan. Untuk setiap data train dan test yang kita miliki, hilangkan variabel kategorik kecuali variabel left. Pisahkan variabel prediktor dan target dari data train dan test.

str(turn_over_clean)
#> 'data.frame':    7142 obs. of  10 variables:
#>  $ satisfaction_level   : num  0.82 0.79 0.73 0.92 0.69 0.98 0.52 0.51 0.88 0.76 ...
#>  $ last_evaluation      : num  0.68 0.67 0.95 0.78 1 0.97 0.9 0.73 0.99 0.85 ...
#>  $ number_project       : int  3 5 3 3 5 3 4 4 3 3 ...
#>  $ average_monthly_hours: int  140 156 149 218 237 209 285 229 190 192 ...
#>  $ time_spend_company   : int  2 2 2 3 3 3 2 3 5 3 ...
#>  $ Work_accident        : Factor w/ 2 levels "0","1": 1 1 1 1 1 1 1 1 1 1 ...
#>  $ promotion_last_5years: Factor w/ 2 levels "0","1": 1 1 1 1 1 1 1 1 1 1 ...
#>  $ division             : Factor w/ 10 levels "accounting","hr",..: 8 6 9 10 10 9 2 8 10 5 ...
#>  $ salary               : Factor w/ 3 levels "high","low","medium": 2 2 2 2 1 2 2 2 1 2 ...
#>  $ left                 : Factor w/ 2 levels "0","1": 1 1 1 1 1 1 1 1 1 1 ...

4.2.1 Data Wrangling

turn_clean <- turn_over_clean %>% 
  select(-c(Work_accident, promotion_last_5years, division, salary))

str(turn_clean)
#> 'data.frame':    7142 obs. of  6 variables:
#>  $ satisfaction_level   : num  0.82 0.79 0.73 0.92 0.69 0.98 0.52 0.51 0.88 0.76 ...
#>  $ last_evaluation      : num  0.68 0.67 0.95 0.78 1 0.97 0.9 0.73 0.99 0.85 ...
#>  $ number_project       : int  3 5 3 3 5 3 4 4 3 3 ...
#>  $ average_monthly_hours: int  140 156 149 218 237 209 285 229 190 192 ...
#>  $ time_spend_company   : int  2 2 2 3 3 3 2 3 5 3 ...
#>  $ left                 : Factor w/ 2 levels "0","1": 1 1 1 1 1 1 1 1 1 1 ...

4.2.2 Cross Validation

RNGkind(sample.kind = "Rounding")
set.seed(100)

# index sampling
index1 <- sample(x = nrow(turn_clean), 
                size = nrow(turn_clean)*0.8)

# splitting
turn_train <- turn_clean[index1,] # mengambil 80% dari total data untuk digunakan sebagai data train
turn_test <- turn_clean[-index1,] # 20% sisanya digunakan sebagai data tes
# variabel prediktor pada `train`
train_x <- select(turn_train, -left)

# variabel prediktor pada `test`
test_x <- select(turn_test, -left)

# variabel target pada `train`
train_y <- turn_train[,"left"]

# variabel target pada `test`
test_y <- turn_test[,"left"]

Ingatlah bahwa pengukuran jarak pada kNN sangat bergantung pada skala data dari variabel prediktor yang dimasukkan sebagai input model. Adanya prediktor yang memiliki range nilai yang amat berbeda dari prediktor lainnya dapat menyebabkan masalah pada model klasifikasi. Oleh karena itu, mari lakukan normalisasi data untuk menyamakan skala dari tiap variabel prediktor agar memiliki range nilai yang standar.

Untuk menormalisasi data train_x, silahkan gunakan fungsi scale(). Sementara itu, untuk menormalisasi data test, silahkan gunakan fungsi yang sama namun menggunakan atribut center dan scale yang didapat dari data train_x.

turn_train_x_scale <- scale(x = train_x)

# scale train_x data
turn_test_x_scale <- scale(x = test_x,                                          # melakukan scale untuk test dari scale train
                           center = attr(turn_train_x_scale, "scaled:center"),
                           scale = attr(turn_train_x_scale, "scaled:scale"))

k-NN tidak membuat model sehingga langsung ke predict.

4.2.3 Predict

Find K - Optimum

sqrt(nrow(turn_train))
#> [1] 75.58439

apakah karyawan mengundurkan diri? 0 = tidak, 1 = ya, Target variable ada 2: kelas (1-) = ya & (0-) = tidak

sehingga K- nya ganjil : 75 / 77

Dengan menggunakan nilai k yang telah kita dapatkan, cobalah untuk memprediksi test_y dengan menggunakan data train_x dan train_y. Untuk membuat model kNN, silahkan gunakan fungsi knn() dan simpanlah hasil prediksi pada objek model_knn.

model_knn <- knn(train = turn_train_x_scale, 
                 test = turn_test_x_scale, 
                 cl = train_y, 
                 k = 77)

# cek hasil prediksi
head(model_knn)
#> [1] 0 0 0 0 0 0
#> Levels: 0 1

Membuat confusion matrix untuk hasil prediksi model_knn dan label aktual test_y.

confusionMatrix(data = model_knn, #hasil prediksi
                reference = test_y, #
                positive = "1")
#> Confusion Matrix and Statistics
#> 
#>           Reference
#> Prediction   0   1
#>          0 646  57
#>          1  63 663
#>                                           
#>                Accuracy : 0.916           
#>                  95% CI : (0.9004, 0.9299)
#>     No Information Rate : 0.5038          
#>     P-Value [Acc > NIR] : <2e-16          
#>                                           
#>                   Kappa : 0.832           
#>                                           
#>  Mcnemar's Test P-Value : 0.6481          
#>                                           
#>             Sensitivity : 0.9208          
#>             Specificity : 0.9111          
#>          Pos Pred Value : 0.9132          
#>          Neg Pred Value : 0.9189          
#>              Prevalence : 0.5038          
#>          Detection Rate : 0.4640          
#>    Detection Prevalence : 0.5080          
#>       Balanced Accuracy : 0.9160          
#>                                           
#>        'Positive' Class : 1               
#> 

left: apakah karyawan mengundurkan diri, 0 = tidak, 1 = ya.

Resiko nya:

  • FN - Recall / Sensitivity - Prediksi stay (0), nyatanya resign (1).

  • FP - Precision / Pos Pred Value - Prediksi resign (1), nyatanya stay (0).

5 Conclusion

Dengan Model Logistic Regression:

  • Accuracy = 76.63%

  • Sensitivity / Recall = 76.25%

  • Pos Pred Value / Precision = 77.11%

Dengan Model KNN:

  • Accuracy = 91.60%

  • Sensitivity / Recall = 92.08%

  • Pos Pred Value / Precision = 91.32%

Kesimpulan untuk evaluasi Model KNN lebih baik dalam melakukan klasifikasi daripada model Logistic Regression.