Mendeteksi apakah suatu mesin akan mengalami kegagalan atau tidak dapat membantu perusahaan untuk mengurangi kemungkinan kerugian yang disebabkan oleh mesin rusak dan mengetahui mesin mana saja yang perlu dilakukan maintenance. Di sini terdapat Machine Failure dataset yang berisi tentang data sensor yang diperoleh dari kegagalan mesin yang terekam. Dari dataset tersebut akan dibuat model machine learning untuk memprediksi data sensor mesin masa depan apakah suatu mesin akan mengalami kegagalan atau tidak dengan menggunakan algoritma Logistic Regression dan K-Nearest Neighbor (KNN).
Kita akan memuat terlebih dahulu semua Library yang nantinya akan digunakan dalam melakukan analisis-analisis.
library(dplyr)
library(inspectdf)
library(gtools)
library(caret)
library(readxl)
library(rsample)
library(class)
Kemudian memuat dataset Machine Failure.
#> Rows: 944
#> Columns: 10
#> $ footfall <int> 0, 190, 31, 83, 640, 110, 100, 31, 180, 2800, 1600, 330, 1…
#> $ tempMode <int> 7, 1, 7, 4, 7, 3, 7, 1, 7, 0, 0, 5, 2, 7, 7, 7, 7, 5, 7, 2…
#> $ AQ <int> 7, 3, 2, 3, 5, 3, 5, 5, 4, 3, 3, 4, 5, 4, 5, 6, 4, 3, 6, 2…
#> $ USS <int> 1, 3, 2, 4, 6, 4, 6, 4, 6, 3, 2, 3, 4, 4, 7, 7, 4, 3, 2, 1…
#> $ CS <int> 6, 5, 6, 5, 4, 6, 4, 5, 3, 7, 4, 6, 6, 6, 4, 5, 5, 6, 6, 4…
#> $ VOC <int> 6, 1, 1, 1, 0, 1, 1, 4, 3, 0, 4, 1, 5, 0, 0, 0, 1, 1, 5, 0…
#> $ RP <int> 36, 20, 24, 28, 68, 21, 77, 21, 31, 39, 26, 31, 22, 42, 74…
#> $ IP <int> 3, 4, 6, 6, 6, 4, 4, 4, 4, 3, 2, 4, 4, 5, 1, 3, 3, 6, 4, 3…
#> $ Temperature <int> 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2…
#> $ fail <fct> 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0…
Dari hasil pembacaan dataset di atas, terdapat 944 data observasi dengan 10 kolom. Di sini kolom fail menjadi targetnya dan 9 kolom sisanya akan menjadi prediktor. Adapun untuk penjelasan masing-masing kolom adalah sebagai berikut.
Kemudian kita akan melakukan pengecekan apakah dataset tersebut terdapat Missing Value.
#> footfall tempMode AQ USS CS VOC
#> 0 0 0 0 0 0
#> RP IP Temperature fail
#> 0 0 0 0
Sebelum membuat model, di sini kita perlu memecah data menjadi 2 bagian yaitu train_machine untuk melakukan pelatihan model yang akan dibuat dan test_machine untuk menguji model yang telah dibuat.
RNGkind(sample.kind = "Rounding")
set.seed(123)
splitter <- initial_split(data = machine, prop = 0.8)
train_machine <- training(splitter)
test_machine <- testing(splitter)
Proporsi yang seimbang penting agar model klasifikasi mempelajari karakteristik setiap kelas secara seimbang, tidak dominan hanya satu kelas saja. Hal ini mencegah model bias terhadap kelas yang lebih besar proporsinya sehingga hanya baik untuk memprediksi 1 kelas saja. Maka dari itu, perlu dicek imbalance class dari dataset train_machine.
#>
#> 0 1
#> 0.5960265 0.4039735
Dari hasil pengecekan di atas dapat diketahui bahwa train_machine memiliki proporsi class pada kolom fail yaitu sebesar 60:40 yang mana proporsi tersebut masih dikatakan cukup seimbang sehingga bisa digunakan sebagai data train.
Dalam pemodelan logistic regression penting untuk menentukan variabel mana saja yang memiliki korelasi yang signifikan terhadap target. Kali ini akan digunakan Model Stepwise-backward untuk menyeleksi variabel apa saja yang memiliki korelasi secara signifikan terhadap target.
model_machine_all <- glm(formula = fail ~ .,
data = train_machine,
family = "binomial"
)
model_machine_step <- step(object = model_machine_all,
direction = "backward")
#> Start: AIC=360.44
#> fail ~ footfall + tempMode + AQ + USS + CS + VOC + RP + IP +
#> Temperature
#>
#> Df Deviance AIC
#> - tempMode 1 340.46 358.46
#> - RP 1 340.48 358.48
#> - footfall 1 340.62 358.62
#> - IP 1 341.02 359.02
#> - Temperature 1 341.47 359.47
#> <none> 340.44 360.44
#> - CS 1 353.92 371.92
#> - AQ 1 364.85 382.85
#> - USS 1 398.09 416.09
#> - VOC 1 518.92 536.92
#>
#> Step: AIC=358.46
#> fail ~ footfall + AQ + USS + CS + VOC + RP + IP + Temperature
#>
#> Df Deviance AIC
#> - RP 1 340.54 356.54
#> - footfall 1 340.65 356.65
#> - IP 1 341.05 357.05
#> - Temperature 1 341.53 357.53
#> <none> 340.46 358.46
#> - CS 1 354.02 370.02
#> - AQ 1 364.88 380.88
#> - USS 1 398.32 414.32
#> - VOC 1 518.97 534.97
#>
#> Step: AIC=356.54
#> fail ~ footfall + AQ + USS + CS + VOC + IP + Temperature
#>
#> Df Deviance AIC
#> - footfall 1 340.72 354.72
#> - IP 1 341.08 355.08
#> - Temperature 1 341.61 355.61
#> <none> 340.54 356.54
#> - CS 1 354.02 368.02
#> - AQ 1 365.25 379.25
#> - USS 1 400.00 414.00
#> - VOC 1 519.05 533.05
#>
#> Step: AIC=354.72
#> fail ~ AQ + USS + CS + VOC + IP + Temperature
#>
#> Df Deviance AIC
#> - IP 1 341.26 353.26
#> - Temperature 1 341.82 353.82
#> <none> 340.72 354.72
#> - CS 1 354.22 366.22
#> - AQ 1 365.74 377.74
#> - USS 1 400.00 412.00
#> - VOC 1 520.31 532.31
#>
#> Step: AIC=353.26
#> fail ~ AQ + USS + CS + VOC + Temperature
#>
#> Df Deviance AIC
#> - Temperature 1 343.23 353.23
#> <none> 341.26 353.26
#> - CS 1 354.37 364.37
#> - AQ 1 365.79 375.79
#> - USS 1 401.05 411.05
#> - VOC 1 522.05 532.05
#>
#> Step: AIC=353.23
#> fail ~ AQ + USS + CS + VOC
#>
#> Df Deviance AIC
#> <none> 343.23 353.23
#> - CS 1 355.59 363.59
#> - AQ 1 367.11 375.11
#> - USS 1 407.70 415.70
#> - VOC 1 533.54 541.54
#>
#> Call:
#> glm(formula = fail ~ AQ + USS + CS + VOC, family = "binomial",
#> data = train_machine)
#>
#> Coefficients:
#> Estimate Std. Error z value Pr(>|z|)
#> (Intercept) -1.50950 0.94667 -1.595 0.110816
#> AQ 0.62723 0.13256 4.732 0.00000222477184 ***
#> USS -0.92222 0.12610 -7.314 0.00000000000026 ***
#> CS -0.41405 0.11648 -3.555 0.000379 ***
#> VOC 0.97394 0.08764 11.113 < 0.0000000000000002 ***
#> ---
#> Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
#>
#> (Dispersion parameter for binomial family taken to be 1)
#>
#> Null deviance: 1018.63 on 754 degrees of freedom
#> Residual deviance: 343.23 on 750 degrees of freedom
#> AIC: 353.23
#>
#> Number of Fisher Scoring iterations: 6
Dari hasil Stepwise-Backward di atas, variabel yang berpengaruh secara signifikan terhadap target fail adalah AQ, USS, CS dan VOC serta model logistic regression yang akan digunakan adalah model_machine_step.
Selanjutnya di sini akan dilakukan prediksi terhadap dataset test_machine menggunakan model_machine_step dan kemudian menyimpan hasil prediksi tersebut ke dalam kolom baru yaitu pred_prob pada dataset test_machine.
test_machine$pred_prob <- predict(object = model_machine_step,
newdata = test_machine,
type = "response")
test_machine %>% head()
Dikarenakan hasil prediksi masih dalam bentuk Probabilitas maka di sini perlu mengubah hasil prediksi tersebut ke dalam kelasnya masing-masing dengan threshold atau ambang batas pada prob > 0.50 yaitu masuk ke kelas 1 = gagal begitu juga sebaliknya. Hasil pengelompokan prediksi tadi disimpan ke kolom baru yaitu pred_label.
test_machine$pred_label <- ifelse(test_machine$pred_prob > 0.50,
yes = "1",
no = "0")
test_machine %>% head()
Untuk mengevaluasi model yang telah dibuat bisa menggunakan Confusion Matrix. Penentuan Kelasnya adalah sebagai berikut.
Dapat kita lihat penjelasan Confusion Matrix di bawah ini.
conf_machine <- confusionMatrix(data = as.factor(test_machine$pred_label),
reference = test_machine$fail,
positive = "1")
conf_machine
#> Confusion Matrix and Statistics
#>
#> Reference
#> Prediction 0 1
#> 0 93 8
#> 1 8 80
#>
#> Accuracy : 0.9153
#> 95% CI : (0.8662, 0.9508)
#> No Information Rate : 0.5344
#> P-Value [Acc > NIR] : <0.0000000000000002
#>
#> Kappa : 0.8299
#>
#> Mcnemar's Test P-Value : 1
#>
#> Sensitivity : 0.9091
#> Specificity : 0.9208
#> Pos Pred Value : 0.9091
#> Neg Pred Value : 0.9208
#> Prevalence : 0.4656
#> Detection Rate : 0.4233
#> Detection Prevalence : 0.4656
#> Balanced Accuracy : 0.9149
#>
#> 'Positive' Class : 1
#>
Dari hasil Confusion Matrix di atas, didapatkan informasi sebagai berikut.
k-NN atau K-Nearest Neighbor mengklasifikasi data baru dengan membandingkan karakteristik data baru (data test) dengan data yang ada (data train).
Kedekatan karakteristik diukur dengan Euclidean Distance hingga didapatkan k titik data (tetangga) dengan jarak terdekat. Kelas terbanyak yang dimiliki para tetangga ini yang menjadi kelas dari data baru (majority voting).
Mari kita lihat kembali object machine
awal yang kita
gunakan.
Pada KNN, data input hanya bisa dalam bentuk numerik. Hal ini karena
perhitungan di baliknya menggunakan Euclidean Distance.
Karena semua variabel yang ada pada object machine
sudah
numerik dan tidak ada data factor, maka kita bisa langsung menggunakan
data machine
serta menggunakan data Cross
Validation pada saat pembuatan model Logistic Regression.
Skala data dari masing-masing variabel harus sama sebelum dilakukan pemodelan, maka perlu dilakukan Scaling Data terhadap data train_machine dan data test_machine.
Sebelum scaling, untuk k-NN, dipisahkan terlebih dahulu antara prediktor dan label (target variabelnya).
# prediktor
machine_train_x <- train_machine %>% select(-fail)
machine_test_x <- test_machine %>% select(-c(fail, pred_prob, pred_label))
# target
machine_train_y <- train_machine$fail
machine_test_y <- test_machine$fail
dim(machine_train_x)
#> [1] 755 9
#> [1] 189 9
Setelah itu kita lakukan scaling terhadap seluruh variabel dengan metode Z-score Standardization melalui fungsi seperti di bawah ini.
# scaling data
# train
machine_train_xs <- scale(machine_train_x)
# test
machine_test_xs <- scale(machine_test_x,
center = attr(machine_train_xs, "scaled:center"),
scale = attr(machine_train_xs, "scaled:scale"))
machine_train_xs %>% head()
#> footfall tempMode AQ USS CS VOC
#> [1,] -0.2532175 -0.6502830 -0.9385855 -0.67991700 0.4821345 -1.2358529
#> [2,] -0.1253962 -1.0208217 0.4744396 -0.67991700 -0.2940095 -0.7975866
#> [3,] -0.2858339 0.4613329 1.1809521 -0.67991700 0.4821345 0.9554786
#> [4,] -0.2408761 -1.0208217 -1.6450981 -0.67991700 0.4821345 0.5172123
#> [5,] -0.2849524 -1.0208217 -0.9385855 0.03107654 0.4821345 -0.3593203
#> [6,] -0.1959183 -1.3913603 -1.6450981 0.03107654 0.4821345 -0.7975866
#> RP IP Temperature
#> [1,] 1.5151937 -0.3188690 -0.39124461
#> [2,] -0.9224181 -0.9377537 0.77301651
#> [3,] 1.2104922 0.9189002 -0.05859857
#> [4,] 0.2963878 1.5377849 1.10566255
#> [5,] 1.0886116 1.5377849 1.27198556
#> [6,] -1.5318211 0.9189002 -2.22079780
k optimum adalah akar dari jumlah baris data dari
data train kemudian dihitung dengan fungsi:
sqrt(nrow(data))
#> [1] 27.47726
Karena kelas target dari data kita adalah 2, maka k Optimum yang bisa digunakan sesuai dengan hasil perhitungan di atas yaitu 27 (Ganjil).
machine_knn <- knn(train = machine_train_xs, # data train
test = machine_test_xs, # data yang akan diprediksi
cl = machine_train_y, # label dari data train
k = 27) # jumlah tetangga
Menyimpan hasil machine_knn
ke dalam kolom baru pada
data test.
conf_machine_knn <- confusionMatrix(data = as.factor(test_machine$knn_label),
reference = test_machine$fail,
positive="1")
conf_machine_knn
#> Confusion Matrix and Statistics
#>
#> Reference
#> Prediction 0 1
#> 0 93 10
#> 1 8 78
#>
#> Accuracy : 0.9048
#> 95% CI : (0.8537, 0.9426)
#> No Information Rate : 0.5344
#> P-Value [Acc > NIR] : <0.0000000000000002
#>
#> Kappa : 0.8083
#>
#> Mcnemar's Test P-Value : 0.8137
#>
#> Sensitivity : 0.8864
#> Specificity : 0.9208
#> Pos Pred Value : 0.9070
#> Neg Pred Value : 0.9029
#> Prevalence : 0.4656
#> Detection Rate : 0.4127
#> Detection Prevalence : 0.4550
#> Balanced Accuracy : 0.9036
#>
#> 'Positive' Class : 1
#>
Dari hasil Confusion Matrix di atas, didapatkan informasi sebagai berikut.
Dari hasil Confusion Matrix masing-masing model, semuanya memberikan hasil yang baik dalam memprediksi dengan mayoritas nilai pada Accuracy, Sensitivity/Recall dan Pos Pred Value/Precision berkisar di 90%.
Kembali lagi ke tujuan utama masalah bisnis yang ingin diselesaikan yaitu membuat sistem Early Warning untuk mendeteksi mesin mana yang memiliki kemungkinan akan gagal atau rusak, sehingga perusahaan bisa melakukan maintenance untuk mencegah kerusakan tersebut.
Dari perumusan masalah di atas, maka dapat disimpulkan bahwa kita lebih memperhatikan sekecil mungkin jumlah mesin yang diprediksi tidak gagal/rusak namun sebenarnya gagal/rusak (FN), daripada jumlah mesin yang diprediksi gagal/rusak, namun sebenarnya tidak rusak (FP).
Maka, metirks performa model yang digunakan adalah Sensitivity/Recall dengan logika semakin tinggi nilai Sensitivity maka semakin kecil jumlah FN. Rumus untuk menghitung Sensitivity sebagai berikut. \[\frac{TP}{(TP+FN)}\] Sehingga jika diantara 2 model di atas, yang menunjukan nilai Sensitivity/Recall lebih tinggi yaitu model Logistic Regression model_machine_step.