1 Pendahuluan

Kali ini Data Scientist menggunakan beberapa algoritma machine learning untuk mengungkap pola-pola yang tersembunyi dalam rangka mendapatkan insigth dari suatu data. Pada level analisis yang tinggi, beberapa algoritma tersebut secara garis besar dapat dibagi menjadi dua bagian berdasarkan bagaimana “mereka” belajar yaitu supervised learning dan unsupervised learning.

Pendekatan supervised learning adalah algoritma yang paling sering digunakan dalam dunia data science dibandingkan dengan unsupervised learning. Analisis regresi linier berganda maupun logistik yang notabene sudah tidak asing lagi di dengar adalah salah satu contoh dari supervised learning.

Perbedaan kedua algorima tersebut terletak pada bagaimana mereka belajar untuk membuat suatu prediksi maupun klasifikasi. Dalam supervised learning, algoritma tersebut seolah-olah dilatih terlebih dahulu agar dapat melakukan prediksi maupun klasifikasi.

Pendekatan supervised learning mempuyai input dan output yang dapat dibuat menjadi suatu model hubungan matematis sehingga mampu melakukan prediksi dan klasifikasi berdasarkan data yang telah ada sebelumnya.

Misalkan pada suatu sumur pemboran di Lapangan Loris, ingin melakukan peramalan tentang pengaruh berbagai parameter pemboran dari beberapa data sumur aktual yang sudah dikerjakan. dimana target yang digunakan adalah ROP (Rate of Penetration). Dataset yang digunakan masih melanjutkan data tugas dari LBB C1-ML sebelumnya. Analisis deret kedalaman (layaknya model regresi) menggunakan data sebelumnya untuk menggunakan prediksi. Data pada periode sebelumnya itulah yang disebut dengan data latih atau data training.

Sehingga dengan data training tersebut akan diperoleh suatu model regresi yang selanjutnya akan digunakan untuk melakukan peramalan. Jadi kesimpulannya adalah supervised learning menggunakan data latih (data training) dalam melakukan prediksi maupun klasifikasi. Beberapa algoritma yang termasuk dalam supervised learning adalah sebagai berikut :

- Regresi Linier Berganda
- Analisis Deret Waktu
- Decision Tree dan Random Forest
- Naive Bayes Classifier
- Nearest Neighbor Classifier
- Artificial Neural Network
- Support Vector Machine

Berbeda dengan analisis Unsupervised Learning, pendekatannya tidak menggunakan data latih atau data training untuk melakukan prediksi maupun klasifikasi. Berdasarkan model matematisnya, algoritma ini tidak memiliki target variabel. Salah satu tujuan dari algoritma ini adalah mengelompokkan objek yang hampir sama dalam suatu area tertentu.

Dengan kata lain, jika kita memiliki target variabel (Y) maka kita dapat menggunakan pendekatan supervised learning sedangkan jika kita memiliki target variabel, maka kita dapat menggunakan unsupervised learning. Supervised learning membutuhkan data training (harus dilatih terlebih dahulu) sedangkan unsupervised learning tidak membutuhkan data training (tidak perlu dilatih terlebih dahulu).

READ DATA

Dataset yang digunakan sama dengan data yang digunakan pada Regression model sebelumnya yaitu “Loris_Drilling.csv”

