Introduction to Data Science

Classification I: training & predicting - TUGAS 3


Kontak : \(\downarrow\)
Email :
Instagram : https://www.instagram.com/dhelaasf/
RPubs : https://rpubs.com/dhelaasafiani/
NIM : 20214920009
Prodi : Statistika Bisnis 2021
Nama : Dhela Asafiani Agatha

Soal

Your task is to execute all code from material 4 on your Rstudio dan publish your report using Rpubs.

Introduction

Pada kasus kali ini, kita akan belajar apa itu KNN (K-Nearest Neighbors). K-nearest neighbors atau knn adalah algoritma yang berfungsi untuk melakukan klasifikasi suatu data berdasarkan data pembelajaran (train data sets), yang diambil dari k tetangga terdekatnya (nearest neighbors). Dengan k merupakan banyaknya tetangga terdekat.
Kita ambil contoh, misalnya suatu pemerintahan mengalami kesulitan dalam menentukan batas daerah seperti daerah Kota Tangerang dengan Kota Tangerang Selatan. Kita bisa menentukannya dengan menggunakan Algoritma k-NN, yaitu dengan melibatkan jarak antara rumah tersebut dengan rumah-rumah yang ada disekitarnya (tetangganya).
Dalam contoh ini, untuk meneyelesaikan nya diperlukan klasifikasi KNN. KNN dapat membantu kita dalam melihat hal yang detail. Sehinga nantinya kita tahu apa akar dari permasalahan suatu penyebab masalah yang sedang kita cari ini. Akan tetapi, pada pembahasan kali ini, kita akan membahas tentang jenis kanker payudara yang terjadi, dimana terdapat 2 jenis kanker nya yaitu ganas atau jinak. Dari sini kita perlu untuk menentukan secara akurat, jenis kanker apa yang terjadi pada suatu data yang kita telaah.

Exploring a data set

Impor the Data

Pada kali ini saya ingin mengimpor dataset yang bernama wdbc.csv dimana isinya tentang data kanker payudara. Setiap barisnya memiliki sampel gambar tumor pada kankernya, dan juga diagnosis nya (Jinak dan Ganas) serta pengukuran nya.

Pada dasarnya, ketika kita ingin mendiagnosa sesuatu tumor, dibutuhkan cara yang detail dan akurat sehingga hasilnya juga akurat. Kita tidak bisa memprediksi atau mendiagnosa sebuah tumor hanya dengan penglihatan kita saja. Pasti hasilnya tidak akurat. Maka dari itu, perlu dilakukan diagnosa tumor yang lebih akurat agar kita mengetahui tumor tersebut bersifat jinak atau justru bersifat ganas.

library(tidyverse)
data.cancer <- read.csv("https://raw.githubusercontent.com/UBC-DSCI/introduction-to-datascience/master/data/wdbc.csv")
data.cancer

Describing the variables in the cancer data set


Setelah kita mengimpor dataset yang kita inginkan, alangkah baiknya bila kita mengetahui data yang memiliki banyak kolom dengan posisi menyamping dibandingkan posisi menurun. Untuk melakukan hal ini, kita perlu menggunakan fungsi glimpse agar memudahkan kita dalam melihat dataset nya.

glimpse(data.cancer)
## 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~

Note: Disini terdapat beberapa kolom yang ada di dalam data. Kolom-kolom itu adalah 1. ID: Nomor Identitas
2. Class: Jenis diagnosa nya (Bersifat jinak atau ganas)
3. Radius: rata-rata jarak dari pusat ke titik-titik pada keliling
4. Texture: standar deviasi nilai skala abu-abu
5. Perimeter: panjang kontur sekitarnya
6. Area: area di dalam kontur
7. Smoothness: variasi lokal dalam panjang radius
8. Compactness: rasio keliling kuadrat dan luas
9. Concavity: Kecekungannya
10. Concave_points: jumlah bagian cekung dari kontur
11. Symmetry: seberapa mirip inti ketika dicerminkan
12. Fractal_Dimension: menunjukkan seberapa kasar kelilingnya


Dari data di atas kita bisa melihat bahwa kolom Class merupakan bentuk character. Karena dalam kondisi ini kolom Class merupakan kolom dari jenis yang mewakili data, maka dari itu kita perlu mengubah menjadi factor dengan fungsi as_factor.

data.cancer <- data.cancer |>
  mutate(Class = as_factor(Class))
glimpse(data.cancer)
## 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~


Untuk melihat kategori yang ada di dalam kolom Class, kita perlu menggunakan fungsi pull untuk mengesktrak 1 kolom lalu fungsi levels untuk melihat kategori apa saja yang ada di dalam kolom itu. Dan seperti yang kita lihat, terdapat kategori M dan B dalam kolom Class.

