Pengatar Data Science

~ Tugas 3 ~


Kontak : \(\downarrow\)
Email
Instagram https://www.instagram.com/saram.05/
RPubs https://rpubs.com/sausanramadhani/

Bab 5 klasifikasi I : Percobaan dan Prediksi

5.1 Ringkasan

Pada bab sebelumnya, lebih terfokus pada pertanyaan-pertanyaan mengenai data analisis deskriptif dan eksploratif. Bab kali ini dan seterusnya merupakan upaya pertama dalam menjawab pertanyaan prediktif mengenai suatu data. Khususnya, kita lebih fokus pada klasifikasi yang mana menggunakan satu atau lebih variabel untuk memprediksi nilai variabel kategori yang diminati. Bab ini akan membahas tentang dasar-dasar klasifikasi, bagaimana langkah sebelum memproses data supaya menjadi sesuai untuk digunakan dalam suatu pengklasifikasi, dan bagaimana untuk menggunakan data observasi untuk membuat prediksi. Pada bab selanjutnya akan fokus pada bagaimana mengevaluasi seberapa akurat prediksi tersebut dari klasifikasi yang kita buat, juga bagaimana untuk meningkatkan klasifikasi kita (jika memungkinkan) untuk memaksimalkan akurasinya.

5.2 Tujuan Pembelajaran

Di akhir bab, pembaca akan bisa melakukan hal berikut ini :

• Mengenali situasi di mana pengklasifikasi dapat sesuai untuk membuat prediksi.
• Menjelaskan apa itu data set pelatihan dan bagaimana ini digunakan untuk klasifikasi.
• Menafsirkan output dari pengklasifikasi.
• Menghitung menggunakan tangan, jarak garis lurus antar poin pada grafik saat terdapat dua variabel prediktor.
• Menjelaskan klasifikasi algoritma K-lingkup terdekat.
• Melakukan klasifikasi K-lingkup terdekat di R menggunakan tidymodels.
• Menggunakan recipe untuk praproses data supaya lebih terpusat, berskala, dan seimbang.
• Menggabungkan prapemrosesan dan pelatihan model menggunakan workflow.

5.3 Permasalahan Klasifikasi

klasifikasi dapat memprediksi kelas kategorikal (terkadang disebut juga label) untuk pengamatan yang diberikan ialah variabel lain (terkadang disebut juga features). Biasanya, pengklasifikasi menetapkan suatu observasi yang tanpa diketahui kelasnya menjadi sebuah kelas. Observasi ini dengan diketahui kelasnya yang kita gunakan sebagai dasar prediksi disebut juga training set. Nama ini berawal dari fakta bahwa kita menggunakan data untuk membuat prediksi pada data baru yang kita tidak ketahui kelasnya. Terdapat banyak kemungkinan metode yang bisa digunakan untuk memprediksi kelas atau label kategori untuk suatu observasi.

5.4 Eksplorasi Data Set

Terdapat data set mengenai kanker payudara dan seperti analisis data pada umumnya maka kita merumuskan pertanyaan (rumusan masalah) yang tepat bahwa kita ingin menjawabnya. Menggunakan pengukuran data tumor yang di dalamnya berisi diagnosis jinak atau ganas dan parameter lainnya seperti nukleostekstur (inti sel), perimeter area dan lain-lain. Setelah kita mengetahui data tersebut dengan beberapa pertanyaan yang berhubungan dengan data set.

5.4.1 Memuat data kanker

Kita menggunakan library tidyverse untuk mengakses datanya supaya lebih mudah dijalankan saat eksplor data dengan visualisasi.

library(tidyverse)

Data yang akan di import berupa csv, maka kita harus memanggil data tersebut dengan menggunakan kode berikut ini :

getwd()
## [1] "C:/Users/Lenovo/Documents/DOK. SAUSAN/Matana University/Semester 2/Pengantar Data Science"
dakan <- read.csv("wdbc.txt")
dakan

5.4.2 Mendeskripsikan variabel-variabel dalam data set kanker

Tumor payudara itu bisa di diagnosa disebabkannya karena biopsy. Kemudian, prosesnya di buang dari badan dan diperiksa lagi apakah penyakit itu ada. Jika menggunakan metode tradisional memakan biaya cukup mahal dan jika memakai metode modern akan membutuhkan banyak pertimbangan dan perhitungan. Contohnya kita harus mengcolab data set, mengekstrak tissu yang jumlahnya sedikit dan inasive rendah.