drilling <- read.csv("Loris_Drilling.csv", stringsAsFactors = F)
str(drilling)
## 'data.frame':    54196 obs. of  27 variables:
##  $ wellName   : chr  "Loris 12H" "Loris 12H" "Loris 12H" "Loris 12H" ...
##  $ datasetName: chr  "Drilling" "Drilling" "Drilling" "Drilling" ...
##  $ Depth      : num  401 402 402 402 403 ...
##  $ Bitm       : num  0.64 1.16 1.63 2.11 2.67 3.16 3.6 4.11 4.63 5.07 ...
##  $ BitRevs    : int  280 305 326 347 371 392 411 432 453 471 ...
##  $ DrillHrs   : num  0.01 0.02 0.02 0.03 0.03 0.04 0.04 0.05 0.06 0.06 ...
##  $ Dxc        : int  0 0 0 0 0 0 0 0 0 0 ...
##  $ FlowRate   : num  414 415 414 415 415 ...
##  $ MSE        : num  439 419 407 437 471 ...
##  $ MSE_DAVG   : num  1.03 1.02 1.02 1.02 1.02 ...
##  $ MW.In      : num  0.216 0.216 0.216 0.216 0.216 0.216 0.216 0.216 0.216 0.216 ...
##  $ MW.Out     : num  0.26 0.27 0.28 0.28 0.29 0.29 0.3 0.3 0.31 0.32 ...
##  $ POWER      : num  2100 2094 2090 2099 2082 ...
##  $ Pump.time  : num  75.9 78.4 80.5 81.4 84.6 ...
##  $ PVT        : num  1.99 2 2 2.01 2.02 2.02 2.03 2.03 2.04 2.04 ...
##  $ ROP        : num  61 60 60 61 61 60 60 60 61 61 ...
##  $ RotatingHrs: num  61 60 60 61 61 60 60 60 61 61 ...
##  $ RPM        : num  226 227 226 227 227 ...
##  $ RPM.SURF   : num  32.9 32.9 33 33 32.9 32.9 33 33 33 32.9 ...
##  $ SPP        : num  30.8 30.8 30.8 30.8 30.7 30.8 30.8 30.8 30.8 30.8 ...
##  $ Temp.In    : num  2 3 3 2 2 3 3 3 3 1 ...
##  $ Temp.Out   : num  1 2 2 1 2 2 2 2 3 1 ...
##  $ TORQUE     : int  3 4 4 3 3 4 4 4 3 2 ...
##  $ Torque.max.: num  412 413 414 414 414 ...
##  $ Torque_2   : num  0.1 0.9 1.2 1 0.8 1.6 0.7 1.1 1.3 0.1 ...
##  $ TVD        : num  NA NA NA NA NA NA NA NA NA NA ...
##  $ WOB        : num  NA NA NA NA NA NA NA NA NA NA ...

Berikut ini gambaran sedikit pada data yang digunakan.

head(drilling)
##    wellName datasetName Depth Bitm BitRevs DrillHrs Dxc FlowRate    MSE
## 1 Loris 12H    Drilling 401.0 0.64     280     0.01   0   413.94 438.70
## 2 Loris 12H    Drilling 401.5 1.16     305     0.02   0   414.54 418.52
## 3 Loris 12H    Drilling 402.0 1.63     326     0.02   0   413.74 407.39
## 4 Loris 12H    Drilling 402.5 2.11     347     0.03   0   414.94 437.37
## 5 Loris 12H    Drilling 403.0 2.67     371     0.03   0   415.34 471.06
## 6 Loris 12H    Drilling 403.5 3.16     392     0.04   0   414.94 432.84
##   MSE_DAVG MW.In MW.Out   POWER Pump.time  PVT ROP RotatingHrs    RPM RPM.SURF
## 1    1.033 0.216   0.26 2099.75     75.89 1.99  61          61 226.07     32.9
## 2    1.025 0.216   0.27 2094.23     78.36 2.00  60          60 226.73     32.9
## 3    1.021 0.216   0.28 2089.72     80.46 2.00  60          60 226.44     33.0
## 4    1.017 0.216   0.28 2098.98     81.38 2.01  61          61 226.83     33.0
## 5    1.022 0.216   0.29 2082.44     84.61 2.02  61          61 227.13     32.9
## 6    1.023 0.216   0.29 2083.50     85.54 2.02  60          60 227.35     32.9
##    SPP Temp.In Temp.Out TORQUE Torque.max. Torque_2 TVD WOB
## 1 30.8       2        1      3       412.5      0.1  NA  NA
## 2 30.8       3        2      4       413.0      0.9  NA  NA
## 3 30.8       3        2      4       413.5      1.2  NA  NA
## 4 30.8       2        1      3       414.0      1.0  NA  NA
## 5 30.7       2        2      3       414.5      0.8  NA  NA
## 6 30.8       3        2      4       415.0      1.6  NA  NA

Informasi penting dalam data :

wellName : Nama sumur sebagai data tiap sumuran

MW.In : Rate lumpur masuk kedalam lubang bor

Pump.time : waktu pemompaan lumpur kedalam lubang bor

ROP : Rate of Penetration (akan digunakan sebagai target value)

RotatingHrs : besaran Waktu putaran BHA per jam

SPP : Surface Pump Pressure

FlowRate : Laju alir fluida lumpur

TVD : True Vertical Depth, kedalaman vertikal sumur

WOB : Weight on Bit, pembacaan berat assembly di mata bor atau Bit

Data Wrangling

Sesuaikan tipe data pada dataset drilling:

Note: Untuk DrillingHrs dibuatkan kategori terhadap nilai nya dengan referensi sebagai berikut: - DrillHrs_OPT = diluar dari data range 8 - 18, artinya kegiatan pemboran tersebut tidak terjadi optimasi atau “Not optimize”. - DrillHrs_REAL = diluar dari data range 0 - 40, artinya kegiatan pemboran tersebut tidak terjadi optimasi atau “Not optimize”.