data.cancer |>
  pull(Class) |>
  levels()
## [1] "M" "B"

Exploring the cancer data


Kita juga perlu untuk mengetahui frekuensi dari tiap kolom Class agar kita mengetahui data menunjukkan berapa jumlah tumor ganas dan berapa jumlah tumor jinak nya. Dalam hal ini kita menggunakan fungsi group_by.Setelah itu, kita juga perlu mengetahui presentase setiap jenis tumor nya, disini kita bisa kalkulasikan dengan menggunakan count yang dimana kita akan membagi frekuensi jenis tumor dengan kolom yang dikali dengan 100.

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


Langkah selanjutnya, kita sudah bisa memulai untuk membuat grafik scatterplot nya. Dimana kita memplot variabel Perimeter dan Concavity.

perim_concav <- data.cancer |>
  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("brown1", "lightgreen")) +
  theme(text = element_text(size = 12))
perim_concav

Seperti pada grafik di atas, dapat disimpulkan bahwa sebaran bawah kiri menunjukkan sebaran jenis tumor jinak atau Benign yang memiliki nilai kecekungan dan keliling yang rendah. Sedangkan jika kita perhatikan pada sebaran kanan atas, sebaran tersebut menunjukkan tumor jenis ganas atau Malignant yang memiliki tingkatan yang tinggi.

Classification with KNN

Untuk membuat prediksi kita lebih kuat, kita perlu untuk melakukan langkah pengklasifikasian atau metode K-Nearest Neighbor. Nah, untuk mengetahui penggunaannya, kita perlu menyimak langkah-langkah dibawah. KNN biasa digunakan untuk mencari K terdekat atau hampir sama untuk nantinya di diagnosis dalam membuat prediksi suatu observasi.
Dalam contoh kali ini, kita buat gambaran dalam menggunakan konsep KNN. Disini kita misalkan ketika kita melakukan observasi KNN dengan menggunakan perimeter 2 dan concavity nya adalah 4. Dimana diagnosis Class belum diketahui. Observasi menunjukkan titik merah yang belum diketahui kejelasannya.


Setelah itu, pada gambar di bawah ini dapat kita liat terdapat observasi yang baru berupa jenis ganas atau Malignant. Disini nilai perimeter dan concavity nya bernilai sama.


Untuk kali ini kita misalkan observasi baru nya adalah perimeter bernilai 0.2 dan concavity bernilai 3.3. Dapat kita lihat dari grafik di bawah bahwa titik merah yang belum diketahui kejelasannya berupa jenis jinak atau Benign.


Kali ini kita ambil contoh K = 3, dari grafik di bawah dapat kita lihat bahwa terdapat 2 dari 3 diagnosis observasi baru adalah jenis ganas. Maka dari itu, hasil pengamatan merah ini mengklasifikasikan bahwa itu adalah tipe jenis ganas.

Distance between points


Langkah selanjutnya, kita perlu mencoba membuat grafiknya agar kita mengetahui hubungan antara perimeter dengan concavity nya. Warna kuning berarti diagnosis Malignant dan warna hijau untuk diagnosis Benign. Disini kita menggunakan grafik scatterplot agar lebih mudah untuk melihat jenis diagnosis nya.

new_obs_Perimeter <- 0
new_obs_Concavity <- 3.5
data.cancer |>
  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) # take the first 5 rows

More than two explanatory variables

Pada langkah ini kita kita menggunakan rumus yang lebih banyak dimensi. Seperti dalam peritungan kita ingin menghitung 3 variabel. yaitu perimeter, concavity, dan symmetry. Pada contoh sebelumnya, kita hanya menggunakan 2 variabel yang menjumlahkan selisih kuadrat antara kedua variabelnya, dan kemudian di akar kuadratkan.
Mari kita coba hitung untuk mencari K=5 neighbors ketika kita memiliki 3 prediktor dibawah ini.

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

data.cancer |>
  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) # take the first 5 rows


Berdasarkan K=5 dgn 3 prediktor yang kita pakai di atas, kita mendapatkan pengamatan baru hasil pengklasifikasian yan menunjukkan knn adalah kelas malignant.

KNN with tidymodels


Langkah berikut ini kita ingin menampilkan data yang berisi kolom Class, Perimeter, Concavity saja untuk memfokuskan pengklasifikasian pada K-Nearest Neighbors. Kita menggunakan fungsi select untuk menampilkan kolom yang ingin kita tampilkan.

library(tidymodels)
cancer_train <- data.cancer |>
  select(Class, Perimeter, Concavity)
cancer_train


Pada langkah ini kita akan memulai untuk membuat model klasifikasi KNN nya dengan menggunakan fungsi nearest_neighbor. dimana K nya adalah 5. Kita juga memakai jarak garis lurusnya berupa rectangular. Set_engine digunakan untuk menentukan model apa yang ingin kita pakai dalam mengklasifikasi. dan set_mode dengan classification untuk melakukan klasifikasi.

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


