REGRESI LOGISTIK UNTUK KLASIFIKASI BINER (dengan Software R)

19 Aug 2020 imran Alwi 0 Pemrograman

REGRESI LOGISTIK UNTUK KLASIFIKASI BINER

(dengan Software R)

Oleh: Fitri Ramadhini

    Regresi logistik merupakan suatu algoritma dalam pengklasifikasian atau classifier yang dapat digunakan untuk memprediksi suatu kelas variabel. Dalam praktiknya, regresi logistik banyak digunakan dalam mengklasifikasikan 2 kelas dalam suatu variabel atau klasifikasi biner. Aplikasi regresi logistik menggunakan software R tidak jauh berbeda dengan regresi linear. Jika regresi linear menggunakan fungsi lm() untuk membangun model, maka regresi logistik menggunakan fungsi glm() untuk membangun modelnya.

Data

Data untuk contoh ini adalah data heart disease sebanyak 303 observasi dan 14 variabel. Dari data ini akan diprediksi apakah seseorang terkena penyakit jantung atau tidak (variabel num) berdasarkan 13 variabel penjelas. Berikut adalah deskripsi dari data heart disease:

Nama Variabel

Deskripsi

Nama Variabel

Deskripsi

Age

Umur dari pasien

Thalach

maximum heart rate achieved
Sex

Jenis kelamin

0: female

1: male

Exang

Exercise induced angina

0: tidak

1: ya

Cp

Chest Pain type

1: typical angina

2: atypical angina

3: non-anginal pain

4: asymptomatic

Oldpeak

ST depression induced by exercise relative to rest
Trestbps
Resting blood pressure (mm Hg)

Slope

Slope of peak exercise ST segment

1: upsloping

2: flat

3: downsloping

Chol

Serum cholesterol (mg/dl)

Ca

number of major vessels (0-3) colored by flourosopy
Fbs

Fasting blood sugar > 120 mg/dl

0: tidak

1: ya

Thal

3 = normal
6 = fixed defect
7 = reversable defect
restecg
resting electrocardiographic results
0: normal
1: having ST-T wave abnormality (T wave inversions and/or ST                  elevation or depression of > 0.05 mV)
2: showing probable or definite left ventricular hypertrophy by Estes' criteria

Num

diagnosis of heart disease (angiographic disease status)
0: < 50% diameter narrowing
1: > 50% diameter narrowing