EDA

drilling_clean <- drilling %>%
                select(-c("Torque.max." , "Torque_2" , wellName, MW.Out , datasetName))

drilling_cleanROP <- subset(drilling_clean, drilling_clean$ROP > (quantile(drilling_clean$ROP, .25) - 1.5*IQR(drilling_clean$ROP)) & drilling_clean$ROP < (quantile(drilling_clean$ROP, .75) + 1.5*IQR(drilling_clean$ROP))) %>%
                na.omit(drilling_clean)

drilling_cleanROP$DrillHrs_OPT <- factor(ifelse(drilling_cleanROP$DrillHrs < 8 | drilling_cleanROP$DrillHrs > 18, "Not optimize","optimize"))
drilling_cleanROP$DrillHrs_REAL <- factor(ifelse(drilling_cleanROP$DrillHrs < 0 | drilling_cleanROP$DrillHrs > 40, "Not optimize","optimize"))
head(drilling_cleanROP)
##      Depth Bitm BitRevs DrillHrs Dxc FlowRate        MSE MSE_DAVG MW.In
## 9179 403.0 0.00      46     0.14   0   225.27      0.000 -9999.00  1.10
## 9180 403.5 0.52      57     0.14   0   223.79 169113.177 -9999.00  1.09
## 9181 404.0 1.00      68     0.15   0   222.28  20820.246 -9999.00  1.08
## 9182 404.5 1.50      78     0.15   0   220.32   5061.134 -9999.00  1.08
## 9183 405.0 2.01      88     0.15   0   220.17   4720.052     2.71  1.09
## 9184 405.5 2.51      98     0.16   0   220.17   4674.229    40.49  1.09
##          POWER Pump.time     PVT    ROP RotatingHrs RPM RPM.SURF   SPP Temp.In
## 9179  0.000000      0.17 2141.88   3.55        0.59  43        4 25.13    32.4
## 9180  8.187181      0.18 2168.51   3.55        0.60  43       43 27.15    32.4
## 9181 16.374362      0.18 2138.48  57.67        0.60  43       43 28.11    32.4
## 9182  8.187181      0.18 2120.94 118.62        0.61  43       43 27.55    32.4
## 9183  8.229550      0.19 2129.53 127.85        0.61  43       43 27.57    32.4
## 9184  8.294993      0.19 2128.11 130.13        0.61  43       43 26.62    32.4
##      Temp.Out TORQUE   TVD WOB DrillHrs_OPT DrillHrs_REAL
## 9179     26.4      0 403.0 0.0 Not optimize      optimize
## 9180     26.5      1 403.5 0.0 Not optimize      optimize
## 9181     26.5      2 404.0 0.0 Not optimize      optimize
## 9182     26.5      1 404.5 0.0 Not optimize      optimize
## 9183     26.5      1 405.0 0.2 Not optimize      optimize
## 9184     26.5      1 405.5 0.5 Not optimize      optimize
drilling_cleanROP <- drilling_cleanROP %>%
                    mutate(DrillHrs_OPT =  as.factor(DrillHrs_OPT),
                            DrillHrs_REAL = as.factor(DrillHrs_REAL) )