Diaini kita memanggil library kknn untuk melakukan klasifikasi KNN. Langkah pertama yang perlu kita lakukan adalah perlu untuk menyesuaikan pemodelan dengan dataset nya terlebih dahulu menggunakan fungsi fit. Di langkah ini kita juga menentukan variabel apa yang akan kita jadikan target dan prediktor. Pada kali ini, kita akan menjadikan variabel Class sebagai target serta perimeter dan concavity menjadi predictor.

library(kknn)
## Warning: package 'kknn' was built under R version 4.1.2
knn_fit <- knn_spec |>
  fit(Class ~ Perimeter + Concavity, data = cancer_train)


Kita juga dapat menggunakan sintaks singkatan yang nyaman menggunakan titik, Class ~ ., untuk menunjukkan bahwa kita ingin menggunakan setiap variabel kecuali Class sebagai prediktor dalam model.

knn_fit <- knn_spec |>
  fit(Class ~ ., data = cancer_train)
knn_fit
## parsnip model object
## 
## Fit time:  31ms 
## 
## 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


Di sini Anda dapat melihat ringkasan model terlatih terakhir. Ini menegaskan bahwa mesin komputasi yang digunakan untuk melatih model adalah kknn::train.kknn.
Pada langkah dibawah ini, kita akan memprediksi datanya. Kira menggunakan fungsi predict() untuk memprediksi data yang ingin kita prediksi. Dan ketika kita run, kita bisa melihat hasilnya. Hasilnya menunjukkan hasil klasifikasi yang memprediksi adanya pengamatan baru sebagai M atau tipe ganas.

new_obs <- tibble(Perimeter = 0, Concavity = 3.5)
predict(knn_fit, new_obs)


Akan tetapi, dalam hal ini kita belum tahu apakah yang kita prediksi benar atau tidak. Prediksi pengklasifikasi belum tentu benar,maka dari itu kita perlu belajar cara mengukur seberapa akurat prediksi kita.

Data preprocessing with tidymodels

Centering and scaling


Untuk menskalakan dan memusatkan data kita, kita perlu menemukan mean variabel kita (rata-rata, yang mengkuantifikasi nilai “pusat” dari serangkaian angka) dan standar deviasi (angka yang mengukur seberapa tersebar nilai). Untuk setiap nilai variabel yang diamati, kita kurangi mean (yaitu, pusatkan variabel) dan bagi dengan standar deviasi (yaitu, skala variabel). Ketika kita melakukan ini, data dikatakan terstandarisasi, dan semua variabel dalam kumpulan data akan memiliki rata-rata 0 dan simpangan baku 1.

Untuk mempermudah, kita hanya akan menggunakan variabel Area, Smoothness, dan Class. Disini kita akan menggunakan dataset unscaled_wdbc.csv.

Seperti biasa kita menjadikan variabel Class menjadi factor

data.unscaled <- read.csv("https://raw.githubusercontent.com/UBC-DSCI/introduction-to-datascience/master/data/unscaled_wdbc.csv") |>
  mutate(Class = as_factor(Class)) |>
  select(Class, Area, Smoothness)
data.unscaled


Melihat data yang tidak diskalakan dan tidak terpusat di atas, Anda dapat melihat bahwa perbedaan antara nilai untuk pengukuran area jauh lebih besar daripada untuk kehalusan. Apakah ini akan memengaruhi prediksi? Untuk mengetahuinya, kami akan membuat plot pencar dari dua prediktor ini (diwarnai oleh diagnosis) untuk data tidak standar yang baru saja kami muat, dan versi standar dari data yang sama. Tapi pertama-tama, kita perlu membakukan kumpulan data unscaled_cancer dengan model rapi.

uc_recipe <- recipe(Class ~ ., data = data.unscaled)
print(uc_recipe)
## Recipe
## 
## Inputs:
## 
##       role #variables
##    outcome          1
##  predictor          2


tambahkan langkah penskalaan (step_scale) dan pemusatan (step_center) untuk semua prediktor sehingga masing-masing memiliki rata-rata 0 dan standar deviasi 1. Perhatikan bahwa cleanverse sebenarnya menyediakan step_normalize, yang melakukan pemusatan dan penskalaan dalam satu langkah resep ; dalam buku ini kita akan memisahkan step_scale dan step_center untuk menekankan secara konseptual bahwa ada dua langkah yang terjadi. Fungsi persiapan menyelesaikan resep dengan menggunakan data (di sini, unscaled_cancer) untuk menghitung apa pun yang diperlukan untuk menjalankan resep (dalam hal ini, rata-rata kolom dan simpangan baku)

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]

