Pendahuluan

Latar Belakang

Air adalah komponen esensial dalam kehidupan manusia, dengan peran utama sebagai sumber kehidupan dan kesejahteraan. Air digunakan dalam berbagai konteks, termasuk untuk minum, memasak, mandi, irigasi, dan banyak aplikasi industri.

Kualitas air minum adalah aspek penting dalam menjaga kesehatan masyarakat, karena air yang tidak layak konsumsi dapat mengakibatkan berbagai masalah kesehatan, termasuk penyakit yang serius. Untuk menilai kelayakan air minum (potability) terdapat beberapa parameter seperti pH, kekerasan (hardness), kandungan padatan terlarut (solids), konsentrasi kloramin, kadar sulfate, konduktivitas, kandungan karbon organik, trihalometana, dan tingkat kekeruhan (turbidity).

Tujuan dari analisis ini adalah dengan mengetahui kelayakan air minum dapat mencegah terjadinya penyebaran penyakit, dan menjaga keberlanjutan sumber daya air. Parameter-parameter tersebut dapat digunakan dalam pengembangan model klasifikasi kelayakan air minum, yang membantu mengidentifikasi apakah sampel air di suatu wilayah layak untuk konsumsi manusia atau tidak.

Tentang Data

Dataset ini diperoleh melalui kaggle Water Quality and Potability yang diposting oleh LAKSIKA THARMALINGAM. Dataset ini berisi data pengukuran kualitas air yang berkaitan dengan potabilitas, yaitu kesesuaian air untuk konsumsi manusia dengan informasi kolom sebagai berikut:

Kolom Deskripsi
pH : Tingkat pH air.
Hardness : Kesadahan air, ukuran kandungan mineral.
Solids : Total padatan terlarut dalam air.
Chloramines : Konsentrasi kloramin di dalam air.
Sulfate : Konsentrasi sulfat di dalam air.
Conductivity : Daya hantar listrik air.
Organic_carbon : Kandungan karbon organik di dalam air.
Trihalomethanes : Konsentrasi trihalometana di dalam air.
Turbidity : Tingkat kekeruhan, ukuran kejernihan air.
Potability : Menunjukkan potensi air dengan nilai 1 (dapat diminum) dan 0 (tidak dapat diminum).

Berdasarkan informasi diatas, akan digunakan kolom Potability sebagai target variabel dan selain kolom potability akan dijadikan variabel prediktor.


Persiapan Analisis

Load Packages

Pada artikel ini akan dilakukan pemodelan klasifikasi menggunakan bahasa pemrograman R, berikut adalah beberapa packages yang akan digunakan dalam pemodelan kali ini.

#Package untuk pemrosesan dataframe dan EDA
library(dplyr) 
library(tidyr)
library(corrplot)
library(class)

#Package untuk pengujian asumsi VIF regresi logistik
library(car)

#Package untuk melakukan evaluasi model
library(caret)

#Package untuk melakukan visualisasi
library(ggplot2)
library(plotly)
library(glue)

Data Preparation

Sebelum dilakukan analisis data lebih lanjut, perlu dilakukan persiapan data seperti:

  1. read data set
  2. pemeriksaan kesesuaian dan penyesuaian tipe data
  3. pemeriksaan dan penanganan missing value
#Read data
wapo <- read.csv("data/water_potability.csv")
head(wapo)
ph Hardness Solids Chloramines Sulfate Conductivity Organic_carbon Trihalomethanes Turbidity Potability
NA 204.8905 20791.32 7.300212 368.5164 564.3087 10.379783 86.99097 2.963135 0
3.716080 129.4229 18630.06 6.635246 NA 592.8854 15.180013 56.32908 4.500656 0
8.099124 224.2363 19909.54 9.275884 NA 418.6062 16.868637 66.42009 3.055934 0
8.316766 214.3734 22018.42 8.059332 356.8861 363.2665 18.436525 100.34167 4.628770 0
9.092223 181.1015 17978.99 6.546600 310.1357 398.4108 11.558279 31.99799 4.075075 0
5.584087 188.3133 28748.69 7.544869 326.6784 280.4679 8.399735 54.91786 2.559708 0

Pemeriksaan & Penyesuaian Tipe Data