glimpse(drilling_cleanROP)
## Rows: 41,710
## Columns: 24
## $ Depth         <dbl> 403.0, 403.5, 404.0, 404.5, 405.0, 405.5, 406.0, 406.5, …
## $ Bitm          <dbl> 0.00, 0.52, 1.00, 1.50, 2.01, 2.51, 3.02, 3.51, 4.03, 4.…
## $ BitRevs       <int> 46, 57, 68, 78, 88, 98, 108, 118, 130, 143, 200, 209, 21…
## $ DrillHrs      <dbl> 0.14, 0.14, 0.15, 0.15, 0.15, 0.16, 0.16, 0.17, 0.17, 0.…
## $ Dxc           <int> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,…
## $ FlowRate      <dbl> 225.27, 223.79, 222.28, 220.32, 220.17, 220.17, 221.83, …
## $ MSE           <dbl> 0.000, 169113.177, 20820.246, 5061.134, 4720.052, 4674.2…
## $ MSE_DAVG      <dbl> -9999.00, -9999.00, -9999.00, -9999.00, 2.71, 40.49, 40.…
## $ MW.In         <dbl> 1.10, 1.09, 1.08, 1.08, 1.09, 1.09, 1.09, 1.10, 1.08, 1.…
## $ POWER         <dbl> 0.000000, 8.187181, 16.374362, 8.187181, 8.229550, 8.294…
## $ Pump.time     <dbl> 0.17, 0.18, 0.18, 0.18, 0.19, 0.19, 0.20, 0.20, 0.20, 0.…
## $ PVT           <dbl> 2141.88, 2168.51, 2138.48, 2120.94, 2129.53, 2128.11, 21…
## $ ROP           <dbl> 3.55, 3.55, 57.67, 118.62, 127.85, 130.13, 130.57, 127.1…
## $ RotatingHrs   <dbl> 0.59, 0.60, 0.60, 0.61, 0.61, 0.61, 0.62, 0.62, 0.63, 0.…
## $ RPM           <dbl> 43, 43, 43, 43, 43, 43, 43, 43, 43, 42, 43, 42, 42, 42, …
## $ RPM.SURF      <dbl> 4, 43, 43, 43, 43, 43, 43, 43, 43, 42, 43, 42, 42, 42, 4…
## $ SPP           <dbl> 25.13, 27.15, 28.11, 27.55, 27.57, 26.62, 26.90, 29.21, …
## $ Temp.In       <dbl> 32.4, 32.4, 32.4, 32.4, 32.4, 32.4, 32.4, 32.4, 32.4, 32…
## $ Temp.Out      <dbl> 26.4, 26.5, 26.5, 26.5, 26.5, 26.5, 26.5, 26.4, 26.5, 26…
## $ TORQUE        <int> 0, 1, 2, 1, 1, 1, 1, 1, 1, 2, 1, 3, 3, 4, 3, 4, 2, 3, 2,…
## $ TVD           <dbl> 403.0, 403.5, 404.0, 404.5, 405.0, 405.5, 406.0, 406.5, …
## $ WOB           <dbl> 0.0, 0.0, 0.0, 0.0, 0.2, 0.5, 0.3, 0.3, 1.3, 0.8, 1.3, 3…
## $ DrillHrs_OPT  <fct> Not optimize, Not optimize, Not optimize, Not optimize, …
## $ DrillHrs_REAL <fct> optimize, optimize, optimize, optimize, optimize, optimi…

Cross-Validation

Split data drilling_cleanROP menjadi drilling_cleanROP_train dan drilling_cleanROP_test dengan proporsi 80:20

set.seed(100)

index <- sample(nrow(drilling_cleanROP), nrow(drilling_cleanROP) * 0.8)
drilling_cleanROP_train <- drilling_cleanROP[index,]
drilling_cleanROP_test <- drilling_cleanROP[-index,]

looking Correlation each variable

library(GGally)
## Registered S3 method overwritten by 'GGally':
##   method from   
##   +.gg   ggplot2
ggcorr(drilling_cleanROP, label = TRUE, label_size = 2.9, hjust = 1, layout.exp = 2)
## Warning in ggcorr(drilling_cleanROP, label = TRUE, label_size = 2.9, hjust =
## 1, : data in column(s) 'DrillHrs_OPT', 'DrillHrs_REAL' are not numeric and were
## ignored

# SUMMARY DATA