(Sumber: https://archive.ics.uci.edu/ml/machine-learning-databases/heart-disease/heart-disease.names)

Variabel yang akan diprediksi adalah variabel num, dengan mengasumsikan bahwa nilai 0 berarti jantung baik-baik saja, dan nilai 1, 2, 3, 4 berarti jantung terkena penyakit. Data heart disease dapat langsung diimpor menggunakan fungsi read.csv() dengan memasukkan alamat https://archive.ics.uci.edu/ml/machine-learning-databases/heart-disease/processed.cleveland.data yang merupakan sumber data tersebut.

heart <- read.csv("https://archive.ics.uci.edu/ml/machine-learning-databases/heart-disease/processed.cleveland.data",header=FALSE,sep=",",na.strings = '?')
names(heart) <- c( "age", "sex", "cp", "trestbps", "chol","fbs", "restecg","thalach","exang", "oldpeak","slope", "ca", "thal", "num")
head(heart)
  age sex cp trestbps chol fbs restecg thalach exang oldpeak slope ca thal num
1  63   1  1      145  233   1       2     150     0     2.3     3  0    6   0
2  67   1  4      160  286   0       2     108     1     1.5     2  3    3   2
3  67   1  4      120  229   0       2     129     1     2.6     2  2    7   1
4  37   1  3      130  250   0       0     187     0     3.5     3  0    3   0
5  41   0  2      130  204   0       2     172     0     1.4     1  0    3   0
6  56   1  2      120  236   0       0     178     0     0.8     1  0    3   0

Ekplorasi Data

    

heart$num<-ifelse(heart$num==0,0,1)
str(heart)
'data.frame':    303 obs. of  14 variables:
 $ age     : num  63 67 67 37 41 56 62 57 63 53 ...
 $ sex     : num  1 1 1 1 0 1 0 0 1 1 ...
 $ cp      : num  1 4 4 3 2 2 4 4 4 4 ...
 $ trestbps: num  145 160 120 130 130 120 140 120 130 140 ...
 $ chol    : num  233 286 229 250 204 236 268 354 254 203 ...
 $ fbs     : num  1 0 0 0 0 0 0 0 0 1 ...
 $ restecg : num  2 2 2 0 2 0 2 0 2 2 ...
 $ thalach : num  150 108 129 187 172 178 160 163 147 155 ...
 $ exang   : num  0 1 1 0 0 0 0 1 0 1 ...
 $ oldpeak : num  2.3 1.5 2.6 3.5 1.4 0.8 3.6 0.6 1.4 3.1 ...
 $ slope   : num  3 2 2 3 1 1 3 1 2 3 ...
 $ ca      : num  0 3 2 0 0 0 2 0 1 0 ...
 $ thal    : num  6 3 7 3 3 3 3 3 7 7 ...
 $ num     : num  0 1 1 0 0 0 1 0 1 1 ...

Variabel-variabel di atas semuanya berupa numerik, akan tetapi jika dilihat dari deskripsi data, ada beberapa variabel yang berupa kategorik yaitu variabel sex, cp, fbs, restecg, exang, slope, ca, thal, dan num sehingga variabel-variabel ini perlu diubah menjadi variabel yang berupa kategorik.

heart$sex<-as.factor(heart$sex)
heart$cp<-as.factor(heart$cp)
heart$fbs<-as.factor(heart$fbs)
heart$restecg<-as.factor(heart$restecg)
heart$exang<-as.factor(heart$exang)
heart$slope<-as.factor(heart$slope)
heart$ca<-as.factor(heart$ca)
heart$thal<-as.factor(heart$thal)
heart$num<-as.factor(heart$num)
str(heart)
'data.frame':    303 obs. of  14 variables:
 $ age     : num  63 67 67 37 41 56 62 57 63 53 ...
 $ sex     : Factor w/ 2 levels "0","1": 2 2 2 2 1 2 1 1 2 2 ...
 $ cp      : Factor w/ 4 levels "1","2","3","4": 1 4 4 3 2 2 4 4 4 4 ...
 $ trestbps: num  145 160 120 130 130 120 140 120 130 140 ...
 $ chol    : num  233 286 229 250 204 236 268 354 254 203 ...
 $ fbs     : Factor w/ 2 levels "0","1": 2 1 1 1 1 1 1 1 1 2 ...
 $ restecg : Factor w/ 3 levels "0","1","2": 3 3 3 1 3 1 3 1 3 3 ...
 $ thalach : num  150 108 129 187 172 178 160 163 147 155 ...
 $ exang   : Factor w/ 2 levels "0","1": 1 2 2 1 1 1 1 2 1 2 ...
 $ oldpeak : num  2.3 1.5 2.6 3.5 1.4 0.8 3.6 0.6 1.4 3.1 ...
 $ slope   : Factor w/ 3 levels "1","2","3": 3 2 2 3 1 1 3 1 2 3 ...
 $ ca      : Factor w/ 4 levels "0","1","2","3": 1 4 3 1 1 1 3 1 2 1 ...
 $ thal    : Factor w/ 3 levels "3","6","7": 2 1 3 1 1 1 1 1 3 3 ...
 $ num     : Factor w/ 2 levels "0","1": 1 2 2 1 1 1 2 1 2 2 ...

Variabel-variabel di atas sudah memiliki jenis variabel yang sesuai dengan deskripsi data. Langkah selanjutnya adalah melihat jumlah kelas pada variabel yang akan diprediksi.

levels(heart$num) = c("No Disease","Disease")
levels(heart$sex) = c("Female","Male")
table(heart$num)
No Disease    Disease 
       164        139 
prop.table(table(heart$num))
No Disease    Disease 
 0.5412541  0.4587459

Jumlah kelas pada data menunjukkan proporsi yang cukup seimbang, sehingga dapat dikatakan tidak ada masalah imbalanced class pada data.

#Pie Chart
mytable <- table(heart$num)
lbls <- paste(names(mytable), "\n", mytable, sep="")
pie(mytable, labels = lbls,
main="Pie Chart of Disease \n (with sample sizes)",
col=c("aquamarine","pink"))
#Grouped Bar Plot
											
counts <- table(heart$num,heart$sex)
barplot(counts,
main="Sebaran Penyakit berdasarkan Jenis Kelamin",
xlab=" ", col=c("aquamarine","pink"),legend=rownames(counts), beside=TRUE)

Pie chart dari variabel respon menunjukkan kelas cukup seimbang, sedangkan bar chart di atas menunjukkan sebaran penyakit berdasarkan jenis kelamin dimana pada kelompok female jumlah pasien yang terdiagnosa penyakit jantung lebih kecil dibanding yang normal, sedangkan pada kelompok male jumlah pasien yang terdiagnosa penyakit jantung lebih besar dibanding yang normal.

Stratifikasi Data

Stratifikasi data diperlukan untuk memastikan setiap kelas respon terambil dalam pengacakan. Stratifikasi data dilakukan dengan fungsi filter() dalam paket dplyr.

library(dplyr)
ho <- filter(heart,num=="No Disease")
hd <- filter(heart,num=="Disease")

Data Training dan Data Testing

    Data training digunakan untuk membangun model, sedangkan data testing digunakan untuk validasidengan pembagian training:testing 70%:30%. Pengambilan data secara acak menggunakan nilai seed 10. Penggunaan seed dilakukan agar hasil pengacakan tetap. Setiap nilai seed akan melakukan pengacakan yang berbeda sehingga hasil dari setiap nilai seed juga akan berbeda (misal dalam akurasi).

set.seed (10)
acak.ho <- sample(1:nrow(ho), 0.7*nrow(ho))
acak.hd <- sample(1:nrow(hd), 0.7*nrow(hd))
heart.tr <- rbind(ho[acak.ho,],hd[acak.hd,])
heart.test <- rbind(ho[-acak.ho,],hd[-acak.hd,])

Regresi Logistik

    Data training digunakan untuk membangun model regresi logistik dengan menggunakan fungsi glm() karena regresi logistik termasuk ke dalam generalized linear model dengan family = binomial.

model.logistik<-glm(num~.,data=heart.tr, family="binomial")
summary(model.logistik)
Call:
glm(formula = num ~ ., family = "binomial", data = heart.tr)
Deviance Residuals: 
    Min       1Q   Median       3Q      Max  
-3.1937  -0.4073  -0.1068   0.2770   2.5892  
Coefficients:
             Estimate Std. Error z value Pr(>|z|)    
(Intercept) -6.066907   3.714357  -1.633 0.102392    
age         -0.029392   0.032283  -0.910 0.362589    
sexMale      1.683733   0.732862   2.297 0.021592 *  
cp2          1.998763   1.061595   1.883 0.059729 .  
cp3          0.761080   0.849789   0.896 0.370461    
cp4          3.099118   0.844679   3.669 0.000244 ***
trestbps     0.037416   0.013773   2.717 0.006595 ** 
chol         0.004578   0.005052   0.906 0.364839    
fbs1        -0.613889   0.804426  -0.763 0.445380    
restecg1     0.535486   3.411634   0.157 0.875277    
restecg2     0.502065   0.487491   1.030 0.303059    
thalach     -0.029019   0.017100  -1.697 0.089689 .  
exang1       0.791261   0.533940   1.482 0.138359    
oldpeak      0.349409   0.301611   1.158 0.246670    
slope2       0.841794   0.601662   1.399 0.161779    
slope3      -0.417909   1.486485  -0.281 0.778604    
ca1          1.950010   0.648863   3.005 0.002653 ** 
ca2          3.224709   1.111950   2.900 0.003731 ** 
ca3          2.492708   1.231755   2.024 0.043001 *  
thal6       -0.064460   1.044622  -0.062 0.950796    
thal7        1.659596   0.555522   2.987 0.002813 ** 
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
(Dispersion parameter for binomial family taken to be 1)
    Null deviance: 285.88  on 206  degrees of freedom
Residual deviance: 124.31  on 186  degrees of freedom
  (4 observations deleted due to missingness)
AIC: 166.31
Number of Fisher Scoring iterations: 6

Dari output di atas, variabel sex, cp, trestbps, ca, dan thal signifikan mempengaruhi respon (num) pada taraf nyata 5%. Pemilihan variabel juga dapat dilakukan dengan hanya memasukkan variabel-variabel yang signifikan mempengaruhi respon dan kemudian membandingkan nilai akurasinya. Dalam artikel ini akan dilakukan hanya pada model penuh (memasukkan semua variabel). Interpretasi untuk pengaruh setiap variabel dapat dilihat dari nilai rasio odds. Misalnya, untuk variabel sex memiliki nilai koefisien sebesar 1.683733 dengan reference category = female, nilai rasio odds nya adalah exp(1.683733) = 5.38 yang artinya untuk pasien laki-laki, odds untuk terkena penyakit jantung adalah 5.38 kali odds perempuan atau dapat dikatakan kecenderungan laki-laki untuk terkena penyakit jantung lebih besar dibanding perempuan.

Prediksi Variabel Respon pada Data Testing

    Prediksi respon pada data testing dilakukan menggunakan threshold = 0.5 dimana jika nilai probabilitas prediksi > 0.5 maka akan diprediksi di kelas event (disease) dan sebaliknya akan diprediksi masuk di kelas non event (no disease).

prob.prediksi<-predict(model.logistik, heart.test, type="response")
prediksi<-ifelse(prob.prediksi>0.5,"Disease","No Disease")

pred.aktual<-data.frame("Prediksi"=prediksi,"Aktual"=heart.test$num)

head(pred.aktual)

Prediksi Aktual

1 No Disease No Disease

5 No Disease No Disease

6 No Disease No Disease

7 No Disease No Disease

11 No Disease No Disease

15 No Disease No Disease

Akurasi

    Hasil prediksi pada data testing selanjutnya dibandingkan dengan data sebenarnya pada respon data testing. Nilai akurasi diperoleh dari fungsi confusionMatrix() pada paket caret.

 

library(caret)
confusionMatrix(as.factor(prediksi), heart.test$num)
Confusion Matrix and Statistics

Accuracy : 0.8778
									
                 95% CI : (0.7918, 0.9374)
    No Information Rate : 0.5444          
    P-Value [Acc > NIR] : 1.202e-11       
                  Kappa : 0.7521          
 Mcnemar's Test P-Value : 0.5465          
            Sensitivity : 0.9184          
            Specificity : 0.8293          
         Pos Pred Value : 0.8654          
         Neg Pred Value : 0.8947          
             Prevalence : 0.5444          
         Detection Rate : 0.5000          
   Detection Prevalence : 0.5778          
      Balanced Accuracy : 0.8738          
       'Positive' Class : No Disease 

Dari Output di atas, untuk hasil confusion matrix prediksi yang meleset cukup kecil yaitu 7 untuk false positivedan 4 untuk false negative.Nilai akurasi sebesar 87.78% menunjukkan bahwa hasil klasifikasi dengan regresi logistik pada data ini sudah cukup baik.

BY: imran Alwi

Artikel terkait

Belum ada komentar, Jadilah yang pertama mengomentari.