glimpse(wapo)
#> Rows: 3,276
#> Columns: 10
#> $ ph              <dbl> NA, 3.716080, 8.099124, 8.316766, 9.092223, 5.584087, …
#> $ Hardness        <dbl> 204.8905, 129.4229, 224.2363, 214.3734, 181.1015, 188.…
#> $ Solids          <dbl> 20791.32, 18630.06, 19909.54, 22018.42, 17978.99, 2874…
#> $ Chloramines     <dbl> 7.300212, 6.635246, 9.275884, 8.059332, 6.546600, 7.54…
#> $ Sulfate         <dbl> 368.5164, NA, NA, 356.8861, 310.1357, 326.6784, 393.66…
#> $ Conductivity    <dbl> 564.3087, 592.8854, 418.6062, 363.2665, 398.4108, 280.…
#> $ Organic_carbon  <dbl> 10.379783, 15.180013, 16.868637, 18.436524, 11.558279,…
#> $ Trihalomethanes <dbl> 86.99097, 56.32908, 66.42009, 100.34167, 31.99799, 54.…
#> $ Turbidity       <dbl> 2.963135, 4.500656, 3.055934, 4.628771, 4.075075, 2.55…
#> $ Potability      <int> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, …

Berdasarkan penyesuaian tipe data diatas, terdapat informasi bahwa:

  • data water potability ini terdapat sebanyak 3276 data
  • memiliki 10 kolom variabel pengukuran kualitas air
  • untuk kolom Potability perlu dilakukan penyesuaian menjadi tipe kategorik / factor
  • dari pemerisaan menunjukkan kolom ph dan sulfate terdapat nilai yang hilang (NA) sehingga akan coba kita periksa berapa banyak nilai yang hilang dari kolom tersebut.

Pengubahan tipe Data

wapo <- wapo %>% mutate(Potability = as.factor(Potability))

Cek Missing Value

colSums(is.na(wapo))
#>              ph        Hardness          Solids     Chloramines         Sulfate 
#>             491               0               0               0             781 
#>    Conductivity  Organic_carbon Trihalomethanes       Turbidity      Potability 
#>               0               0             162               0               0

Berdasarkan pemeriksaan nilai yang hilang (NA) diatas. dapat kita ketahui bahwa:

  • terdapat nilai yang hilang pada kolom ph sebanyak 491 data.
  • terdapat nilai yang hilang pada kolom Sulfate sebanyak 781 data.
  • terdapat nilai yang hilang pada kolom Trihalomethanes sebanyak 162 data.

dikarenakan keseluruhan kolom ini penting dan harus ada pada penentuan kualitas kelayakan air minum, maka tindakan yang akan dilakukan untuk penanganan nilai yang hilang ini adalah tidak menyertakan data yang tidak lengkap.

#drop data tidak lengkap
wapo <- drop_na(wapo)

#menghitung kembali jumlah data
nrow(wapo)
#> [1] 2011

setelah dilakukan drop data yang tidak lengkap, jumlah data tereduksi sebanyak 1265 data (38.61%) dan tersisa sebanyak 2011 data (61.39%)


Exploratory Data Analysis

Ringkasan Data

summary(wapo)
#>        ph             Hardness          Solids         Chloramines    
#>  Min.   : 0.2275   Min.   : 73.49   Min.   :  320.9   Min.   : 1.391  
#>  1st Qu.: 6.0897   1st Qu.:176.74   1st Qu.:15615.7   1st Qu.: 6.139  
#>  Median : 7.0273   Median :197.19   Median :20933.5   Median : 7.144  
#>  Mean   : 7.0860   Mean   :195.97   Mean   :21917.4   Mean   : 7.134  
#>  3rd Qu.: 8.0530   3rd Qu.:216.44   3rd Qu.:27182.6   3rd Qu.: 8.110  
#>  Max.   :14.0000   Max.   :317.34   Max.   :56488.7   Max.   :13.127  
#>     Sulfate       Conductivity   Organic_carbon  Trihalomethanes  
#>  Min.   :129.0   Min.   :201.6   Min.   : 2.20   Min.   :  8.577  
#>  1st Qu.:307.6   1st Qu.:366.7   1st Qu.:12.12   1st Qu.: 55.953  
#>  Median :332.2   Median :423.5   Median :14.32   Median : 66.542  
#>  Mean   :333.2   Mean   :426.5   Mean   :14.36   Mean   : 66.401  
#>  3rd Qu.:359.3   3rd Qu.:482.4   3rd Qu.:16.68   3rd Qu.: 77.292  
#>  Max.   :481.0   Max.   :753.3   Max.   :27.01   Max.   :124.000  
#>    Turbidity     Potability
#>  Min.   :1.450   0:1200    
#>  1st Qu.:3.443   1: 811    
#>  Median :3.968             
#>  Mean   :3.970             
#>  3rd Qu.:4.514             
#>  Max.   :6.495