summary(drilling_cleanROP)
##      Depth           Bitm           BitRevs          DrillHrs    
##  Min.   : 401   Min.   :   0.0   Min.   :     0   Min.   : 0.00  
##  1st Qu.:1546   1st Qu.: 263.7   1st Qu.: 27307   1st Qu.: 5.20  
##  Median :2414   Median : 594.9   Median : 88621   Median :15.24  
##  Mean   :2407   Mean   : 653.9   Mean   :112318   Mean   :17.88  
##  3rd Qu.:3284   3rd Qu.: 973.6   3rd Qu.:155007   3rd Qu.:26.42  
##  Max.   :4560   Max.   :1917.5   Max.   :553482   Max.   :78.89  
##       Dxc               FlowRate           MSE              MSE_DAVG        
##  Min.   :-9999.000   Min.   :   0.0   Min.   :   -9999   Min.   :  -9999.0  
##  1st Qu.:    1.000   1st Qu.: 491.8   1st Qu.:    3853   1st Qu.:    144.6  
##  Median :    1.000   Median : 738.4   Median :  211506   Median :  25803.3  
##  Mean   :   -0.237   Mean   : 750.3   Mean   :  251755   Mean   :  33609.6  
##  3rd Qu.:    1.000   3rd Qu.:1018.6   3rd Qu.:  346296   3rd Qu.:  50941.9  
##  Max.   :    2.000   Max.   :1523.1   Max.   :14300000   Max.   :1754382.0  
##      MW.In           POWER           Pump.time            PVT       
##  Min.   :0.784   Min.   :  0.000   Min.   :   0.00   Min.   :-9999  
##  1st Qu.:1.120   1st Qu.:  5.837   1st Qu.:  13.17   1st Qu.: 1142  
##  Median :1.126   Median :144.388   Median :  29.80   Median : 2002  
##  Mean   :1.146   Mean   :148.253   Mean   : 365.55   Mean   : 1634  
##  3rd Qu.:1.215   3rd Qu.:252.224   3rd Qu.:  58.80   3rd Qu.: 2340  
##  Max.   :1.725   Max.   :699.067   Max.   :2780.34   Max.   : 2850  
##       ROP          RotatingHrs          RPM           RPM.SURF   
##  Min.   :  0.91   Min.   :  0.00   Min.   :  0.0   Min.   :   0  
##  1st Qu.: 38.08   1st Qu.: 24.77   1st Qu.: 83.0   1st Qu.:  79  
##  Median : 53.80   Median : 42.81   Median :109.0   Median :  94  
##  Mean   : 57.18   Mean   : 57.83   Mean   :103.2   Mean   : 479  
##  3rd Qu.: 71.92   3rd Qu.: 77.16   3rd Qu.:120.0   3rd Qu.: 122  
##  Max.   :145.58   Max.   :377.00   Max.   :204.0   Max.   :3292  
##       SPP             Temp.In         Temp.Out            TORQUE     
##  Min.   :  25.13   Min.   :21.60   Min.   :-9999.00   Min.   : 0.00  
##  1st Qu.:1018.50   1st Qu.:29.50   1st Qu.:   28.80   1st Qu.: 7.00  
##  Median :1436.75   Median :31.60   Median :   31.90   Median :12.00  
##  Mean   :1578.44   Mean   :32.57   Mean   :   30.43   Mean   :13.02  
##  3rd Qu.:2451.19   3rd Qu.:35.90   3rd Qu.:   38.10   3rd Qu.:19.00  
##  Max.   :4110.98   Max.   :51.10   Max.   :   49.40   Max.   :37.00  
##       TVD              WOB              DrillHrs_OPT        DrillHrs_REAL  
##  Min.   : 402.5   Min.   : 0.00   Not optimize:32178   Not optimize: 3409  
##  1st Qu.:1228.6   1st Qu.: 7.40   optimize    : 9532   optimize    :38301  
##  Median :1269.0   Median :11.40                                            
##  Mean   :1185.2   Mean   :13.97                                            
##  3rd Qu.:1273.6   3rd Qu.:17.50                                            
##  Max.   :1283.5   Max.   :99.80

Cek proporsi kelas di data training:

prop.table(table(drilling_cleanROP_train$DrillHrs_OPT))
## 
## Not optimize     optimize 
##      0.76927      0.23073

Dari data diatas, perbandingan data diatas drilling_cleanROP_train secara proposional 77 : 23. maka perlu dilakukan upsampling / downsampling. kali ini akan menggunakan metode downsampling

# downsampling
RNGkind(sample.kind = "Rounding")
## Warning in RNGkind(sample.kind = "Rounding"): non-uniform 'Rounding' sampler
## used
set.seed(100)

library(caret)
drilling_cleanROP_train <- downSample(x = drilling_cleanROP_train %>% select(-DrillHrs_OPT), # prediktor saja
                         y = drilling_cleanROP_train$DrillHrs_OPT, # target saja
                         yname = "DrillHrs_OPT") # rename kolom

