Introduction to Data Science
TUGAS 1
Email          : calvin.riswandi@student.matanauniversity.ac.id
RPubs         : https://rpubs.com/Calvinriswandy/
Jurusan      : Statistika
Address     : ARA Center, Matana University Tower
             Jl. CBD Barat Kav, RT.1, Curug Sangereng, Kelapa Dua, Tangerang, Banten 15810.
Latar Belakang Data
jadi pada chapter ini kita akan lebih fokus untuk menjawab persoalan mengenai pertanyaan prediksi dan kita akan fokus kepada pengklasifikasian.
Import Data
library(tidyverse)## Warning: package 'tidyverse' was built under R version 4.1.2
## -- Attaching packages --------------------------------------- tidyverse 1.3.1 --
## v ggplot2 3.3.5 v purrr 0.3.4
## v tibble 3.1.4 v dplyr 1.0.7
## v tidyr 1.2.0 v stringr 1.4.0
## v readr 2.0.1 v forcats 0.5.1
## Warning: package 'tidyr' was built under R version 4.1.2
## -- Conflicts ------------------------------------------ tidyverse_conflicts() --
## x dplyr::filter() masks stats::filter()
## x dplyr::lag() masks stats::lag()
pacman ::p_load(readxl, writexl)
Cancer <- read.csv("C:/Users/5/Documents/Semester2/Input/wdbc.csv")
CancerData yang diperoleh merupakan Tumor Payudara yang dapat didiagnosis dengan melakukan biospi. Jadi, berdasarkan gambar digital yang dikumpulkan dari sampel berikut, ada 10 variabel berbeda yang diukur melalui inti sel dan ditentukan rata2 untuk setiap variabel di seluruh inti dicatat.
Penjelasan mengenai data penyakit Cancer
berikut adalah cara untuk mempermudah dalam memeriksa data saat data tersebut memiliki kolom yaitu dengan menggunakan fungsi glimpse.
glimpse(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~
Lalu karena kita akan bekerja menggunakan kelas sebagai variabel kategorikal, maka kita menggubahnya menjadi faktor menggunakan fungsi as_factor.
Cancer <- Cancer |>
mutate(Class = as_factor(Class))
glimpse(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~
Pada Faktor ada yang disebut Tingkatansehingga bisa di anggap sebagai kategori. Kita dapat mengverivikasi level dengan menggunakan fungsi levels.
Cancer |>
pull(Class) |>
levels()## [1] "M" "B"
Disini kita bisa melihat 2 macam kategori level, yaitu M yang berarti ganas dan B yang berarti jinak. Jadi kita menggunakan fungsi pull untuk mengekstrak satu kolom dan dilanjutkan ke fungsi level untuk melihat kategori kelas.
Mengeksplor data
Di bawah ini kami menggunakan fungsi group_by, meringkas dan n untuk menemukan jumlah dan persentase pengamatan tumor jinak dan ganas dalam kumpulan data. Fungsi n dalam ringkasan, ketika dipasangkan dengan group_by, menghitung jumlah pengamatan di setiap grup Kelas. Bisa diketahui bahwa kita menemukan 357 (63%) tumor jinak dan 212 (37%) pengamatan tumor ganas.
num_obs <- nrow(Cancer)
Cancer |>
group_by(Class) |>
summarize(
count = n(),
percentage = n() / num_obs * 100
)Berikut ada visualisasi menggunakan Scatter plot.
perim_concav <- 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("Green", "Blue")) +
theme(text = element_text(size = 12))
perim_concavKlasifikasi dengan k-Nearest Neighbors
Untuk memprediksi observasi baru pada sebuah penelitian, kita perlu algoritma untuk melakukan klasifikasi. Laku kali ini kita akan menggunakan algoritma k-Nearest Neighbors. K adalah angka yang harus kita pilih.
Jarak Antar Titik
Untuk mencari k-Nearest Neighbors pada suatu observasi, kita harus menentukan jarak observasi baru dengan yang lama. Nanti nilai Knya akan dipilih berdasarkan jarak terdekat dengan objek observasi.
new_obs_Perimeter <- 0
new_obs_Concavity <- 3.5
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:10)yang di eksplor lebih dari 2 variabel
kadang kita memerlukan 2 atau lebih data untuk mencari informasi dari data. Contohnya pada data ini kita akan menggunakan variabel perimeter, concavity, symetry.
new_obs_Perimeter <- 0
new_obs_Concavity <- 3.5
new_obs_Symmetry <- 1
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:10)k-Nearest Neighbors menggunakan tidymodels
pada k-Nearest Neighbors terkadang kita kesulitan ada mendapat masalah saat ingin mengendaikan kelas lebih dari 2 variabel. Dengan menggunakan tidymodels dapat membantu kita untuk membuat dan menggunakan model untuk mengklasifikasi data. Fungsi ini membuat kode lebih akurat dan simpel.
library(tidymodels)## Warning: package 'tidymodels' was built under R version 4.1.2
## Registered S3 method overwritten by 'tune':
## method from
## required_pkgs.model_spec parsnip
## -- Attaching packages -------------------------------------- tidymodels 0.1.4 --
## v broom 0.7.9 v rsample 0.1.1
## v dials 0.1.0 v tune 0.1.6
## v infer 1.0.0 v workflows 0.2.4
## v modeldata 0.1.1 v workflowsets 0.1.0
## v parsnip 0.1.7 v yardstick 0.0.9
## v recipes 0.1.17
## Warning: package 'dials' was built under R version 4.1.2
## Warning: package 'infer' was built under R version 4.1.2
## Warning: package 'modeldata' was built under R version 4.1.2
## Warning: package 'parsnip' was built under R version 4.1.2
## Warning: package 'recipes' was built under R version 4.1.2
## Warning: package 'rsample' was built under R version 4.1.2
## Warning: package 'tune' was built under R version 4.1.2
## Warning: package 'workflows' was built under R version 4.1.2
## Warning: package 'workflowsets' was built under R version 4.1.2
## Warning: package 'yardstick' was built under R version 4.1.2
## -- Conflicts ----------------------------------------- tidymodels_conflicts() --
## x scales::discard() masks purrr::discard()
## x dplyr::filter() masks stats::filter()
## x recipes::fixed() masks stringr::fixed()
## x dplyr::lag() masks stats::lag()
## x yardstick::spec() masks readr::spec()
## x recipes::step() masks stats::step()
## * Learn how to get started at https://www.tidymodels.org/start/
cancer_train <- Cancer |>
select(Class, Perimeter, Concavity)
cancer_trainlalu kita akan membuat spesifikasi algoritmanya dengan menggunakan fungsi nearest_neighbor dengan K=5 neighbor.
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
agar sesuai dengan data yang kita miliki, kita perlu membuat spesifikasi modelnya dan data menggunakan fit. Lalu, kita juga perlu menentukan variabel yang digunakan sebagai prediktor menggunakan fungsi Class sebagai target dan perimeter dan concavity sebagai prediktor.
knn_fit <- knn_spec |>
fit(Class ~ Perimeter + Concavity, data = cancer_train)lalu kita bisa menggunakan cara berikut untuk mencari target variabel kecuali Class. Dan kita dapat memilih prediktor dengan simbol + dan jika ingin memilih semua menjadi prediktor menggunakan ..
knn_fit <- knn_spec |>
fit(Class ~ ., data = cancer_train)
knn_fit## parsnip model object
##
## Fit time: 20ms
##
## 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
Selanjutnya barulah kita bisa menggunakan fungsi predict
new_obs <- tibble(Perimeter = 0, Concavity = 3.5)
predict(knn_fit, new_obs)saat menjalankan K-nearest neighbors secara manual, hasilnya akan menjadi malignant atau M. Kita akan berpikir bahwa malignant adalah hasil dari pengamatan ini.Namun, jawaban kita tidak bisa langsung mengambil kesimpulan karena, prediksi belum tentu benar. tetapi, kita bisa menghitung tingkat keakuratan dari prediksi kita.
Pemusatan dan Skala
Ketika menggunakan k-Nearest Neighbors skala variabel itu penting. Karena dalam mengklasifikasi kelas suatu objekyang kita prediksi, jarak observasi sangat berdampak. Saat melakukan pemusatan dan skala data yang harus kita lakukan adalah mecari rata-rata variabel pada data dan standar deviasi sehingga data kita dapat dikatakan memenuhi standar dan variabel.
unscaled_cancer <- read_csv("C:/Users/5/Documents/Semester2/Input/unscaled_wdbc.csv") |>
mutate(Class = as_factor(Class)) |>
select(Class, Area, Smoothness)## 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.
unscaled_cancerterdapat perbedaan antara nilai area lebih besar dari nilai smoothness. Untuk mengetahui pengaruhnya terhadap hasil prediksi, maka kita harus membuat scatter plot dari dua prediktor.
uc_recipe <- recipe(Class ~ ., data = unscaled_cancer)
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]
rare_cancer <- bind_rows(
filter(Cancer, Class == "B"),
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("orange2", "steelblue2")) +
theme(text = element_text(size = 12))
rare_plot jika kita menggunakan nilai K = 7 dan hanya dengan 3 pengamatan Tumor ganas. hasil klasifikasi akan selalu jinak tidak peduli dengan nilai cekung dan perimeter. Mengapa demikian? karena hasil sampel yang menunjukan tumor jinak ada 4 sampel, sehingga di ambil yang terbanyak.
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())Menggunakan workflow
Dalam paket tidymodels ada yang namanya workflow yang berfungsi untuk merantai bersama sebuah langkah analisis data tanpa banyak kode yang diperlukan untuk proses klasifikasi datanya.
unscaled_cancer <- read_csv("C:/Users/5/Documents/Semester2/Input/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.
# membuat KNN model
knn_spec <- nearest_neighbor(weight_func = "rectangular", neighbors = 7) |>
set_engine("kknn") |>
set_mode("classification")uc_recipe <- recipe(Class ~ Area + Smoothness, data = unscaled_cancer) |>
step_scale(all_predictors()) |>
step_center(all_predictors())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)
predictionSekarang kita akan melakukan analisis dengan langkah yang tidak memerlukan kode yang banyak.
# 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("orange2", "steelblue2")) +
theme(text = element_text(size = 12))
wkflw_plot