Berdasarkan summary diatas dapat kita ketahui bahwa skala nilai untuk setiap variabel prediktor tidak seragam, dimana: - untuk variabel pH, Chloramines, Organic_carbon, dan Turbidity memiliki rentang nilai satuan hingga belasan - untuk variabel Trihalomethanes memiliki rentang puluhan - untuk variabel Hardness, Sulfate, Conductivity memiliki rentang nilai ratusan - dan untuk variabel Solids memiliki rentang nilai puluhan ribu.

kondisi tersebut bisa menjadi salah satu indikasi akan adanya kecenderungan pengaruh dari salah satu variabel prediktor terhadap variabel target apabila tidak dilakukan penyetaraan skala nilai.

Korelasi

Korelasi dapatsebagai salah satu pemeriksaan adanya multikolinieritas antara variabel prediktor dapat kita gunakan

corrplot(cor(wapo %>% mutate(Potability = as.integer(Potability))),        # Correlation matrix
         method = "shade", # Correlation plot method
         type = "full",    # Correlation plot style (also "upper" and "lower")
         diag = T,      # If TRUE (default), adds the diagonal
         tl.col = "black", # Labels color
         bg = "white",     # Background color
         title = ""       # Main title
         )

Berdasarkan hasil pemeriksaan korelasi di atas dapat kita ketahui bahwa:

  • antara variabel target (potability) dengan variabel prediktor tidak didapati adanya korelasi yang kuat, hal ini ditunjukkan pada hasil visualisasi shade diatas yang cenderung cerah (mendekati nilai 0 pada skala warna)
  • antara variabel prediktor tidak terdapat korelasi yang kuat, ditunjukkan pada hasil visualisasi shade diatas yang cenderung cerah (mendekati nilai 0 pada skala warna),
  • untuk hasil pemeriksaan multikolinieritas yang lebih pasti akan dilakukan pada tahapan pemeriksaan asumsi model regresi logistik.

Keseimbangan Kelas target

dalam pemodelan klasifikasi diperlukan kelas target yang seimbang, agar model yang dibuat dapat mengklasifikasi dengan baik untuk setiap kelasnya.

prop.table(table(wapo$Potability))*100
#> 
#>        0        1 
#> 59.67181 40.32819

Berdasarkan pemeriksaan kelas target di atas dapat kita nyatakan proporsi kelas 0 (tidak layak minum) dan kelas 1 (layak minum) sebesar 60:40 sudah cukup seimbang.


Analisis Data

Untuk analisis data ini akan coba digunakan dua model klasifikasi, yakni regresi logistik dan KNN

Model Regresi Logistik

Cross Validation

Jika kita ingin melakukan sebuah prediksi, maka kita tidak disarankan melihat nilai error pada data yang digunakan untuk melatih model, karena itu hanya menunjukkan bahwa model dapat memprediksi data lama tetapi belum tentu dapat memprediksi data baru.

Data yang digunakan untuk melatih model kita sebut dengan data train, sedangkan data yang digunakan untuk menguji model disebut dengan data test.

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

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

# splitting
wapo_train <- wapo[index,]
wapo_test <- wapo[-index,]

Build Model

Untuk membuat model regresi logistik di R dapat kita lakukan menggunakan fungsi glm()

