1 Introduction

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).

2 Data Preparation

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.

machine <- read.csv("machine.csv")

rmarkdown::paged_table(machine)
machine$fail <- as.factor(machine$fail)
glimpse(machine)
#> 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.

  • footfall : Ini mengukur berapa banyak individu atau barang yang berada di dekat suatu mesin.
  • tempMode : Mode atau pengaturan suhu mesin.
  • AQ : Indeks kualitas udara di dekat mesin.
  • USS : Pengukuran data sensor ultrasonik.
  • CS : Pembacaan sensor arus, menunjukkan penggunaan arus listrik mesin.
  • VOC : Tingkat senyawa organik volatil terdeteksi di dekat mesin.
  • RP : Posisi rotasi atau RPM (putaran per menit) dari bagian-bagian mesin.
  • IP : Tekanan masukan ke mesin.
  • Temperature : Suhu pengoperasian mesin.
  • fail : Indikator kegagalan mesin (1 untuk kegagalan, 0 untuk tidak ada kegagalan).

Kemudian kita akan melakukan pengecekan apakah dataset tersebut terdapat Missing Value.

machine %>% is.na() %>% colSums()
#>    footfall    tempMode          AQ         USS          CS         VOC 
#>           0           0           0           0           0           0 
#>          RP          IP Temperature        fail 
#>           0           0           0           0

3 Cross Validation

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)

3.1 Cek Imbalance Class

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.

table(train_machine$fail) %>% prop.table()
#> 
#>         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.

4 Modelling

4.1 Logistic Regression

4.1.1 Model Logsitic Regression

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
summary(model_machine_step)
#> 
#> 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.

4.1.2 Predict

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()

4.1.3 Model Evaluation

Untuk mengevaluasi model yang telah dibuat bisa menggunakan Confusion Matrix. Penentuan Kelasnya adalah sebagai berikut.

  • Kelas Positif: mesin dinyatakan gagal atau 1
  • Kelas Negatif: mesin dinyatakan tidak gagal atau 0

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.

  • Accuracy = 91.53%, berarti dari keseluruhan data aktual model dapat memprediksi dengan benar (pred_label = fail pada dataset test_machine) sebesar 91.53%.
  • Sensitivity/Recall = 90.91%, berarti model dapat memprediksi gagal mesin sebesar 90.91% dari total aktual gagal mesin.
  • Pos Pred Value/Precision = 90.91%, berarti model dapat memprediksi gagal mesin sebesar 90.91% dari total yang diprediksi gagal mesin.

4.2 K-Nearest Neighbour

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).

4.2.1 Understanding Data

Mari kita lihat kembali object machine awal yang kita gunakan.

machine %>% 
  head()

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.

4.2.2 Data Preprocessing - Scaling

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
dim(machine_test_x)
#> [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

4.2.3 Optimum k

k optimum adalah akar dari jumlah baris data dari data train kemudian dihitung dengan fungsi: sqrt(nrow(data))

sqrt( nrow(machine_train_xs) )
#> [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).

4.2.4 Predict

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.

test_machine$knn_label <- machine_knn

test_machine %>% 
  select(fail, knn_label) %>% 
  head()

4.2.5 Model Evaluation

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.

  • Accuracy = 90.48%, berarti dari keseluruhan data aktual model dapat memprediksi dengan benar (pred_label = fail pada dataset test_machine) sebesar 90.48%.
  • Sensitivity/Recall = 88.64%, berarti model dapat memprediksi gagal mesin sebesar 88.64% dari total aktual gagal mesin.
  • Pos Pred Value/Precision = 90.70%, berarti model dapat memprediksi gagal mesin sebesar 90.70% dari total yang diprediksi gagal mesin.

5 Conclusion

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.