Dari data set kanker, kita memiliki beberapa variabel sebagai berikut :

• ID: nomor identifikasi
• Class: diagnosis (M = ganas atau B = jinak)
• radius: rata-rata jarak dari pusat ke titik-titik pada keliling
• Tekstur: standar deviasi nilai skala abu-abu
• Perimeter: panjang kontur sekitarnya
• Area: area di dalam kontur
• Kehalusan/smoothness: variasi lokal dalam panjang radius
• compactness: rasio keliling kuadrat dan luas
• concavity: tingkat keparahan bagian cekung dari kontur
• concave points: jumlah bagian cekung dari kontur
• Simetri: seberapa mirip inti ketika dicerminkan
• Fraktal dimensi: pengukuran seberapa “kasar” kelilingnya

glimpse(dakan)   # menampilkan nama variabel, tipe variabel, dan beberapa baris pertama dari data
## Rows: 569
## Columns: 12
## $ ID                <int> 842302, 842517, 84300903, 84348301, 84358402, 843786~
## $ Class             <chr> "M", "M", "M", "M", "M", "M", "M", "M", "M", "M", "M~
## $ Radius            <dbl> 1.0960995, 1.8282120, 1.5784992, -0.7682333, 1.74875~
## $ Texture           <dbl> -2.0715123, -0.3533215, 0.4557859, 0.2535091, -1.150~
## $ Perimeter         <dbl> 1.26881726, 1.68447255, 1.56512598, -0.59216612, 1.7~
## $ Area              <dbl> 0.98350952, 1.90703027, 1.55751319, -0.76379174, 1.8~
## $ Smoothness        <dbl> 1.56708746, -0.82623545, 0.94138212, 3.28066684, 0.2~
## $ Compactness       <dbl> 3.28062806, -0.48664348, 1.05199990, 3.39991742, 0.5~
## $ Concavity         <dbl> 2.65054179, -0.02382489, 1.36227979, 1.91421287, 1.3~
## $ Concave_Points    <dbl> 2.53024886, 0.54766227, 2.03543978, 1.45043113, 1.42~
## $ Symmetry          <dbl> 2.215565542, 0.001391139, 0.938858720, 2.864862154, ~
## $ Fractal_Dimension <dbl> 2.25376381, -0.86788881, -0.39765801, 4.90660199, -0~

Dari hasil diatas, kita dapat simpulkan bahwa class bertipe karakter. Karena kita akan bekerja dengan class sebagai variabel statistik kategorikal maka kita akan mengubahnya menjadi faktor menggunakan fungsi as_factor.

dakan <- dakan |>
  mutate(Class = as.factor(Class))
glimpse(dakan)
## Rows: 569
## Columns: 12
## $ ID                <int> 842302, 842517, 84300903, 84348301, 84358402, 843786~
## $ Class             <fct> M, M, M, M, M, M, M, M, M, M, M, M, M, M, M, M, M, M~
## $ Radius            <dbl> 1.0960995, 1.8282120, 1.5784992, -0.7682333, 1.74875~
## $ Texture           <dbl> -2.0715123, -0.3533215, 0.4557859, 0.2535091, -1.150~
## $ Perimeter         <dbl> 1.26881726, 1.68447255, 1.56512598, -0.59216612, 1.7~
## $ Area              <dbl> 0.98350952, 1.90703027, 1.55751319, -0.76379174, 1.8~
## $ Smoothness        <dbl> 1.56708746, -0.82623545, 0.94138212, 3.28066684, 0.2~
## $ Compactness       <dbl> 3.28062806, -0.48664348, 1.05199990, 3.39991742, 0.5~
## $ Concavity         <dbl> 2.65054179, -0.02382489, 1.36227979, 1.91421287, 1.3~
## $ Concave_Points    <dbl> 2.53024886, 0.54766227, 2.03543978, 1.45043113, 1.42~
## $ Symmetry          <dbl> 2.215565542, 0.001391139, 0.938858720, 2.864862154, ~
## $ Fractal_Dimension <dbl> 2.25376381, -0.86788881, -0.39765801, 4.90660199, -0~

Kita bisa memverifikasikan level dari kolom Class menggunakan fungsi levels.

dakan |>
  pull(Class) |>
  levels()
## [1] "B" "M"

5.4.3 Mengeksplor data kanker