model_LR <- glm(Potability ~ ., data = wapo_train, family = "binomial")
summary(model_LR)
#> 
#> Call:
#> glm(formula = Potability ~ ., family = "binomial", data = wapo_train)
#> 
#> Deviance Residuals: 
#>     Min       1Q   Median       3Q      Max  
#> -1.3286  -1.0347  -0.9503   1.3063   1.6618  
#> 
#> Coefficients:
#>                     Estimate   Std. Error z value Pr(>|z|)  
#> (Intercept)     -0.528502447  0.843489771  -0.627   0.5309  
#> ph               0.050177145  0.032659504   1.536   0.1244  
#> Hardness        -0.000415146  0.001588486  -0.261   0.7938  
#> Solids           0.000013076  0.000005975   2.188   0.0286 *
#> Chloramines      0.049683043  0.032134094   1.546   0.1221  
#> Sulfate         -0.000999056  0.001267549  -0.788   0.4306  
#> Conductivity    -0.000482396  0.000632847  -0.762   0.4459  
#> Organic_carbon  -0.026370862  0.015508126  -1.700   0.0890 .
#> Trihalomethanes -0.001964225  0.003208210  -0.612   0.5404  
#> Turbidity        0.075007048  0.065657583   1.142   0.2533  
#> ---
#> Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
#> 
#> (Dispersion parameter for binomial family taken to be 1)
#> 
#>     Null deviance: 2177.3  on 1607  degrees of freedom
#> Residual deviance: 2162.0  on 1598  degrees of freedom
#> AIC: 2182
#> 
#> Number of Fisher Scoring iterations: 4

Berdasarkan output model regresi logistik diatas dapat kita ketahui bahwa:

  • Nilai p-value dari keseruluhan variabel prediktor yang digunakan terlihat bahwa hanya variabel prediktor Solids saja yang signifikan.
  • Selisih antara nilai Null deviance (2177.3) dan Residual deviance (2162) sebesar 15 yang dapat dinyatakan cukup rendah menunjukkan bahwa hampir tidak terdapat perbedaan yang signifikan antara model tanpa prediktor dengan model yang menggunakan keseluruhan prediktor

Pengujian Asumsi Model

Pada model regresi logistik terdapat satu asumsi yang hrus diperiksa, yakni mengenai multikolinieritas. diharapkan tidak terjadi korelasi yang kuat antar variabel prediktor (multikolinieritas). Untuk melakukanya dapat kita gunakan fungsi vif dari package caret.

vif(model_LR)
#>              ph        Hardness          Solids     Chloramines         Sulfate 
#>        1.030276        1.031122        1.053342        1.010306        1.054149 
#>    Conductivity  Organic_carbon Trihalomethanes       Turbidity 
#>        1.002722        1.005590        1.004388        1.004565

Berdasarkan hasil pemeriksaan diatas, kita dapati dari keseluruhan variabel prediktor tidak terdapat nilai vif yang lebih besar dari 10. maka dapat dinyatakan bahwa tidak terjadi multikolinieritas.

Interpretasi Model

Output model regresi logistik merupakan sebuah nilai log of odds, sehingga perlu diubah menjadi nilai odds atau peluang agar dapat diinterpretasikan.

# Mengubah nilai koefisien menjadi nilai odds
model_LR$coefficients %>% exp()
#>     (Intercept)              ph        Hardness          Solids     Chloramines 
#>       0.5894871       1.0514573       0.9995849       1.0000131       1.0509379 
#>         Sulfate    Conductivity  Organic_carbon Trihalomethanes       Turbidity 
#>       0.9990014       0.9995177       0.9739738       0.9980377       1.0778917

Interpretasi:

  • variabel PH: untuk setiap kenaikan 1 nilai pH maka akan meningkatan kemungkinan air Layak minum sebesar 1.0514573 kali, dengan catatan variabel prediktor lainnya bernilai sama/tetap

  • variabel Hardness: untuk setiap kenaikan 1 nilai Hardness maka akan meningkatan kemungkinan air Layak minum sebesar 0.9995849 kali, dengan catatan variabel prediktor lainnya bernilai sama/tetap

  • variabel Solids: untuk setiap kenaikan 1 nilai Solids maka akan meningkatan kemungkinan air Layak minum sebesar 1.0000131 kali, dengan catatan variabel prediktor lainnya bernilai sama/tetap

  • variabel Chloramines: untuk setiap kenaikan 1 nilai Chloramines maka akan meningkatan kemungkinan air Layak minum sebesar 1.0509379 kali, dengan catatan variabel prediktor lainnya bernilai sama/tetap

  • variabel Sulfate: untuk setiap kenaikan 1 nilai Sulfate maka akan meningkatan kemungkinan air Layak minum sebesar 0.9990014 kali, dengan catatan variabel prediktor lainnya bernilai sama/tetap

  • variabel Conductivity : untuk setiap kenaikan 1 nilai Conductivity maka akan meningkatan kemungkinan air Layak minum sebesar 0.9995177 kali, dengan catatan variabel prediktor lainnya bernilai sama/tetap

  • variabel Organic_carbon : untuk setiap kenaikan 1 nilai Organic_carbon maka akan meningkatan kemungkinan air Layak minum sebesar 0.9739738 kali, dengan catatan variabel prediktor lainnya bernilai sama/tetap

  • variabel Trihalomethanes : untuk setiap kenaikan 1 nilai Trihalomethanes maka akan meningkatan kemungkinan air Layak minum sebesar 0.9980377 kali, dengan catatan variabel prediktor lainnya bernilai sama/tetap

  • variabel Turbidity : untuk setiap kenaikan 1 nilai Turbidity maka akan meningkatan kemungkinan air Layak minum sebesar 1.0778917 kali, dengan catatan variabel prediktor lainnya bernilai sama/tetap