head(drilling_cleanROP_train)
##    Depth    Bitm BitRevs DrillHrs Dxc FlowRate         MSE  MSE_DAVG MW.In
## 1 2392.5  220.36   27227     6.82   1   468.51 509149.1713 39833.860 1.134
## 2  460.0   51.78    2985     0.95   1   884.45  16773.0022   499.830 1.085
## 3 3950.0 1027.22  233766    32.33   1   487.77 187027.0000     0.947 1.141
## 4 2895.5 1340.20  386243    41.57   1   761.45  85494.3600     1.189 1.225
## 5  546.0   81.06    1156     0.98   1   854.48    996.3343  -250.600 1.109
## 6 3043.0  870.75   98644    21.02   1   497.61 403606.7910 62924.350 1.143
##        POWER Pump.time     PVT    ROP RotatingHrs RPM RPM.SURF     SPP Temp.In
## 1 194.207546     11.03  835.69  27.97       35.53  85    85.00  972.48    29.9
## 2   5.553772      2.62 2260.03  24.28       20.82  29    29.00 1059.25    34.1
## 3  61.790000   1113.57   38.49  69.09      119.00 119  1872.78   28.80    31.5
## 4  79.690000   1566.25   26.60 123.33      181.00 181  1787.60   35.90    42.4
## 5   1.698279      1.95 2711.23 124.99       14.52  94     0.00  965.62    31.7
## 6 316.101015     28.80 1722.27  57.43       54.71  92    91.00 1218.54    30.6
##   Temp.Out TORQUE     TVD WOB DrillHrs_REAL DrillHrs_OPT
## 1     36.6     12 1272.69 0.0      optimize Not optimize
## 2     29.8      1  459.99 0.8      optimize Not optimize
## 3     30.0     30 1277.20 7.0      optimize Not optimize
## 4     13.0     13 1271.99 0.7  Not optimize Not optimize
## 5     21.6      0  545.96 8.2      optimize Not optimize
## 6     35.6     18 1269.11 8.4      optimize Not optimize
prop.table(table(drilling_cleanROP_train$DrillHrs_OPT))
## 
## Not optimize     optimize 
##          0.5          0.5
table(drilling_cleanROP_train$DrillHrs_OPT)
## 
## Not optimize     optimize 
##         7699         7699

Model Fitting

library(partykit)
## Loading required package: grid
## Loading required package: libcoin
## Loading required package: mvtnorm
drilling_tree <- ctree(formula = DrillHrs_OPT ~ .,
                       data = drilling_cleanROP_train)
# visualisasi decision tree
plot(drilling_tree)

Model Evaluation

Mari evaluasi drilling_tree menggunakan confusion matrix berdasarkan hasil prediksi di data test:

Parameter type:

  • type = "prob" mengembalikan nilai peluang untuk masing-masing kelas
  • type = "response" mengembalikan label kelasnya (default threshold 0.5)
# prediksi kelas di data test
pred_drilling_test <- predict(object = drilling_tree, 
                          newdata = drilling_cleanROP_test,
                          type = "response")

head(pred_drilling_test)
##         9181         9185         9187         9190         9196         9218 
## Not optimize Not optimize Not optimize Not optimize Not optimize Not optimize 
## Levels: Not optimize optimize
# confusion matrix data test
confusionMatrix(data = pred_drilling_test,
                reference = drilling_cleanROP_test$DrillHrs_REAL,
                positive = "optimize")
## Confusion Matrix and Statistics
## 
##               Reference
## Prediction     Not optimize optimize
##   Not optimize          658     5849
##   optimize                0     1835
##                                          
##                Accuracy : 0.2988         
##                  95% CI : (0.289, 0.3088)
##     No Information Rate : 0.9211         
##     P-Value [Acc > NIR] : 1              
##                                          
##                   Kappa : 0.0472         
##                                          
##  Mcnemar's Test P-Value : <2e-16         
##                                          
##             Sensitivity : 0.2388         
##             Specificity : 1.0000         
##          Pos Pred Value : 1.0000         
##          Neg Pred Value : 0.1011         
##              Prevalence : 0.9211         
##          Detection Rate : 0.2200         
##    Detection Prevalence : 0.2200         
##       Balanced Accuracy : 0.6194         
##                                          
##        'Positive' Class : optimize       
## 

Mode model diatas adalah Precision = 1.0 dengan tingkat Specificity = 1.0

Selain melihat confusion matrix untuk data test saja, ada baiknya kita juga bandingkan dengan performance model di data train (drilling_cleanROP_train) untuk mengetahui fitting dari sebuah model:

# prediksi kelas di data train
pred_drill_train <- predict(object = drilling_tree, 
                          newdata = drilling_cleanROP_train,
                          type = "response")

# confusion matrix data train
confusionMatrix(data = pred_drill_train,
                reference = drilling_cleanROP_train$DrillHrs_OPT,
                positive = "optimize")
## Confusion Matrix and Statistics
## 
##               Reference
## Prediction     Not optimize optimize
##   Not optimize         7699        0
##   optimize                0     7699
##                                      
##                Accuracy : 1          
##                  95% CI : (0.9998, 1)
##     No Information Rate : 0.5        
##     P-Value [Acc > NIR] : < 2.2e-16  
##                                      
##                   Kappa : 1          
##                                      
##  Mcnemar's Test P-Value : NA         
##                                      
##             Sensitivity : 1.0        
##             Specificity : 1.0        
##          Pos Pred Value : 1.0        
##          Neg Pred Value : 1.0        
##              Prevalence : 0.5        
##          Detection Rate : 0.5        
##    Detection Prevalence : 0.5        
##       Balanced Accuracy : 1.0        
##                                      
##        'Positive' Class : optimize   
## 
  • Recall di data train: 0.5286
  • Recall di data test: 0.2386

