You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
686 lines
31 KiB
686 lines
31 KiB
{
|
|
"cells": [
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"## Membangun Model Regresi Logistik - Pelajaran 4\n",
|
|
"\n",
|
|
"\n",
|
|
"\n",
|
|
"#### **[Kuis sebelum pelajaran](https://gray-sand-07a10f403.1.azurestaticapps.net/quiz/15/)**\n",
|
|
"\n",
|
|
"#### Pendahuluan\n",
|
|
"\n",
|
|
"Dalam pelajaran terakhir tentang Regresi ini, salah satu teknik dasar *klasik* dalam pembelajaran mesin, kita akan mempelajari Regresi Logistik. Anda dapat menggunakan teknik ini untuk menemukan pola guna memprediksi kategori biner. Apakah permen ini cokelat atau bukan? Apakah penyakit ini menular atau tidak? Apakah pelanggan ini akan memilih produk ini atau tidak?\n",
|
|
"\n",
|
|
"Dalam pelajaran ini, Anda akan mempelajari:\n",
|
|
"\n",
|
|
"- Teknik-teknik untuk regresi logistik\n",
|
|
"\n",
|
|
"✅ Perdalam pemahaman Anda tentang cara bekerja dengan jenis regresi ini di [modul pembelajaran ini](https://learn.microsoft.com/training/modules/introduction-classification-models/?WT.mc_id=academic-77952-leestott)\n",
|
|
"\n",
|
|
"## Prasyarat\n",
|
|
"\n",
|
|
"Setelah bekerja dengan data labu, kita sekarang cukup familiar untuk menyadari bahwa ada satu kategori biner yang dapat kita gunakan: `Color`.\n",
|
|
"\n",
|
|
"Mari kita bangun model regresi logistik untuk memprediksi, berdasarkan beberapa variabel, *warna apa yang kemungkinan dimiliki oleh sebuah labu* (oranye 🎃 atau putih 👻).\n",
|
|
"\n",
|
|
"> Mengapa kita membahas klasifikasi biner dalam kelompok pelajaran tentang regresi? Hanya untuk kemudahan linguistik, karena regresi logistik sebenarnya adalah [metode klasifikasi](https://scikit-learn.org/stable/modules/linear_model.html#logistic-regression), meskipun berbasis linear. Pelajari cara lain untuk mengklasifikasikan data di kelompok pelajaran berikutnya.\n",
|
|
"\n",
|
|
"Untuk pelajaran ini, kita memerlukan paket-paket berikut:\n",
|
|
"\n",
|
|
"- `tidyverse`: [tidyverse](https://www.tidyverse.org/) adalah [koleksi paket R](https://www.tidyverse.org/packages) yang dirancang untuk membuat ilmu data lebih cepat, mudah, dan menyenangkan!\n",
|
|
"\n",
|
|
"- `tidymodels`: Kerangka kerja [tidymodels](https://www.tidymodels.org/) adalah [koleksi paket](https://www.tidymodels.org/packages/) untuk pemodelan dan pembelajaran mesin.\n",
|
|
"\n",
|
|
"- `janitor`: Paket [janitor](https://github.com/sfirke/janitor) menyediakan alat sederhana untuk memeriksa dan membersihkan data yang kotor.\n",
|
|
"\n",
|
|
"- `ggbeeswarm`: Paket [ggbeeswarm](https://github.com/eclarke/ggbeeswarm) menyediakan metode untuk membuat plot gaya beeswarm menggunakan ggplot2.\n",
|
|
"\n",
|
|
"Anda dapat menginstalnya dengan perintah berikut:\n",
|
|
"\n",
|
|
"`install.packages(c(\"tidyverse\", \"tidymodels\", \"janitor\", \"ggbeeswarm\"))`\n",
|
|
"\n",
|
|
"Sebagai alternatif, skrip di bawah ini akan memeriksa apakah Anda memiliki paket-paket yang diperlukan untuk menyelesaikan modul ini dan menginstalnya untuk Anda jika belum tersedia.\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {
|
|
"vscode": {
|
|
"languageId": "r"
|
|
}
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"suppressWarnings(if (!require(\"pacman\"))install.packages(\"pacman\"))\n",
|
|
"\n",
|
|
"pacman::p_load(tidyverse, tidymodels, janitor, ggbeeswarm)\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"## **Tentukan pertanyaan**\n",
|
|
"\n",
|
|
"Untuk tujuan kita, kita akan menyatakannya sebagai biner: 'Putih' atau 'Bukan Putih'. Ada juga kategori 'bergaris' dalam dataset kita, tetapi jumlahnya sangat sedikit, jadi kita tidak akan menggunakannya. Kategori ini juga akan hilang setelah kita menghapus nilai null dari dataset.\n",
|
|
"\n",
|
|
"> 🎃 Fakta menarik, kadang-kadang kita menyebut labu putih sebagai labu 'hantu'. Labu ini tidak mudah diukir, sehingga tidak sepopuler labu oranye, tetapi tampilannya keren! Jadi kita juga bisa merumuskan ulang pertanyaan kita sebagai: 'Hantu' atau 'Bukan Hantu'. 👻\n",
|
|
"\n",
|
|
"## **Tentang regresi logistik**\n",
|
|
"\n",
|
|
"Regresi logistik berbeda dari regresi linier, yang telah Anda pelajari sebelumnya, dalam beberapa cara penting.\n",
|
|
"\n",
|
|
"#### **Klasifikasi biner**\n",
|
|
"\n",
|
|
"Regresi logistik tidak menawarkan fitur yang sama seperti regresi linier. Regresi logistik memberikan prediksi tentang `kategori biner` (\"oranye atau bukan oranye\"), sedangkan regresi linier mampu memprediksi `nilai kontinu`, misalnya berdasarkan asal labu dan waktu panen, *berapa harga labu akan naik*.\n",
|
|
"\n",
|
|
"\n",
|
|
"\n",
|
|
"### Klasifikasi lainnya\n",
|
|
"\n",
|
|
"Ada jenis regresi logistik lainnya, termasuk multinomial dan ordinal:\n",
|
|
"\n",
|
|
"- **Multinomial**, yang melibatkan lebih dari satu kategori - \"Oranye, Putih, dan Bergaris\".\n",
|
|
"\n",
|
|
"- **Ordinal**, yang melibatkan kategori yang terurut, berguna jika kita ingin mengurutkan hasil secara logis, seperti labu kita yang diurutkan berdasarkan sejumlah ukuran tertentu (mini, sm, med, lg, xl, xxl).\n",
|
|
"\n",
|
|
"\n",
|
|
"\n",
|
|
"#### **Variabel TIDAK harus berkorelasi**\n",
|
|
"\n",
|
|
"Ingat bagaimana regresi linier bekerja lebih baik dengan variabel yang lebih berkorelasi? Regresi logistik adalah kebalikannya - variabel tidak harus selaras. Ini cocok untuk data ini yang memiliki korelasi yang agak lemah.\n",
|
|
"\n",
|
|
"#### **Anda membutuhkan banyak data yang bersih**\n",
|
|
"\n",
|
|
"Regresi logistik akan memberikan hasil yang lebih akurat jika Anda menggunakan lebih banyak data; dataset kecil kita tidak optimal untuk tugas ini, jadi ingatlah hal itu.\n",
|
|
"\n",
|
|
"✅ Pikirkan jenis data yang cocok untuk regresi logistik\n",
|
|
"\n",
|
|
"## Latihan - rapikan data\n",
|
|
"\n",
|
|
"Pertama, bersihkan data sedikit, hapus nilai null, dan pilih hanya beberapa kolom:\n",
|
|
"\n",
|
|
"1. Tambahkan kode berikut:\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {
|
|
"vscode": {
|
|
"languageId": "r"
|
|
}
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"# Load the core tidyverse packages\n",
|
|
"library(tidyverse)\n",
|
|
"\n",
|
|
"# Import the data and clean column names\n",
|
|
"pumpkins <- read_csv(file = \"https://raw.githubusercontent.com/microsoft/ML-For-Beginners/main/2-Regression/data/US-pumpkins.csv\") %>% \n",
|
|
" clean_names()\n",
|
|
"\n",
|
|
"# Select desired columns\n",
|
|
"pumpkins_select <- pumpkins %>% \n",
|
|
" select(c(city_name, package, variety, origin, item_size, color)) \n",
|
|
"\n",
|
|
"# Drop rows containing missing values and encode color as factor (category)\n",
|
|
"pumpkins_select <- pumpkins_select %>% \n",
|
|
" drop_na() %>% \n",
|
|
" mutate(color = factor(color))\n",
|
|
"\n",
|
|
"# View the first few rows\n",
|
|
"pumpkins_select %>% \n",
|
|
" slice_head(n = 5)\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"Anda selalu dapat melihat sekilas dataframe baru Anda dengan menggunakan fungsi [*glimpse()*](https://pillar.r-lib.org/reference/glimpse.html) seperti di bawah ini:\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {
|
|
"vscode": {
|
|
"languageId": "r"
|
|
}
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"pumpkins_select %>% \n",
|
|
" glimpse()\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"Mari kita pastikan bahwa kita benar-benar akan mengerjakan masalah klasifikasi biner:\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {
|
|
"vscode": {
|
|
"languageId": "r"
|
|
}
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"# Subset distinct observations in outcome column\n",
|
|
"pumpkins_select %>% \n",
|
|
" distinct(color)\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"### Visualisasi - plot kategorikal\n",
|
|
"Saat ini Anda telah memuat kembali data labu dan membersihkannya sehingga menghasilkan dataset yang berisi beberapa variabel, termasuk Warna. Mari kita visualisasikan dataframe di notebook menggunakan pustaka ggplot.\n",
|
|
"\n",
|
|
"Pustaka ggplot menawarkan beberapa cara menarik untuk memvisualisasikan data Anda. Sebagai contoh, Anda dapat membandingkan distribusi data untuk setiap Varietas dan Warna dalam plot kategorikal.\n",
|
|
"\n",
|
|
"1. Buat plot seperti itu dengan menggunakan fungsi geombar, menggunakan data labu kita, dan menentukan pemetaan warna untuk setiap kategori labu (oranye atau putih):\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {
|
|
"vscode": {
|
|
"languageId": "python"
|
|
}
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"# Specify colors for each value of the hue variable\n",
|
|
"palette <- c(ORANGE = \"orange\", WHITE = \"wheat\")\n",
|
|
"\n",
|
|
"# Create the bar plot\n",
|
|
"ggplot(pumpkins_select, aes(y = variety, fill = color)) +\n",
|
|
" geom_bar(position = \"dodge\") +\n",
|
|
" scale_fill_manual(values = palette) +\n",
|
|
" labs(y = \"Variety\", fill = \"Color\") +\n",
|
|
" theme_minimal()"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"Dengan mengamati data, Anda dapat melihat bagaimana data Warna berhubungan dengan Variasi.\n",
|
|
"\n",
|
|
"✅ Berdasarkan plot kategorikal ini, eksplorasi menarik apa yang dapat Anda bayangkan?\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"### Pra-pemrosesan Data: Pengkodean Fitur\n",
|
|
"\n",
|
|
"Dataset labu kita berisi nilai string untuk semua kolomnya. Bekerja dengan data kategorikal memang intuitif bagi manusia, tetapi tidak untuk mesin. Algoritma pembelajaran mesin bekerja lebih baik dengan angka. Itulah mengapa pengkodean adalah langkah yang sangat penting dalam fase pra-pemrosesan data, karena memungkinkan kita mengubah data kategorikal menjadi data numerik tanpa kehilangan informasi apa pun. Pengkodean yang baik akan membantu membangun model yang baik.\n",
|
|
"\n",
|
|
"Untuk pengkodean fitur, terdapat dua jenis pengkode utama:\n",
|
|
"\n",
|
|
"1. **Ordinal encoder**: Cocok untuk variabel ordinal, yaitu variabel kategorikal di mana datanya memiliki urutan logis, seperti kolom `item_size` dalam dataset kita. Pengkode ini membuat pemetaan sehingga setiap kategori direpresentasikan oleh sebuah angka, yang merupakan urutan kategori dalam kolom tersebut.\n",
|
|
"\n",
|
|
"2. **Categorical encoder**: Cocok untuk variabel nominal, yaitu variabel kategorikal di mana datanya tidak memiliki urutan logis, seperti semua fitur selain `item_size` dalam dataset kita. Ini menggunakan pengkodean one-hot, yang berarti setiap kategori direpresentasikan oleh kolom biner: variabel yang dikodekan bernilai 1 jika labu tersebut termasuk dalam Varietas tertentu dan 0 jika tidak.\n",
|
|
"\n",
|
|
"Tidymodels menyediakan satu paket keren lainnya: [recipes](https://recipes.tidymodels.org/) - sebuah paket untuk pra-pemrosesan data. Kita akan mendefinisikan sebuah `recipe` yang menentukan bahwa semua kolom prediktor harus dikodekan menjadi serangkaian bilangan bulat, kemudian `prep` untuk memperkirakan kuantitas dan statistik yang diperlukan oleh operasi apa pun, dan akhirnya `bake` untuk menerapkan perhitungan tersebut pada data baru.\n",
|
|
"\n",
|
|
"> Biasanya, recipes sering digunakan sebagai pra-pemroses untuk pemodelan, di mana ia mendefinisikan langkah-langkah apa yang harus diterapkan pada sebuah dataset agar siap untuk pemodelan. Dalam kasus tersebut, **sangat disarankan** untuk menggunakan `workflow()` daripada memperkirakan recipe secara manual menggunakan prep dan bake. Kita akan melihat semua ini sebentar lagi.\n",
|
|
">\n",
|
|
"> Namun, untuk saat ini, kita menggunakan recipes + prep + bake untuk menentukan langkah-langkah apa yang harus diterapkan pada sebuah dataset agar siap untuk analisis data, dan kemudian mengekstrak data yang telah diproses dengan langkah-langkah tersebut.\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {
|
|
"vscode": {
|
|
"languageId": "r"
|
|
}
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"# Preprocess and extract data to allow some data analysis\n",
|
|
"baked_pumpkins <- recipe(color ~ ., data = pumpkins_select) %>%\n",
|
|
" # Define ordering for item_size column\n",
|
|
" step_mutate(item_size = ordered(item_size, levels = c('sml', 'med', 'med-lge', 'lge', 'xlge', 'jbo', 'exjbo'))) %>%\n",
|
|
" # Convert factors to numbers using the order defined above (Ordinal encoding)\n",
|
|
" step_integer(item_size, zero_based = F) %>%\n",
|
|
" # Encode all other predictors using one hot encoding\n",
|
|
" step_dummy(all_nominal(), -all_outcomes(), one_hot = TRUE) %>%\n",
|
|
" prep(data = pumpkin_select) %>%\n",
|
|
" bake(new_data = NULL)\n",
|
|
"\n",
|
|
"# Display the first few rows of preprocessed data\n",
|
|
"baked_pumpkins %>% \n",
|
|
" slice_head(n = 5)\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"✅ Apa keuntungan menggunakan ordinal encoder untuk kolom Item Size?\n",
|
|
"\n",
|
|
"### Menganalisis hubungan antar variabel\n",
|
|
"\n",
|
|
"Setelah kita melakukan pra-pemrosesan data, kita dapat menganalisis hubungan antara fitur-fitur dan label untuk mendapatkan gambaran seberapa baik model dapat memprediksi label berdasarkan fitur-fitur tersebut. Cara terbaik untuk melakukan analisis semacam ini adalah dengan memvisualisasikan data. \n",
|
|
"Kita akan kembali menggunakan fungsi ggplot geom_boxplot_ untuk memvisualisasikan hubungan antara Item Size, Variety, dan Color dalam plot kategorikal. Untuk mempermudah visualisasi data, kita akan menggunakan kolom Item Size yang telah dienkode dan kolom Variety yang belum dienkode.\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {
|
|
"vscode": {
|
|
"languageId": "r"
|
|
}
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"# Define the color palette\n",
|
|
"palette <- c(ORANGE = \"orange\", WHITE = \"wheat\")\n",
|
|
"\n",
|
|
"# We need the encoded Item Size column to use it as the x-axis values in the plot\n",
|
|
"pumpkins_select_plot<-pumpkins_select\n",
|
|
"pumpkins_select_plot$item_size <- baked_pumpkins$item_size\n",
|
|
"\n",
|
|
"# Create the grouped box plot\n",
|
|
"ggplot(pumpkins_select_plot, aes(x = `item_size`, y = color, fill = color)) +\n",
|
|
" geom_boxplot() +\n",
|
|
" facet_grid(variety ~ ., scales = \"free_x\") +\n",
|
|
" scale_fill_manual(values = palette) +\n",
|
|
" labs(x = \"Item Size\", y = \"\") +\n",
|
|
" theme_minimal() +\n",
|
|
" theme(strip.text = element_text(size = 12)) +\n",
|
|
" theme(axis.text.x = element_text(size = 10)) +\n",
|
|
" theme(axis.title.x = element_text(size = 12)) +\n",
|
|
" theme(axis.title.y = element_blank()) +\n",
|
|
" theme(legend.position = \"bottom\") +\n",
|
|
" guides(fill = guide_legend(title = \"Color\")) +\n",
|
|
" theme(panel.spacing = unit(0.5, \"lines\"))+\n",
|
|
" theme(strip.text.y = element_text(size = 4, hjust = 0)) \n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"#### Gunakan plot swarm\n",
|
|
"\n",
|
|
"Karena Color adalah kategori biner (Putih atau Tidak), maka membutuhkan '[pendekatan khusus](https://github.com/rstudio/cheatsheets/blob/main/data-visualization.pdf)' untuk visualisasi.\n",
|
|
"\n",
|
|
"Cobalah `plot swarm` untuk menunjukkan distribusi warna berdasarkan item_size.\n",
|
|
"\n",
|
|
"Kita akan menggunakan [paket ggbeeswarm](https://github.com/eclarke/ggbeeswarm) yang menyediakan metode untuk membuat plot gaya beeswarm menggunakan ggplot2. Plot beeswarm adalah cara memplot titik-titik yang biasanya saling tumpang tindih sehingga mereka jatuh bersebelahan satu sama lain.\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {
|
|
"vscode": {
|
|
"languageId": "r"
|
|
}
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"# Create beeswarm plots of color and item_size\n",
|
|
"baked_pumpkins %>% \n",
|
|
" mutate(color = factor(color)) %>% \n",
|
|
" ggplot(mapping = aes(x = color, y = item_size, color = color)) +\n",
|
|
" geom_quasirandom() +\n",
|
|
" scale_color_brewer(palette = \"Dark2\", direction = -1) +\n",
|
|
" theme(legend.position = \"none\")\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"Sekarang kita memiliki gambaran tentang hubungan antara kategori biner warna dan kelompok ukuran yang lebih besar, mari kita eksplorasi regresi logistik untuk menentukan kemungkinan warna sebuah labu.\n",
|
|
"\n",
|
|
"## Bangun model Anda\n",
|
|
"\n",
|
|
"Pilih variabel yang ingin Anda gunakan dalam model klasifikasi dan bagi data menjadi set pelatihan dan pengujian. [rsample](https://rsample.tidymodels.org/), sebuah paket dalam Tidymodels, menyediakan infrastruktur untuk pembagian data dan resampling yang efisien:\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {
|
|
"vscode": {
|
|
"languageId": "r"
|
|
}
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"# Split data into 80% for training and 20% for testing\n",
|
|
"set.seed(2056)\n",
|
|
"pumpkins_split <- pumpkins_select %>% \n",
|
|
" initial_split(prop = 0.8)\n",
|
|
"\n",
|
|
"# Extract the data in each split\n",
|
|
"pumpkins_train <- training(pumpkins_split)\n",
|
|
"pumpkins_test <- testing(pumpkins_split)\n",
|
|
"\n",
|
|
"# Print out the first 5 rows of the training set\n",
|
|
"pumpkins_train %>% \n",
|
|
" slice_head(n = 5)\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"🙌 Kita sekarang siap untuk melatih model dengan mencocokkan fitur pelatihan ke label pelatihan (warna).\n",
|
|
"\n",
|
|
"Kita akan mulai dengan membuat resep yang menentukan langkah-langkah praproses yang harus dilakukan pada data kita agar siap untuk pemodelan, yaitu: mengubah variabel kategorikal menjadi serangkaian bilangan bulat. Sama seperti `baked_pumpkins`, kita membuat `pumpkins_recipe` tetapi tidak melakukan `prep` dan `bake` karena ini akan digabungkan ke dalam sebuah alur kerja, yang akan Anda lihat dalam beberapa langkah ke depan.\n",
|
|
"\n",
|
|
"Ada cukup banyak cara untuk menentukan model regresi logistik di Tidymodels. Lihat `?logistic_reg()` Untuk saat ini, kita akan menentukan model regresi logistik melalui mesin default `stats::glm()`.\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {
|
|
"vscode": {
|
|
"languageId": "r"
|
|
}
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"# Create a recipe that specifies preprocessing steps for modelling\n",
|
|
"pumpkins_recipe <- recipe(color ~ ., data = pumpkins_train) %>% \n",
|
|
" step_mutate(item_size = ordered(item_size, levels = c('sml', 'med', 'med-lge', 'lge', 'xlge', 'jbo', 'exjbo'))) %>%\n",
|
|
" step_integer(item_size, zero_based = F) %>% \n",
|
|
" step_dummy(all_nominal(), -all_outcomes(), one_hot = TRUE)\n",
|
|
"\n",
|
|
"# Create a logistic model specification\n",
|
|
"log_reg <- logistic_reg() %>% \n",
|
|
" set_engine(\"glm\") %>% \n",
|
|
" set_mode(\"classification\")\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"Sekarang kita memiliki resep dan spesifikasi model, kita perlu mencari cara untuk menggabungkan keduanya menjadi sebuah objek yang akan terlebih dahulu memproses data (prep+bake di belakang layar), menyesuaikan model pada data yang telah diproses, dan juga memungkinkan aktivitas pasca-pemrosesan jika diperlukan.\n",
|
|
"\n",
|
|
"Dalam Tidymodels, objek yang praktis ini disebut [`workflow`](https://workflows.tidymodels.org/) dan dengan mudah menyimpan komponen pemodelan Anda.\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {
|
|
"vscode": {
|
|
"languageId": "r"
|
|
}
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"# Bundle modelling components in a workflow\n",
|
|
"log_reg_wf <- workflow() %>% \n",
|
|
" add_recipe(pumpkins_recipe) %>% \n",
|
|
" add_model(log_reg)\n",
|
|
"\n",
|
|
"# Print out the workflow\n",
|
|
"log_reg_wf\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"Setelah alur kerja *ditentukan*, sebuah model dapat `dilatih` menggunakan fungsi [`fit()`](https://tidymodels.github.io/parsnip/reference/fit.html). Alur kerja akan memperkirakan resep dan memproses data sebelum pelatihan, sehingga kita tidak perlu melakukannya secara manual menggunakan prep dan bake.\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {
|
|
"vscode": {
|
|
"languageId": "r"
|
|
}
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"# Train the model\n",
|
|
"wf_fit <- log_reg_wf %>% \n",
|
|
" fit(data = pumpkins_train)\n",
|
|
"\n",
|
|
"# Print the trained workflow\n",
|
|
"wf_fit\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"Model mencetak koefisien yang dipelajari selama pelatihan.\n",
|
|
"\n",
|
|
"Sekarang kita telah melatih model menggunakan data pelatihan, kita dapat membuat prediksi pada data uji menggunakan [parsnip::predict()](https://parsnip.tidymodels.org/reference/predict.model_fit.html). Mari kita mulai dengan menggunakan model untuk memprediksi label untuk set uji kita dan probabilitas untuk setiap label. Ketika probabilitas lebih dari 0.5, kelas prediksi adalah `WHITE`, jika tidak maka `ORANGE`.\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {
|
|
"vscode": {
|
|
"languageId": "r"
|
|
}
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"# Make predictions for color and corresponding probabilities\n",
|
|
"results <- pumpkins_test %>% select(color) %>% \n",
|
|
" bind_cols(wf_fit %>% \n",
|
|
" predict(new_data = pumpkins_test)) %>%\n",
|
|
" bind_cols(wf_fit %>%\n",
|
|
" predict(new_data = pumpkins_test, type = \"prob\"))\n",
|
|
"\n",
|
|
"# Compare predictions\n",
|
|
"results %>% \n",
|
|
" slice_head(n = 10)\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"Sangat bagus! Ini memberikan wawasan lebih tentang cara kerja regresi logistik.\n",
|
|
"\n",
|
|
"### Pemahaman lebih baik melalui matriks kebingungan\n",
|
|
"\n",
|
|
"Membandingkan setiap prediksi dengan nilai \"ground truth\" aktual yang sesuai bukanlah cara yang efisien untuk menentukan seberapa baik model memprediksi. Untungnya, Tidymodels memiliki beberapa trik lagi: [`yardstick`](https://yardstick.tidymodels.org/) - sebuah paket yang digunakan untuk mengukur efektivitas model menggunakan metrik kinerja.\n",
|
|
"\n",
|
|
"Salah satu metrik kinerja yang terkait dengan masalah klasifikasi adalah [`confusion matrix`](https://wikipedia.org/wiki/Confusion_matrix). Matriks kebingungan menggambarkan seberapa baik model klasifikasi bekerja. Matriks kebingungan mencatat berapa banyak contoh di setiap kelas yang diklasifikasikan dengan benar oleh model. Dalam kasus kita, matriks ini akan menunjukkan berapa banyak labu oranye yang diklasifikasikan sebagai oranye dan berapa banyak labu putih yang diklasifikasikan sebagai putih; matriks kebingungan juga menunjukkan berapa banyak yang diklasifikasikan ke kategori **yang salah**.\n",
|
|
"\n",
|
|
"Fungsi [**`conf_mat()`**](https://tidymodels.github.io/yardstick/reference/conf_mat.html) dari yardstick menghitung tabulasi silang antara kelas yang diamati dan yang diprediksi.\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {
|
|
"vscode": {
|
|
"languageId": "r"
|
|
}
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"# Confusion matrix for prediction results\n",
|
|
"conf_mat(data = results, truth = color, estimate = .pred_class)\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"Mari kita interpretasikan matriks kebingungan. Model kita diminta untuk mengklasifikasikan labu ke dalam dua kategori biner, kategori `putih` dan kategori `tidak-putih`.\n",
|
|
"\n",
|
|
"- Jika model Anda memprediksi sebuah labu sebagai putih dan labu tersebut memang termasuk kategori 'putih' dalam kenyataannya, kita menyebutnya sebagai `true positive`, ditunjukkan oleh angka di kiri atas.\n",
|
|
"\n",
|
|
"- Jika model Anda memprediksi sebuah labu sebagai tidak putih dan labu tersebut sebenarnya termasuk kategori 'putih' dalam kenyataannya, kita menyebutnya sebagai `false negative`, ditunjukkan oleh angka di kiri bawah.\n",
|
|
"\n",
|
|
"- Jika model Anda memprediksi sebuah labu sebagai putih dan labu tersebut sebenarnya termasuk kategori 'tidak-putih' dalam kenyataannya, kita menyebutnya sebagai `false positive`, ditunjukkan oleh angka di kanan atas.\n",
|
|
"\n",
|
|
"- Jika model Anda memprediksi sebuah labu sebagai tidak putih dan labu tersebut memang termasuk kategori 'tidak-putih' dalam kenyataannya, kita menyebutnya sebagai `true negative`, ditunjukkan oleh angka di kanan bawah.\n",
|
|
"\n",
|
|
"| Kebenaran |\n",
|
|
"|:---------:|\n",
|
|
"\n",
|
|
"\n",
|
|
"| | | |\n",
|
|
"|---------------|--------|-------|\n",
|
|
"| **Prediksi** | PUTIH | ORANYE |\n",
|
|
"| PUTIH | TP | FP |\n",
|
|
"| ORANYE | FN | TN |\n",
|
|
"\n",
|
|
"Seperti yang mungkin Anda duga, lebih baik memiliki jumlah true positive dan true negative yang lebih besar serta jumlah false positive dan false negative yang lebih kecil, yang menunjukkan bahwa model bekerja lebih baik.\n",
|
|
"\n",
|
|
"Matriks kebingungan sangat berguna karena menghasilkan metrik lain yang dapat membantu kita mengevaluasi kinerja model klasifikasi dengan lebih baik. Mari kita bahas beberapa di antaranya:\n",
|
|
"\n",
|
|
"🎓 Presisi: `TP/(TP + FP)` didefinisikan sebagai proporsi prediksi positif yang benar-benar positif. Juga disebut [nilai prediktif positif](https://en.wikipedia.org/wiki/Positive_predictive_value \"Positive predictive value\").\n",
|
|
"\n",
|
|
"🎓 Recall: `TP/(TP + FN)` didefinisikan sebagai proporsi hasil positif dari jumlah sampel yang benar-benar positif. Juga dikenal sebagai `sensitivitas`.\n",
|
|
"\n",
|
|
"🎓 Spesifisitas: `TN/(TN + FP)` didefinisikan sebagai proporsi hasil negatif dari jumlah sampel yang benar-benar negatif.\n",
|
|
"\n",
|
|
"🎓 Akurasi: `TP + TN/(TP + TN + FP + FN)` Persentase label yang diprediksi dengan benar untuk sebuah sampel.\n",
|
|
"\n",
|
|
"🎓 F Measure: Rata-rata tertimbang dari presisi dan recall, dengan nilai terbaik adalah 1 dan terburuk adalah 0.\n",
|
|
"\n",
|
|
"Mari kita hitung metrik-metrik ini!\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {
|
|
"vscode": {
|
|
"languageId": "r"
|
|
}
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"# Combine metric functions and calculate them all at once\n",
|
|
"eval_metrics <- metric_set(ppv, recall, spec, f_meas, accuracy)\n",
|
|
"eval_metrics(data = results, truth = color, estimate = .pred_class)\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"## Visualisasikan kurva ROC dari model ini\n",
|
|
"\n",
|
|
"Mari kita lakukan satu visualisasi lagi untuk melihat apa yang disebut [`kurva ROC`](https://en.wikipedia.org/wiki/Receiver_operating_characteristic):\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {
|
|
"vscode": {
|
|
"languageId": "r"
|
|
}
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"# Make a roc_curve\n",
|
|
"results %>% \n",
|
|
" roc_curve(color, .pred_ORANGE) %>% \n",
|
|
" autoplot()\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"Kurva ROC sering digunakan untuk melihat output dari sebuah pengklasifikasi dalam hal positif benar vs. positif salah. Kurva ROC biasanya menampilkan `True Positive Rate`/Sensitivitas pada sumbu Y, dan `False Positive Rate`/1-Spesifisitas pada sumbu X. Oleh karena itu, kemiringan kurva dan ruang antara garis tengah dan kurva menjadi penting: Anda menginginkan kurva yang dengan cepat naik dan melewati garis tersebut. Dalam kasus kita, ada positif salah di awal, lalu garisnya naik dan melewati dengan benar.\n",
|
|
"\n",
|
|
"Terakhir, mari gunakan `yardstick::roc_auc()` untuk menghitung Area Under the Curve yang sebenarnya. Salah satu cara untuk menginterpretasikan AUC adalah sebagai probabilitas bahwa model memberi peringkat lebih tinggi pada contoh positif acak dibandingkan dengan contoh negatif acak.\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {
|
|
"vscode": {
|
|
"languageId": "r"
|
|
}
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"# Calculate area under curve\n",
|
|
"results %>% \n",
|
|
" roc_auc(color, .pred_ORANGE)\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"Hasilnya sekitar `0.975`. Mengingat bahwa AUC berkisar dari 0 hingga 1, Anda menginginkan skor yang besar, karena model yang 100% benar dalam prediksinya akan memiliki AUC sebesar 1; dalam hal ini, modelnya *cukup baik*.\n",
|
|
"\n",
|
|
"Dalam pelajaran mendatang tentang klasifikasi, Anda akan belajar cara meningkatkan skor model Anda (seperti menangani data yang tidak seimbang dalam kasus ini).\n",
|
|
"\n",
|
|
"## 🚀Tantangan\n",
|
|
"\n",
|
|
"Masih banyak yang bisa dipelajari tentang regresi logistik! Tetapi cara terbaik untuk belajar adalah dengan bereksperimen. Temukan dataset yang cocok untuk jenis analisis ini dan bangun model dengannya. Apa yang Anda pelajari? tip: coba [Kaggle](https://www.kaggle.com/search?q=logistic+regression+datasets) untuk dataset yang menarik.\n",
|
|
"\n",
|
|
"## Tinjauan & Studi Mandiri\n",
|
|
"\n",
|
|
"Baca beberapa halaman pertama dari [makalah ini dari Stanford](https://web.stanford.edu/~jurafsky/slp3/5.pdf) tentang beberapa penggunaan praktis regresi logistik. Pikirkan tentang tugas-tugas yang lebih cocok untuk salah satu jenis regresi yang telah kita pelajari sejauh ini. Apa yang akan bekerja paling baik?\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"\n---\n\n**Penafian**: \nDokumen ini telah diterjemahkan menggunakan layanan penerjemahan AI [Co-op Translator](https://github.com/Azure/co-op-translator). Meskipun kami berupaya untuk memberikan hasil yang akurat, harap diperhatikan bahwa terjemahan otomatis mungkin mengandung kesalahan atau ketidakakuratan. Dokumen asli dalam bahasa aslinya harus dianggap sebagai sumber yang berwenang. Untuk informasi yang bersifat kritis, disarankan menggunakan jasa penerjemahan manusia profesional. Kami tidak bertanggung jawab atas kesalahpahaman atau penafsiran yang keliru yang timbul dari penggunaan terjemahan ini.\n"
|
|
]
|
|
}
|
|
],
|
|
"metadata": {
|
|
"anaconda-cloud": "",
|
|
"kernelspec": {
|
|
"display_name": "R",
|
|
"langauge": "R",
|
|
"name": "ir"
|
|
},
|
|
"language_info": {
|
|
"codemirror_mode": "r",
|
|
"file_extension": ".r",
|
|
"mimetype": "text/x-r-source",
|
|
"name": "R",
|
|
"pygments_lexer": "r",
|
|
"version": "3.4.1"
|
|
},
|
|
"coopTranslator": {
|
|
"original_hash": "feaf125f481a89c468fa115bf2aed580",
|
|
"translation_date": "2025-09-04T06:58:07+00:00",
|
|
"source_file": "2-Regression/4-Logistic/solution/R/lesson_4-R.ipynb",
|
|
"language_code": "id"
|
|
}
|
|
},
|
|
"nbformat": 4,
|
|
"nbformat_minor": 1
|
|
} |