Predict & Model Evaluation

untuk mengetahui seberapa baik model yang sudah kita buat dalam memprediksi data baru, kita akan gunakan fungsi predict yang akan mengeluarkan hasil prediksi berupa peluang, dan fungsi ifelse untuk mengetahui kelas hasil prediksi model.

# Prediksi 
wapo_test$pred_Risk <- predict(model_LR,
                                newdata = wapo_test,
                                type = "response")

# labeling kelas target
wapo_test$pred_Label <- ifelse(test = wapo_test$pred_Risk >= 0.5, 
                                yes = 1,
                                no = 0)

sedangkan untuk melakukan evaluasinya akan digunakan confussion matrix dari package caret

CF_RL<- confusionMatrix(data = as.factor(wapo_test$pred_Label),
                reference = wapo_test$Potability,
                positive = "1")
CF_RL
#> Confusion Matrix and Statistics
#> 
#>           Reference
#> Prediction   0   1
#>          0 244 143
#>          1   8   8
#>                                              
#>                Accuracy : 0.6253             
#>                  95% CI : (0.576, 0.6727)    
#>     No Information Rate : 0.6253             
#>     P-Value [Acc > NIR] : 0.5222             
#>                                              
#>                   Kappa : 0.0259             
#>                                              
#>  Mcnemar's Test P-Value : <0.0000000000000002
#>                                              
#>             Sensitivity : 0.05298            
#>             Specificity : 0.96825            
#>          Pos Pred Value : 0.50000            
#>          Neg Pred Value : 0.63049            
#>              Prevalence : 0.37469            
#>          Detection Rate : 0.01985            
#>    Detection Prevalence : 0.03970            
#>       Balanced Accuracy : 0.51062            
#>                                              
#>        'Positive' Class : 1                  
#> 

Penentuan matriks evaluasi yang akan digunakan untuk kasus prediksi kelayakan air minum (potability)

  • Kelas positif: potable (layak minum)
  • kondisi False Negatif: diprediksi tidak potable (0) namun aktualnya potable (1)
    • Resiko : apabila kondisi ini terjadi, semakin sedikit jumlah sumber mata air yang dinyatakan layak minum
  • kondisi False Positif: diprediksi potable (1) namun aktualnya tidak potable (0)
    • Resiko : apabila kondisi ini terjadi, akan ada banyak air yang tidak layak minum berstatus layak minum dan berimbas pada kesehatan masyarakat yang mengonsumsi air minum tersebut.
  • Tujuan utama: mencegah terjadinya penyakit karena air tidak layak minum

berdasarkan informasi diatas pada kasus ini akan memfokuskan untuk meminimalisir terjadinya kondisi False Positif, sehingga akan digunakan matriks evaluasi Specificity dan **yang memfokuskan pada target kelas negatif (tidak potable).

Diperoleh nilai Specificity sebesar 0.96825 artinya, model dapat memprediksi dengan benar bahwa air tidak potable sebesar 96.83%.

Model KNN

Sebagai pembanding, disini akan kita coba membuat model prediksi dengan menggunakan metode KNN. Berbeda dengan model regresi logistik yang menghasilkan persamaan untuk memprediksi kelas target, disini KNN menentukan kelas target berdasarkan kedekatan jarak objek yang diprediksi.

Data preprocessing

Berbeda dengan regresi logistik sebelumnya, metode KNN mengharuskan kita untuk memisahkan variabel target dan variabel prediktor ke dalam sebua objek yang berbeda setelah dilakukan cross validation.

Pemisahan Target & Prediktor

# prediktor
wapo_train_x <- wapo_train %>% select(-Potability)

wapo_test_x <- wapo_test %>% select(-c(Potability,pred_Risk,pred_Label))