Ketika dibandingkan, performa model drilling_tree cenderung lebih baik pada data train dibandingkan data test. Model ini dikatakan sebagai model yang overfitting. Karena performa model belum cukup baik, perlu dilakukan model tuning.

MODEIL TUNING

drilling_tree_tuned <- ctree(formula = DrillHrs_OPT ~ .,
                             data = drilling_cleanROP_train,
                             control = ctree_control(mincriterion = 0.1,
                                                     minsplit = 70,
                                                     minbucket = 50)) # harus coba coba

plot(drilling_tree_tuned, type = "simple")

Kemudian kita coba re-evaluasi untuk model yang sudah dilakukan tuning, simpan pada objek pred_diab_train_tuned dan pred_diab_test_tuned:

# prediksi kelas di data test
pred_drill_test_tuned <- predict(object = drilling_tree_tuned, 
                          newdata = drilling_cleanROP_test,
                          type = "response")

# confusion matrix data test
confusionMatrix(data = pred_drill_test_tuned,
                reference = drilling_cleanROP_test$DrillHrs_OPT,
                positive = "optimize")
## Confusion Matrix and Statistics
## 
##               Reference
## Prediction     Not optimize optimize
##   Not optimize         6507        0
##   optimize                2     1833
##                                      
##                Accuracy : 0.9998     
##                  95% CI : (0.9991, 1)
##     No Information Rate : 0.7803     
##     P-Value [Acc > NIR] : <2e-16     
##                                      
##                   Kappa : 0.9993     
##                                      
##  Mcnemar's Test P-Value : 0.4795     
##                                      
##             Sensitivity : 1.0000     
##             Specificity : 0.9997     
##          Pos Pred Value : 0.9989     
##          Neg Pred Value : 1.0000     
##              Prevalence : 0.2197     
##          Detection Rate : 0.2197     
##    Detection Prevalence : 0.2200     
##       Balanced Accuracy : 0.9998     
##                                      
##        'Positive' Class : optimize   
## 
# prediksi kelas di data train
pred_drill_train_tuned <- predict(object = drilling_tree_tuned, 
                          newdata = drilling_cleanROP_train,
                          type = "response")

# confusion matrix data train
confusionMatrix(data = pred_drill_train_tuned,
                reference = drilling_cleanROP_train$DrillHrs_OPT,
                positive = "optimize")
## Confusion Matrix and Statistics
## 
##               Reference
## Prediction     Not optimize optimize
##   Not optimize         7699        0
##   optimize                0     7699
##                                      
##                Accuracy : 1          
##                  95% CI : (0.9998, 1)
##     No Information Rate : 0.5        
##     P-Value [Acc > NIR] : < 2.2e-16  
##                                      
##                   Kappa : 1          
##                                      
##  Mcnemar's Test P-Value : NA         
##                                      
##             Sensitivity : 1.0        
##             Specificity : 1.0        
##          Pos Pred Value : 1.0        
##          Neg Pred Value : 1.0        
##              Prevalence : 0.5        
##          Detection Rate : 0.5        
##    Detection Prevalence : 0.5        
##       Balanced Accuracy : 1.0        
##                                      
##        'Positive' Class : optimize   
## 

Modeling: Naive Bayes

library(e1071)
## 
## Attaching package: 'e1071'
## The following object is masked from 'package:gtools':
## 
##     permutations
# model building
naive_model_drill <- naiveBayes(x = drilling_cleanROP %>% select(-DrillHrs_OPT), # kolom-kolom prediktor
                          y = drilling_cleanROP$DrillHrs_OPT) # kolom target variable
                        