Sebelum melakukan berbagai pemodelan, kita explore dulu data setnya. Kita pakai group_by, summarize, dan n untuk mencari jumlah dan persentase dari pengamatan tumor jinak dan ganas yang ada dalam data. Fungsi n bersamaan summarize saat disatukan dengan group_by bisa menghitung jumlah pengamatan di setiap kelompok kelas. Lalu kita hitung persentase tiap kelompok dengan membagi jumlah total pengamatan. Data kita mempunyai 357 (63%) jinak dan 212 (37%) ganas.

num_obs <- nrow(dakan)
dakan |>
  group_by(Class) |>
  summarize(
    count = n(),
    percentage = n() / num_obs*100
  )

Setelah itu, kita membuat plotnya yang mana melibatkan Perimeter dan Concavity. Selanjutnya, mari kita gambar alur yang menyebar untuk memvisualisasikan hubungan antara perimeter dan variabel yang menyempit. Alih-alih menggunakan palet standar ggplot, kita memilih warna kita sendiri —“orange2” untuk oranye terang dan “steelblue2” untuk biru terang — dan melewati mereka sebagai argumen nilai ke fungsi scale_color_manual. Kami juga membuat label kategori (” B “dan” M “) lebih mudah dibaca dengan mengubahnya menjadi”jinak (benign)” dan “ganas (maligant)” dengan menggunakan argumen label.

perim_concav <- dakan |>
  ggplot(aes(x = Perimeter, y = Concavity, color = Class)) +
  geom_point(alpha = 0.6) +
  labs(x = "Perimeter (standardized)",
       y = "Concavity (standardized)",
       color = "Diagnosis") +
  scale_color_manual(labels = c("Malignant", "Benign"),
                     values = c("orange2", "steelblue2")) +
  theme(text = element_text(size = 12))
perim_concav

5.5 Klasifikasi Menggunakan K-Nearest Neighbors

Terdapat beberapa cara untuk mengklasifikasikan data dengan menggunakan KNN (K-Nearest Neighbor) sebagai berikut :

5.5.1 Jarak antar poin

Kita bisa menghitung jarak antar poin dengan menggunakan K-Nearest Neighbors. Berikut ini kode perhitungannya :

new_obs_Perimeter <- 0
new_obs_Concavity <- 3.5  # nilai K terkecil
dakan |>
  select(ID, Perimeter, Concavity, Class) |>
  mutate(dist_from_new = sqrt((Perimeter - new_obs_Perimeter)^2 +
                                (Concavity - new_obs_Concavity)^2)) |>
  arrange(dist_from_new) |>
  slice(1:5)  # 5 baris pertama

5.5.2 Lebih dari dua penjelasan variabel

Untuk variabel yang lebih dari dua bisa menggunakan kode berikut ini :

new_obs_Perimeter <- 0
new_obs_Concavity <- 3.5
new_obs_Symmetry <- 1

dakan |>
  select(ID, Perimeter, Concavity, Symmetry, Class) |>
  mutate(dist_from_new = sqrt((Perimeter - new_obs_Perimeter)^2 +
                                (Concavity - new_obs_Concavity)^2 +
                                (Symmetry - new_obs_Symmetry)^2)) |>
  arrange(dist_from_new) |>
  slice(1:5) #5 baris pertama

5.5.3 Penjumlahan Algoritma K-Nearest Neighbors

Untuk mengklasifikasi pengamatan baru menggunakan KNN, kita bisa melakukan tahapan berikut :

• Menghitung jarak antara pengamatan baru dan setiap pengamatan dalam set pelatihan.
• Mengurutkan tabel data dalam urutan menaik menurut jarak.
• Pilih baris KNN teratas dari tabel yang diurutkan.
• Klasifikasikan pengamatan baru berdasarkan suara mayoritas dari kelas tetangga.

5.6 K-nearest neighbors menggunakan tidymodels

Kita menggunakan fungsi select untuk memilih kolom data yang akan difokuskan saat memproses K-Nearest Neighbors. Berikut ini kode KNN menggunakan tidymodels :

library(tidymodels)

kanker_train <- dakan |>
  select(Class, Perimeter, Concavity)
kanker_train

Untuk pemodelan dari K-Nearest Neighbors bisa menggunakan fungsi nearest_neighbor (K=5). Kita juga menggunakan fungsi set_engine untuk menentukan jenis metode/model yang akan digunakan. Fungsi set_mode untuk menentukan klasifikasi K-Nearest Neighbors. Berikut ini kodenya :