# target
wapo_train_y <- wapo_train[,"Potability"]

wapo_test_y <- wapo_test[,"Potability"]

Scaling

Berbeda dengan model regresi logistik yang dapat diinterpretasikan untuk setiap koefisien dari model yang terbentuk yang mengharuskan kondisi data yang digunakan adalah data dengan skala nilai asli. Metode klasifikasi KNN yang memprediksi berdasarkan kedekatan jarak objek, mengharuskan adanya kesetaraan skala nilai dari setiap variabel prediktor yang digunakan agar hasil prediksi kelas target nantinya tidak terlalu condong oleh karakteristik salah satu prediktor. Maka sebelum dilakukan prediksi dengan metode Klasifikasi KNN akan dilakukan scaling terlebih dahulu untuk menyetarakan skala nilai setiap variabel prediktor.

pada tahapan ini akan dilakukan scaling menggunakan metode z-score. Scaling ini akan dilakukan pada data train dan data test.

1. Scaling data train

Untuk melakukan scaling pada variabel prediktor data train kita dapat langsung menggunakan fungsi scale.

# train
wapo_train_xs <- scale(x = wapo_train_x)

**2. Scaling data test*

Sedangkan untuk melakukan scaling pada variabel prediktor data test kita tetap menggunakan fungsi scale, dengan tambahan parameter center(nilai mean data train) dan scale(nilai standar deviasi data train) yang diperoleh dari hasil scaling pada data train sebelumnya.

Hal ini diperlukan karena konsep scaling dengan z-score pada data test memerlukan nilai mean dan standar deviasi dari data train agar hasil prediksi bisa mengikuti pola dari kecenderungan data yang digunakan sebagai data train.

# test
wapo_test_xs <- scale(x = wapo_test_x,
                      center = attr(wapo_train_xs,"scaled:center"),
                      scale = attr(wapo_train_xs,"scaled:scale"))

Penentuan nilai K Optimum

KNN menentukan suatu objek masuk kedalam suatu kelas target berdasarkan kedekatan objek tersebut terhadap seberapa banyak objek lainnya yang disimbolkan sebagai nilai K. Untuk menentukan seberapa banyak objek terdekat yang dijadikan acuan penentuan kelas, kita dapat menggunakan aturan berikut ini:

  • hitung nilai k optimum menggunakan akar dari jumlah data kita: sqrt(nrow(data))

  • dan untuk menghindari hasil prediksi kelas yang seri ketika majority voting:

    • nilai k harus ganjil bila jumlah kelas target genap
    • nilai k harus genap bila jumlah kelas target ganjil
    • nilai k tidak boleh angka kelipatan jumlah kelas target
sqrt(nrow(wapo_train_xs))
#> [1] 40.09988

dikarenakan kelas target kita memiliki 2 kelas (potable/tidak potable) dan diperoleh akar dari jumlah data train sebesar 40.09 maka akan digunakan nilai K optimum sebesar 41 atau 39 untuk menghindari terjadinya hasil prediksi kelas target yang seri.

Predict & Model Evaluation

Pada KNN kita tidak membuat model dan langsung melakukan prediksi berdasarkan karakteristik data train yang kita miliki. Untuk melakukannya dapat kita gunakan fungsi knn dari package class.

# nilai K optimum 41
wapo_pred_41 <- knn(train = wapo_train_xs,
                 test = wapo_test_xs,
                 cl = wapo_train_y,
                 k = 41)

# nilai K optimum 39
wapo_pred_39 <- knn(train = wapo_train_xs,
                 test = wapo_test_xs,
                 cl = wapo_train_y,
                 k = 39)
# Confusion matrix K = 41
CF_41 <- confusionMatrix(data = wapo_pred_41, # merupakan hasil prediksi kelas target
                reference = wapo_test_y,      # merupakan kelas target data test
                positive = "1")

# Confusion matrix K = 39
CF_39 <- confusionMatrix(data = wapo_pred_39, # merupakan hasil prediksi kelas target
                reference = wapo_test_y,      # merupakan kelas target data test
                positive = "1")
evaluation <- data.frame(
  K_optimum = c("K = 41","K = 39"),
  rbind(CF_41$byClass,CF_39$byClass)) %>% select(c(K_optimum,Specificity))
evaluation
K_optimum Specificity
K = 41 0.9166667
K = 39 0.9206349