naive_model_drill
## 
## Naive Bayes Classifier for Discrete Predictors
## 
## Call:
## naiveBayes.default(x = drilling_cleanROP %>% select(-DrillHrs_OPT), 
##     y = drilling_cleanROP$DrillHrs_OPT)
## 
## A-priori probabilities:
## drilling_cleanROP$DrillHrs_OPT
## Not optimize     optimize 
##    0.7714697    0.2285303 
## 
## Conditional probabilities:
##                               Depth
## drilling_cleanROP$DrillHrs_OPT     [,1]     [,2]
##                   Not optimize 2411.290 1139.303
##                   optimize     2394.385  738.187
## 
##                               Bitm
## drilling_cleanROP$DrillHrs_OPT     [,1]     [,2]
##                   Not optimize 701.4987 509.3482
##                   optimize     493.2728 155.8348
## 
##                               BitRevs
## drilling_cleanROP$DrillHrs_OPT      [,1]      [,2]
##                   Not optimize 121349.91 120753.98
##                   optimize      81829.82  34504.51
## 
##                               DrillHrs
## drilling_cleanROP$DrillHrs_OPT     [,1]      [,2]
##                   Not optimize 19.30764 16.933246
##                   optimize     13.06979  3.037243
## 
##                               Dxc
## drilling_cleanROP$DrillHrs_OPT       [,1]        [,2]
##                   Not optimize -0.6040152 124.6456362
##                   optimize      1.0008393   0.1149753
## 
##                               FlowRate
## drilling_cleanROP$DrillHrs_OPT     [,1]     [,2]
##                   Not optimize 756.5987 269.7881
##                   optimize     728.8515 281.8522
## 
##                               MSE
## drilling_cleanROP$DrillHrs_OPT     [,1]     [,2]
##                   Not optimize 245544.2 391136.3
##                   optimize     272719.7 232605.4
## 
##                               MSE_DAVG
## drilling_cleanROP$DrillHrs_OPT     [,1]     [,2]
##                   Not optimize 33442.67 42393.94
##                   optimize     34173.13 44815.20
## 
##                               MW.In
## drilling_cleanROP$DrillHrs_OPT     [,1]       [,2]
##                   Not optimize 1.141113 0.07766791
##                   optimize     1.162814 0.04868777
## 
##                               POWER
## drilling_cleanROP$DrillHrs_OPT     [,1]     [,2]
##                   Not optimize 140.9270 142.4453
##                   optimize     172.9838 109.1777
## 
##                               Pump.time
## drilling_cleanROP$DrillHrs_OPT     [,1]     [,2]
##                   Not optimize 411.0113 773.4554
##                   optimize     212.0737 487.6857
## 
##                               PVT
## drilling_cleanROP$DrillHrs_OPT     [,1]     [,2]
##                   Not optimize 1609.675 906.1327
##                   optimize     1717.386 848.8078
## 
##                               ROP
## drilling_cleanROP$DrillHrs_OPT     [,1]     [,2]
##                   Not optimize 58.18309 31.38107
##                   optimize     53.78605 19.28418
## 
##                               RotatingHrs
## drilling_cleanROP$DrillHrs_OPT     [,1]     [,2]
##                   Not optimize 61.19909 48.10772
##                   optimize     46.45435 35.40054
## 
##                               RPM
## drilling_cleanROP$DrillHrs_OPT     [,1]     [,2]
##                   Not optimize 103.1057 32.17409
##                   optimize     103.4440 22.38686
## 
##                               RPM.SURF
## drilling_cleanROP$DrillHrs_OPT     [,1]     [,2]
##                   Not optimize 516.3788 856.8983
##                   optimize     352.6196 641.1022
## 
##                               SPP
## drilling_cleanROP$DrillHrs_OPT     [,1]      [,2]
##                   Not optimize 1569.885 1114.7980
##                   optimize     1607.329  911.0225
## 
##                               Temp.In
## drilling_cleanROP$DrillHrs_OPT     [,1]     [,2]
##                   Not optimize 32.80424 5.307552
##                   optimize     31.79501 4.397011
## 
##                               Temp.Out
## drilling_cleanROP$DrillHrs_OPT     [,1]      [,2]
##                   Not optimize 29.99337 56.925976
##                   optimize     31.90153  8.443198
## 
##                               TORQUE
## drilling_cleanROP$DrillHrs_OPT     [,1]     [,2]
##                   Not optimize 13.04419 8.799693
##                   optimize     12.95573 6.426467
## 
##                               TVD
## drilling_cleanROP$DrillHrs_OPT     [,1]      [,2]
##                   Not optimize 1164.518 217.93496
##                   optimize     1254.808  32.91672
## 
##                               WOB
## drilling_cleanROP$DrillHrs_OPT     [,1]     [,2]
##                   Not optimize 13.48905 11.99353
##                   optimize     15.57411 10.22645
## 
##                               DrillHrs_REAL
## drilling_cleanROP$DrillHrs_OPT Not optimize  optimize
##                   Not optimize    0.1059419 0.8940581
##                   optimize        0.0000000 1.0000000