knn_spec <- nearest_neighbor(weight_func = "rectangular", neighbors = 5) |>
  set_engine("kknn") |>
  set_mode("classification")
knn_spec
## K-Nearest Neighbor Model Specification (classification)
## 
## Main Arguments:
##   neighbors = 5
##   weight_func = rectangular
## 
## Computational engine: kknn

Untuk menyesuaikan model pada data kanker payudara, kita harus melewati spesifikasi model dan kumpulan data ke fungsi fit. Kita juga perlu menentukan variabel apa yang akan digunakan sebagai prediktor dan variabel apa yang akan digunakan sebagai target. Di bawah, argumen Class ~ Perimeter + Concavity menetapkan bahwa Class adalah variabel target (yang ingin kita prediksi), dan Perimeter dan Concavity akan digunakan sebagai prediktor.

knn_fit <- knn_spec |>
  fit(Class ~ Perimeter + Concavity, data = kanker_train)
knn_fit <- knn_spec |>
  fit(Class ~ ., data = kanker_train)
knn_fit
## parsnip model object
## 
## Fit time:  51ms 
## 
## Call:
## kknn::train.kknn(formula = Class ~ ., data = data, ks = min_rows(5,     data, 5), kernel = ~"rectangular")
## 
## Type of response variable: nominal
## Minimal misclassification: 0.07557118
## Best kernel: rectangular
## Best k: 5
new_obs <- tibble(Perimeter = 0, Concavity = 3.5)
predict(knn_fit, new_obs)

5.7 Memproses Data Menggunakan tidymodels

5.7.1 Pemusatan dan Penskalaan

Memproses data menggunakan tidymodels berawal dari data unscaled_kanker melakukan perubahan tipe data menjadi faktor dan melakukan pemilihan data diantaranta Class, Area, Smoothness saat pemrosesan menggunakan fungsi select.

unscaled_kanker <- read_csv("unscaled_wdbc.txt") |>
  mutate(class = as_factor(Class)) |>
  select(Class, Area, Smoothness)
unscaled_kanker
uc_recipe <- recipe(Class ~ ., data = unscaled_kanker)
print(uc_recipe)
## Recipe
## 
## Inputs:
## 
##       role #variables
##    outcome          1
##  predictor          2
uc_recipe <- uc_recipe |>
  step_scale(all_predictors()) |>
  step_center(all_predictors()) |>
  prep()
uc_recipe
## Recipe
## 
## Inputs:
## 
##       role #variables
##    outcome          1
##  predictor          2
## 
## Training data contained 569 data points and no missing data.
## 
## Operations:
## 
## Scaling for Area, Smoothness [trained]
## Centering for Area, Smoothness [trained]
scaled_cancer <- bake(uc_recipe, unscaled_kanker)
scaled_cancer

5.7.2 Pengimbangan

Permasalahan ketidakseimbangan data, misalnya seperti mengambil 3 data dari ganas (malignant) dan menyimpan semua data Benign dengan menggunakan fungsi slice_head().

rare_cancer <- bind_rows(
  filter(dakan, Class == "B"),
  dakan |> filter(Class == "M") |> slice_head(n=3)
) |>
  select(Class, Perimeter, Concavity)

rare_plot <- rare_cancer |>
  ggplot(aes(x = Perimeter, y = Concavity, color = Class)) +
  geom_point(alpha = 0.5) +
  labs(x = "Perimeter (standardized)",
       y = "Concavity (standardized)",
       color = "Diagnosis") +
  scale_color_manual(labels = c("Malignant", "Benign"),
                     values = c("orange2", "steelblue2")) +
  theme(text = element_text(size = 12))

rare_plot

Untuk menghindari permasalahan di atas, maka kita melakukan cara statistika yaitu dengan menambahkan oversampling pada data ups_recipe dan menggunakan fungsi step_upsample() dari package themis.

library(themis)

ups_recipe <- recipe(Class ~ ., data = rare_cancer) |>
  step_upsample(Class, over_ratio = 1, skip = FALSE) |>
  prep()

ups_recipe
## Recipe
## 
## Inputs:
## 
##       role #variables
##    outcome          1
##  predictor          2
## 
## Training data contained 360 data points and no missing data.
## 
## Operations:
## 
## Up-sampling based on Class [trained]

Untuk melihat apakah proses Balancing data sudah sukses kita dapat menggunakan metode dibawah ini.