Sama halnya dengan model regresi logistik, disini kita akan gunakan nlai secificity karena kita akan fokus untuk memprediksi air tidak layak minum sebagai pencegahan penyakit pada masyarakat.

Berdasarkan hasil evaluasi diatas, dapat kita ketahui bahwa:

  • KNN dengan nilai K optimum sebesar 41 dan 39 sama-sama dapat memprediksi dengan benar bahwa air tidak potable lebih dari 90%.
  • KNN dengan nilai K optimum 39 lebih baik memprediksi dari KNN dengan nilai K optimum 41 dengan selisih kurang lebih sebesar 1%.

Kesimpulan & Saran

Kesimpulan

ev <- data.frame(
  metode_klasifikasi = c("Regresi Logistik","KNN(41)","KNN(39)"),
  rbind(CF_RL$byClass,CF_41$byClass,CF_39$byClass)) %>% select(c(metode_klasifikasi,Specificity))
ev
metode_klasifikasi Specificity
Regresi Logistik 0.9682540
KNN(41) 0.9166667
KNN(39) 0.9206349

Berdasarkan hasil Eksplorasi Data Analisis dan Analisis data yang telah dilakukan diatas dapat kita simpulkan bahwa:

  • Variabel Solids bisa diindikasian bisa menjadi variabel yang berpengaruh karena skala nilainya yang cenderung lebih besar dibandingkan dengan variabel prediktor lainnya. dimana variabel lainnya memiliki skala pada rentang nilai puluhan atau ratusan sedangkan variabel Solids memiliki skala pada rentang nilai puluhan ribu.
  • Tidak ditemukan nilai korelasi yang kuat antara keseluruhan variabel prediktor dengan variabel target. Hal ini dapat menjadi salah satu pertimbangan untuk mengkaji lebih lanjut terkait perlu atau tidaknya menambahkan variabel lain sebagai prediktor dari potabilitas air.
  • Proporsi antara kelas target dari data (tidak potable dan potable) sebesar 60:40 menunjukkan kondisi yang cukup seimbang untuk dilakukan pemodelan klasifikasi.
  • Selaras dengan nilai summary data dan korelasi sebelumnya, pada model regresi logistik hampir keseluruhan variabel prediktor tidak signifikan mempengaruhi potabilitas air selain variabel Solids.
  • dan dari hasil interpretasi nilai odds koefisien model regresi logistik cenderung berada pada nilai 0.9 hingga 1 yang menunjukkan hampir tidak ada perbedaan yang signifikan dari meningkat/menurunnya nilai pada variabel prediktor terhadap hasil prediksi kelas target.
  • Pengklasifikasian dengan metode KNN menunjukkan nilai optimum untuk penentuan kelas target sebesar 41 atau 39.
  • Untuk mencegah terajadinya penyakit karena konsumsi air minum yang tidak potable, digunakan matriks evaluasi specificity yang berfokus pada nilai keakuratan model dalam memprediksi kelas negatif (tidak potable).
  • Pengklasifikasian kelas target baik dengan model Regresi Logistik maupun KNN dapat memperediksi dengan akurat kelas target tidak potable lebih dari 90%.

Saran

Berdasarkan hasil simpulan diatas terdapat beberapa saran sebagai berikut:

  • Perlu adanya literasi lebih lanjut atau rekan ahli di bidang kualitas air agar dapat memberikan insight/pemahaman yang lebih mendalam terkait setiap variabel prediktor yang digunakan, agar dapat menghasilkan model yang lebih baik lagi.
ev2 <- data.frame(
  metode_klasifikasi = c("Regresi Logistik","KNN(41)","KNN(39)"),
  rbind(CF_RL$byClass,CF_41$byClass,CF_39$byClass)) %>% select(c(metode_klasifikasi,Sensitivity))
ev2
metode_klasifikasi Sensitivity
Regresi Logistik 0.0529801
KNN(41) 0.2516556
KNN(39) 0.2516556
  • apabila tujuan dari prediksi ini adalah untuk memperoleh sebanyak mungkin sumber air yang layak untuk minum perlu dialkukan pengklasifikasian dengan model lain, karena hasil evaluasi untuk keakuratan prediksi kelas target positif (potable) pada model regresi logistik dan model KNN yang ditunjukan oleh nilai Sensitivity menunjukkan nilai yang sangat rendah yakni dibawah 30%