Ketika kita ingin menambahkan langkah menuju ke recipe, kita harus menentukan kolom mana yang ingin kita tambahkan. Di sini kita menggunakan fungsi all_predictors() untuk menentukan bahwa setiap langkah harus diterapkan ke semua variabel prediktor. Namun, ada juga argumen serta sintaks lain yang dapat digunakan dan memiliki fungsi sebagai berikut: 1. all_nominal() dan all_numeric(): tentukan semua variabel kategori atau semua numerik
2. all_predictors() dan all_outcomes(): tentukan semua prediktor atau semua variabel target
3. Area, Smoothness: tentukan variabel Area dan Smoothness
4. Class: tentukan semuanya kecuali variabel Class
Anda dapat menemukan set lengkap semua langkah dan fungsi pemilihan variabel di halaman referensi resep.

Pada langkah sebelumnya, kita telah menghitung statistik data dengan input data ke recipe. Tetapi datanya nya belum terskala dan terpusat. Untuk benar-benar menskalakan dan memusatkan datanya, kita gunakan fungsi bake()

scaled_cancer <- bake(uc_recipe, data.unscaled)
scaled_cancer

Balancing


Masalah potensial lain dalam kumpulan data untuk pengklasifikasi adalah ketidakseimbangan kelas, yaitu ketika satu label jauh lebih umum daripada yang lain. Karena saat melakukan KNN oitenggunakan label titik terdekat untuk memprediksi label titik baru, jika ada lebih banyak titik data dengan satu label secara keseluruhan, algoritme lebih cenderung memilih label itu secara umum (bahkan jika “pola” dari data menunjukkan sebaliknya).

rare_cancer <- bind_rows(
      filter(data.cancer, Class == "B"),
      data.cancer |> 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("brown1", "lightgreen")) +
  theme(text = element_text(size = 12))

rare_plot


Dalam kode berikut ini, tujuannya sama untuk balance data. Tapi kali ini kita akan melakukan balance data dengan melakukan oversampling Class nya. Disini kita akan menggunakan library themis dalam menggunakan fungsi step_upsample.

library(themis)
## Warning: package 'themis' was built under R version 4.1.2
## Registered S3 methods overwritten by 'themis':
##   method                  from   
##   bake.step_downsample    recipes
##   bake.step_upsample      recipes
##   prep.step_downsample    recipes
##   prep.step_upsample      recipes
##   tidy.step_downsample    recipes
##   tidy.step_upsample      recipes
##   tunable.step_downsample recipes
##   tunable.step_upsample   recipes
## 
## Attaching package: 'themis'
## The following objects are masked from 'package:recipes':
## 
##     step_downsample, step_upsample
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]
upsampled_cancer <- bake(ups_recipe, rare_cancer)

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


Dan seperti yang bisa kita lihat, Class dari M dan B telah seimbang.

Putting it together in a workflow

Library tidymodels juga menyediakan workflow. Kali ini kita akan melakukan analisis dengan langkah yang tidak perlu kode yang banyak. Disini kita akan menggunakan dataset 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_cancer <- read_csv("https://raw.githubusercontent.com/UBC-DSCI/introduction-to-datascience/master/data/unscaled_wdbc.csv") |>
  mutate(Class = as_factor(Class))
## Rows: 569 Columns: 12
## -- Column specification --------------------------------------------------------
## Delimiter: ","
## chr  (1): Class
## dbl (11): ID, Radius, Texture, Perimeter, Area, Smoothness, Compactness, Con...
## 
## i Use `spec()` to retrieve the full column specification for this data.
## i Specify the column types or set `show_col_types = FALSE` to quiet this message.
# 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_cancer) |>
  step_scale(all_predictors()) |>
  step_center(all_predictors())


Sekarang kita akan menempatkan langkah-langkah ini dalam alur kerja menggunakan fungsi add_recipe dan add_model, dan terakhir kita akan menggunakan fungsi fit untuk menjalankan seluruh alur kerja pada data unscaled_cancer. Perhatikan perbedaan lain dari sebelumnya di sini:

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

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
new_observation <- tibble(Area = c(500, 1500), Smoothness = c(0.075, 0.1))
prediction <- predict(knn_fit, new_observation)

prediction


DAri hasil di atas, kita dapat melihat hasil klasifikasi memprediksi bahwa pengamatan pertama itu jinak B sedangkan kedua ganas M.


Library tidymodels juga menyediakan workflow. Kali ini kita akan melakukan analisis dengan langkah yang tidak perlu kode yang banyak. Disini kita akan menggunakan

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

# use the fit workflow to make predictions 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_cancer, 
             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("brown1", "lightgreen")) +
  theme(text = element_text(size = 12))

wkflw_plot