upsampled_cancer <- bake(ups_recipe, rare_cancer)

upsampled_cancer |>
  group_by(Class) |>
  summarize(n = n())

5.8 Menyatukannya Dalam Sebuah Workflow

Koleksi package tidymodels juga menyediakan workflow, cara untuk menyatukan beberapa langkah analisis data tanpa banyak kode yang diperlukan untuk langkah perantara. Untuk mengilustrasikan keseluruhan pipeline, mari kita mulai dari awal dengan data unscaled_wdbc.csv. Pertama kita akan memuat data, membuat model, dan menentukan resep bagaimana data harus diproses sebelumnya:

# load the unscaled cancer data
# and make sure the target Class variable is a factor
unscaled_kanker <- read.csv("unscaled_wdbc.txt") |>
  mutate(Class = as_factor(Class))

# create the KNN model
knn_spec <- nearest_neighbor(weight_func = "rectangular", neighbors = 7) |>
  set_engine("kknn") |>
  set_mode("classification")

# create the centering / scaling recipe
uc_recipe <- recipe(Class ~ Area + Smoothness, data = unscaled_kanker) |>
  step_scale(all_predictors()) |>
  step_center(all_predictors())

Kita tidak menggunakan fungsi select untuk mengekstrak variabel yang relevan dari data frame.

knn_fit <- workflow() |>
  add_recipe(uc_recipe) |>
  add_model(knn_spec) |>
  fit(data = unscaled_kanker)

knn_fit
## == Workflow [trained] ==========================================================
## Preprocessor: Recipe
## Model: nearest_neighbor()
## 
## -- Preprocessor ----------------------------------------------------------------
## 2 Recipe Steps
## 
## * step_scale()
## * step_center()
## 
## -- Model -----------------------------------------------------------------------
## 
## Call:
## kknn::train.kknn(formula = ..y ~ ., data = data, ks = min_rows(7,     data, 5), kernel = ~"rectangular")
## 
## Type of response variable: nominal
## Minimal misclassification: 0.112478
## Best kernel: rectangular
## Best k: 7

Untuk melakukan prediksi pada penelitian kita gunakan predict() dengan objeknya adalah knn_fit. Dibawah ini kita lakukan prediksi pada data Class dengan dua label penelitian yang berbeda yaitu dengan Area 1 = 500, Area 2 = 1500, Smoothness 1 = 0.075 dan Smoothness 2 = 0.1 :

new_observation <- tibble(Area = c(500, 1500), Smoothness = c(0.075, 0.1))
prediction <- predict(knn_fit, new_observation)

prediction
# create the grid of area/smoothness vals, and arrange in a data frame
are_grid <- seq(min(unscaled_kanker$Area),
                max(unscaled_kanker$Area),
                length.out = 100)
smo_grid <- seq(min(unscaled_kanker$Smoothness),
                max(unscaled_kanker$Smoothness),
                length.out = 100)
asgrid <- as_tibble(expand.grid(Area = are_grid,
                                Smoothness = smo_grid))

# use the fit workflow to make prediction at the grid points
knnPredGrid <- predict(knn_fit, asgrid)

#bind the predictions as a new column with the grid points
prediction_table <- bind_cols(knnPredGrid, asgrid) |>
  rename(Class = .pred_class)

# plot:
# 1. the colored scatter of the original data
# 2. the faded colored scatter for the grid points
wkflw_plot <-
  ggplot() +
  geom_point(data = unscaled_kanker, 
             mapping = aes(x = Area, 
                           y = Smoothness, 
                           color = Class), 
             alpha = 0.75) +
  geom_point(data = prediction_table, 
             mapping = aes(x = Area, 
                           y = Smoothness, 
                           color = Class), 
             alpha = 0.02, 
             size = 5) +
  labs(color = "Diagnosis", 
       x = "Area (standardized)", 
       y = "Smoothness (standardized)") +
  scale_color_manual(labels = c("Malignant", "Benign"), 
                     values = c("orange2", "steelblue2")) +
  theme(text = element_text(size = 12))

wkflw_plot

Berdasarkan plot diatas, pada area 1000 sampai 1500 dengan kehalusan antara 0.075 sampai 0.125 merupakan titik kumpul terbanyak dari tumor ganas. Sedangkan, pada area 500 dengan kehalusan 0.075 sampai 0.100 merupakan titik kumpul terbanyak dari tumor jinak.