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.
685 lines
32 KiB
685 lines
32 KiB
{
|
|
"cells": [
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"## Gumawa ng logistic regression model - Aralin 4\n",
|
|
"\n",
|
|
"\n",
|
|
"\n",
|
|
"#### **[Pre-lecture quiz](https://gray-sand-07a10f403.1.azurestaticapps.net/quiz/15/)**\n",
|
|
"\n",
|
|
"#### Panimula\n",
|
|
"\n",
|
|
"Sa huling araling ito tungkol sa Regression, isa sa mga pangunahing *classic* na teknik sa Machine Learning (ML), tatalakayin natin ang Logistic Regression. Ginagamit ang teknik na ito upang matuklasan ang mga pattern para hulaan ang mga binary na kategorya. Ang candy ba na ito ay tsokolate o hindi? Ang sakit ba na ito ay nakakahawa o hindi? Pipiliin ba ng customer na ito ang produktong ito o hindi?\n",
|
|
"\n",
|
|
"Sa araling ito, matututunan mo ang:\n",
|
|
"\n",
|
|
"- Mga teknik para sa logistic regression\n",
|
|
"\n",
|
|
"✅ Palalimin ang iyong kaalaman sa paggamit ng ganitong uri ng regression sa [Learn module](https://learn.microsoft.com/training/modules/introduction-classification-models/?WT.mc_id=academic-77952-leestott)\n",
|
|
"\n",
|
|
"## Prerequisite\n",
|
|
"\n",
|
|
"Matapos magtrabaho gamit ang pumpkin data, sapat na ang ating kaalaman upang mapansin na may isang binary na kategorya na maaari nating pag-aralan: `Color`.\n",
|
|
"\n",
|
|
"Gumawa tayo ng logistic regression model upang mahulaan, batay sa ilang mga variable, *kung anong kulay ang malamang na mayroon ang isang kalabasa* (orange 🎃 o puti 👻).\n",
|
|
"\n",
|
|
"> Bakit natin pinag-uusapan ang binary classification sa isang aralin tungkol sa regression? Para lamang sa kaginhawaan sa wika, dahil ang logistic regression ay [talagang isang classification method](https://scikit-learn.org/stable/modules/linear_model.html#logistic-regression), bagama't ito ay batay sa linear regression. Alamin ang iba pang paraan ng pag-classify ng data sa susunod na pangkat ng mga aralin.\n",
|
|
"\n",
|
|
"Para sa araling ito, kakailanganin natin ang mga sumusunod na package:\n",
|
|
"\n",
|
|
"- `tidyverse`: Ang [tidyverse](https://www.tidyverse.org/) ay isang [koleksyon ng mga R package](https://www.tidyverse.org/packages) na idinisenyo upang gawing mas mabilis, mas madali, at mas masaya ang data science!\n",
|
|
"\n",
|
|
"- `tidymodels`: Ang [tidymodels](https://www.tidymodels.org/) framework ay isang [koleksyon ng mga package](https://www.tidymodels.org/packages/) para sa pagmomodelo at machine learning.\n",
|
|
"\n",
|
|
"- `janitor`: Ang [janitor package](https://github.com/sfirke/janitor) ay nagbibigay ng mga simpleng tool para sa pagsusuri at paglilinis ng maruruming data.\n",
|
|
"\n",
|
|
"- `ggbeeswarm`: Ang [ggbeeswarm package](https://github.com/eclarke/ggbeeswarm) ay nagbibigay ng mga paraan upang lumikha ng beeswarm-style plots gamit ang ggplot2.\n",
|
|
"\n",
|
|
"Maaari mong i-install ang mga ito gamit ang:\n",
|
|
"\n",
|
|
"`install.packages(c(\"tidyverse\", \"tidymodels\", \"janitor\", \"ggbeeswarm\"))`\n",
|
|
"\n",
|
|
"Bilang alternatibo, ang script sa ibaba ay nagche-check kung mayroon ka ng mga kinakailangang package upang makumpleto ang module na ito at awtomatikong ini-install ang mga ito kung wala pa.\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": [
|
|
"## **Tukuyin ang tanong**\n",
|
|
"\n",
|
|
"Para sa ating layunin, ipapahayag natin ito bilang isang binary: 'Puti' o 'Hindi Puti'. Mayroon ding kategoryang 'striped' sa ating dataset ngunit kakaunti ang mga halimbawa nito, kaya hindi natin ito gagamitin. Nawawala rin ito kapag tinanggal natin ang mga null values mula sa dataset.\n",
|
|
"\n",
|
|
"> 🎃 Nakakatuwang kaalaman, minsan tinatawag natin ang mga puting kalabasa na 'ghost' pumpkins. Hindi sila madaling ukitin, kaya hindi sila kasing sikat ng mga orange na kalabasa, pero maganda ang itsura nila! Kaya maaari rin nating baguhin ang tanong bilang: 'Ghost' o 'Hindi Ghost'. 👻\n",
|
|
"\n",
|
|
"## **Tungkol sa logistic regression**\n",
|
|
"\n",
|
|
"Ang logistic regression ay naiiba sa linear regression, na natutunan mo na dati, sa ilang mahahalagang aspeto.\n",
|
|
"\n",
|
|
"#### **Binary classification**\n",
|
|
"\n",
|
|
"Ang logistic regression ay hindi nag-aalok ng parehong mga tampok tulad ng linear regression. Ang una ay nagbibigay ng prediksyon tungkol sa isang `binary category` (\"orange o hindi orange\") samantalang ang huli ay may kakayahang mag-predict ng `continual values`, halimbawa, batay sa pinanggalingan ng kalabasa at oras ng pag-ani, *kung gaano tataas ang presyo nito*.\n",
|
|
"\n",
|
|
"\n",
|
|
"\n",
|
|
"### Iba pang mga klasipikasyon\n",
|
|
"\n",
|
|
"May iba pang uri ng logistic regression, kabilang ang multinomial at ordinal:\n",
|
|
"\n",
|
|
"- **Multinomial**, na may higit sa isang kategorya - \"Orange, Puti, at Striped\".\n",
|
|
"\n",
|
|
"- **Ordinal**, na may mga ordered categories, kapaki-pakinabang kung nais nating ayusin ang ating mga resulta nang lohikal, tulad ng mga kalabasa na nakaayos ayon sa tiyak na bilang ng mga sukat (mini, sm, med, lg, xl, xxl).\n",
|
|
"\n",
|
|
"\n",
|
|
"\n",
|
|
"#### **Hindi kailangang magkaugnay ang mga variable**\n",
|
|
"\n",
|
|
"Tandaan kung paano mas gumagana ang linear regression kapag mas correlated ang mga variable? Ang logistic regression ay kabaligtaran - hindi kailangang mag-align ang mga variable. Angkop ito para sa data na may medyo mahihinang correlations.\n",
|
|
"\n",
|
|
"#### **Kailangan mo ng maraming malinis na data**\n",
|
|
"\n",
|
|
"Mas magiging tumpak ang resulta ng logistic regression kung gagamit ka ng mas maraming data; ang maliit na dataset natin ay hindi optimal para sa gawaing ito, kaya tandaan ito.\n",
|
|
"\n",
|
|
"✅ Pag-isipan ang mga uri ng data na angkop para sa logistic regression\n",
|
|
"\n",
|
|
"## Ehersisyo - ayusin ang data\n",
|
|
"\n",
|
|
"Una, linisin ang data nang kaunti, tanggalin ang mga null values at piliin lamang ang ilang mga column:\n",
|
|
"\n",
|
|
"1. Idagdag ang sumusunod na code:\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": [
|
|
"Maaari mong silipin ang iyong bagong dataframe gamit ang [*glimpse()*](https://pillar.r-lib.org/reference/glimpse.html) na function tulad ng nasa ibaba:\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {
|
|
"vscode": {
|
|
"languageId": "r"
|
|
}
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"pumpkins_select %>% \n",
|
|
" glimpse()\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"Tiyakin natin na ang gagawin natin ay isang binary classification problem:\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": [
|
|
"### Visualization - categorical plot\n",
|
|
"Sa ngayon, na-load mo na muli ang pumpkin data at nalinis ito upang mapanatili ang dataset na may ilang mga variable, kabilang ang Color. Tingnan natin ang dataframe sa notebook gamit ang ggplot library.\n",
|
|
"\n",
|
|
"Ang ggplot library ay nag-aalok ng magagandang paraan upang ma-visualize ang iyong data. Halimbawa, maaari mong ikumpara ang distribusyon ng data para sa bawat Variety at Color sa isang categorical plot.\n",
|
|
"\n",
|
|
"1. Gumawa ng ganitong plot gamit ang geombar function, gamit ang pumpkin data, at tukuyin ang color mapping para sa bawat kategorya ng kalabasa (orange o white):\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": [
|
|
"Sa pag-obserba ng datos, makikita mo kung paano nauugnay ang datos ng Kulay sa Uri.\n",
|
|
"\n",
|
|
"✅ Batay sa categorical plot na ito, ano ang mga kawili-wiling pagsusuri na maaari mong maisip?\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"### Pagproseso ng Data: Pag-encode ng mga Katangian\n",
|
|
"\n",
|
|
"Ang dataset ng ating mga kalabasa ay naglalaman ng mga string na halaga para sa lahat ng mga column nito. Ang paggamit ng categorical na data ay natural para sa mga tao ngunit hindi para sa mga makina. Ang mga algorithm ng machine learning ay mas mahusay gumana gamit ang mga numero. Kaya't ang pag-encode ay isang napakahalagang hakbang sa yugto ng pagproseso ng data, dahil pinapayagan tayo nitong gawing numerical data ang categorical data nang hindi nawawala ang anumang impormasyon. Ang mahusay na pag-encode ay nagreresulta sa pagbuo ng isang mahusay na modelo.\n",
|
|
"\n",
|
|
"Para sa pag-encode ng mga katangian, mayroong dalawang pangunahing uri ng encoder:\n",
|
|
"\n",
|
|
"1. **Ordinal encoder**: Angkop ito para sa mga ordinal na variable, na mga categorical na variable kung saan ang kanilang data ay may lohikal na pagkakasunod-sunod, tulad ng column na `item_size` sa ating dataset. Gumagawa ito ng mapping kung saan ang bawat kategorya ay kinakatawan ng isang numero, na siyang pagkakasunod-sunod ng kategorya sa column.\n",
|
|
"\n",
|
|
"2. **Categorical encoder**: Angkop ito para sa mga nominal na variable, na mga categorical na variable kung saan ang kanilang data ay walang lohikal na pagkakasunod-sunod, tulad ng lahat ng mga katangian maliban sa `item_size` sa ating dataset. Ito ay isang one-hot encoding, na nangangahulugang ang bawat kategorya ay kinakatawan ng isang binary na column: ang encoded na variable ay katumbas ng 1 kung ang kalabasa ay kabilang sa Variety na iyon at 0 kung hindi.\n",
|
|
"\n",
|
|
"Ang Tidymodels ay nagbibigay ng isa pang kapaki-pakinabang na package: [recipes](https://recipes.tidymodels.org/) - isang package para sa pagproseso ng data. Magtatakda tayo ng isang `recipe` na tumutukoy na ang lahat ng mga predictor column ay dapat i-encode sa isang set ng mga integer, `prep` ito upang tantiyahin ang mga kinakailangang dami at istatistika na kailangan para sa anumang operasyon, at sa huli ay `bake` upang ilapat ang mga kalkulasyon sa bagong data.\n",
|
|
"\n",
|
|
"> Karaniwan, ang recipes ay kadalasang ginagamit bilang isang preprocessor para sa pagmomodelo kung saan tinutukoy nito kung anong mga hakbang ang dapat ilapat sa isang dataset upang maihanda ito para sa pagmomodelo. Sa ganitong kaso, **lubos na inirerekomenda** na gumamit ka ng `workflow()` sa halip na manu-manong tantiyahin ang recipe gamit ang prep at bake. Makikita natin ang lahat ng ito sa ilang sandali.\n",
|
|
">\n",
|
|
"> Gayunpaman, sa ngayon, ginagamit natin ang recipes + prep + bake upang tukuyin kung anong mga hakbang ang dapat ilapat sa isang dataset upang maihanda ito para sa pagsusuri ng data at pagkatapos ay kunin ang preprocessed na data na may mga hakbang na inilapat.\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": [
|
|
"✅ Ano ang mga benepisyo ng paggamit ng ordinal encoder para sa column na Item Size?\n",
|
|
"\n",
|
|
"### Suriin ang relasyon sa pagitan ng mga variable\n",
|
|
"\n",
|
|
"Ngayon na na-preprocess na natin ang ating data, maaari na nating suriin ang relasyon sa pagitan ng mga features at ng label upang magkaroon ng ideya kung gaano kahusay mahuhulaan ng modelo ang label base sa mga features. Ang pinakamainam na paraan upang gawin ang ganitong uri ng pagsusuri ay sa pamamagitan ng pag-plot ng data. \n",
|
|
"Gagamitin natin muli ang ggplot geom_boxplot_ function upang maipakita ang relasyon sa pagitan ng Item Size, Variety, at Color sa isang categorical plot. Upang mas maayos na maipakita ang data, gagamitin natin ang encoded na Item Size column at ang unencoded na Variety column.\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": [
|
|
"#### Gumamit ng swarm plot\n",
|
|
"\n",
|
|
"Dahil ang Color ay isang binary na kategorya (White o Hindi), nangangailangan ito ng '[espesyal na paraan](https://github.com/rstudio/cheatsheets/blob/main/data-visualization.pdf) sa pag-visualize'.\n",
|
|
"\n",
|
|
"Subukan ang `swarm plot` upang ipakita ang distribusyon ng kulay kaugnay ng item_size.\n",
|
|
"\n",
|
|
"Gagamitin natin ang [ggbeeswarm package](https://github.com/eclarke/ggbeeswarm) na nagbibigay ng mga paraan upang lumikha ng beeswarm-style plots gamit ang ggplot2. Ang mga beeswarm plot ay isang paraan ng pag-plot ng mga puntos na karaniwang magpapatong upang mailagay ang mga ito sa tabi ng isa't isa.\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": [
|
|
"Ngayon na may ideya na tayo tungkol sa ugnayan ng mga binary na kategorya ng kulay at ng mas malaking grupo ng mga sukat, tuklasin natin ang logistic regression upang matukoy ang posibleng kulay ng isang kalabasa.\n",
|
|
"\n",
|
|
"## Bumuo ng iyong modelo\n",
|
|
"\n",
|
|
"Piliin ang mga variable na nais mong gamitin sa iyong classification model at hatiin ang data sa training at test sets. Ang [rsample](https://rsample.tidymodels.org/), isang package sa Tidymodels, ay nagbibigay ng imprastraktura para sa mahusay na paghahati at resampling ng data:\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": [
|
|
"🙌 Handa na tayong magsanay ng modelo sa pamamagitan ng pag-angkop ng mga training features sa training label (kulay).\n",
|
|
"\n",
|
|
"Magsisimula tayo sa paglikha ng recipe na nagtatakda ng mga hakbang sa preprocessing na kailangang isagawa sa ating data upang maihanda ito para sa pagmomodelo, halimbawa: pag-encode ng mga categorical variables sa isang set ng integers. Katulad ng `baked_pumpkins`, gagawa tayo ng `pumpkins_recipe` ngunit hindi natin ito `prep` at `bake` dahil ito ay isasama sa isang workflow, na makikita mo sa ilang hakbang mula ngayon.\n",
|
|
"\n",
|
|
"Mayroong iba't ibang paraan upang tukuyin ang isang logistic regression model sa Tidymodels. Tingnan ang `?logistic_reg()`. Sa ngayon, itatakda natin ang isang logistic regression model gamit ang default na `stats::glm()` engine.\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": [
|
|
"Ngayon na mayroon na tayong recipe at model specification, kailangan nating maghanap ng paraan upang pagsamahin ang mga ito sa isang object na unang magpoproseso ng data (prep+bake sa likod ng eksena), magfi-fit ng modelo sa naprosesong data, at magbibigay-daan din para sa mga posibleng aktibidad ng post-processing.\n",
|
|
"\n",
|
|
"Sa Tidymodels, ang maginhawang object na ito ay tinatawag na [`workflow`](https://workflows.tidymodels.org/) at maginhawang humahawak sa iyong mga modeling components.\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": [
|
|
"Kapag ang isang workflow ay *naitakda* na, maaaring `i-train` ang isang modelo gamit ang [`fit()`](https://tidymodels.github.io/parsnip/reference/fit.html) na function. Awtomatikong tatantiyahin ng workflow ang recipe at ipo-proseso ang data bago ang training, kaya hindi na natin kailangang gawin ito nang manu-mano gamit ang prep at 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": [
|
|
"Ipinapakita ng model print out ang mga coefficients na natutunan sa panahon ng training.\n",
|
|
"\n",
|
|
"Ngayon na na-train na natin ang model gamit ang training data, maaari na tayong gumawa ng mga prediksyon sa test data gamit ang [parsnip::predict()](https://parsnip.tidymodels.org/reference/predict.model_fit.html). Magsimula tayo sa paggamit ng model upang hulaan ang mga label para sa ating test set at ang mga probabilidad para sa bawat label. Kapag ang probabilidad ay higit sa 0.5, ang predicted class ay `WHITE`, kung hindi naman ay `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": [
|
|
"Napakaganda! Nagbibigay ito ng mas malalim na pag-unawa sa kung paano gumagana ang logistic regression.\n",
|
|
"\n",
|
|
"### Mas malinaw na pag-unawa gamit ang confusion matrix\n",
|
|
"\n",
|
|
"Ang paghahambing ng bawat prediksyon sa kaukulang \"ground truth\" o aktwal na halaga ay hindi masyadong epektibong paraan upang matukoy kung gaano kahusay ang modelo sa pag-predict. Sa kabutihang-palad, may ilang karagdagang kakayahan ang Tidymodels: [`yardstick`](https://yardstick.tidymodels.org/) - isang package na ginagamit upang sukatin ang bisa ng mga modelo gamit ang performance metrics.\n",
|
|
"\n",
|
|
"Isa sa mga performance metric na nauugnay sa mga classification problem ay ang [`confusion matrix`](https://wikipedia.org/wiki/Confusion_matrix). Ang confusion matrix ay naglalarawan kung gaano kahusay ang isang classification model sa pagganap. Ang confusion matrix ay nagtatala kung ilang halimbawa sa bawat klase ang tama na na-classify ng isang modelo. Sa ating kaso, ipapakita nito kung ilang orange pumpkins ang na-classify bilang orange at kung ilang white pumpkins ang na-classify bilang white; ipinapakita rin ng confusion matrix kung ilan ang na-classify sa **maling** mga kategorya.\n",
|
|
"\n",
|
|
"Ang [**`conf_mat()`**](https://tidymodels.github.io/yardstick/reference/conf_mat.html) na function mula sa yardstick ang nagkakalkula ng cross-tabulation ng mga observed at predicted na klase.\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": [
|
|
"Tukuyin natin ang confusion matrix. Ang ating modelo ay inatasang uriin ang mga kalabasa sa dalawang binary na kategorya, kategoryang `puti` at kategoryang `hindi-puti`.\n",
|
|
"\n",
|
|
"- Kapag ang iyong modelo ay nag-predict na ang kalabasa ay puti at ito ay talagang kabilang sa kategoryang 'puti', tinatawag natin itong `true positive`, na makikita sa itaas na kaliwang numero.\n",
|
|
"\n",
|
|
"- Kapag ang iyong modelo ay nag-predict na ang kalabasa ay hindi puti at ito ay talagang kabilang sa kategoryang 'puti', tinatawag natin itong `false negative`, na makikita sa ibabang kaliwang numero.\n",
|
|
"\n",
|
|
"- Kapag ang iyong modelo ay nag-predict na ang kalabasa ay puti at ito ay talagang kabilang sa kategoryang 'hindi-puti', tinatawag natin itong `false positive`, na makikita sa itaas na kanang numero.\n",
|
|
"\n",
|
|
"- Kapag ang iyong modelo ay nag-predict na ang kalabasa ay hindi puti at ito ay talagang kabilang sa kategoryang 'hindi-puti', tinatawag natin itong `true negative`, na makikita sa ibabang kanang numero.\n",
|
|
"\n",
|
|
"| Katotohanan |\n",
|
|
"|:-----------:|\n",
|
|
"\n",
|
|
"| | | |\n",
|
|
"|---------------|--------|-------|\n",
|
|
"| **Predicted** | PUTI | KAHEL |\n",
|
|
"| PUTI | TP | FP |\n",
|
|
"| KAHEL | FN | TN |\n",
|
|
"\n",
|
|
"Tulad ng maaaring nahulaan mo, mas mainam na magkaroon ng mas mataas na bilang ng true positives at true negatives at mas mababang bilang ng false positives at false negatives, na nagpapahiwatig na mas mahusay ang pagganap ng modelo.\n",
|
|
"\n",
|
|
"Ang confusion matrix ay kapaki-pakinabang dahil nagbibigay ito ng iba pang mga sukatan na makakatulong sa atin na mas mahusay na suriin ang pagganap ng isang classification model. Talakayin natin ang ilan sa mga ito:\n",
|
|
"\n",
|
|
"🎓 Precision: `TP/(TP + FP)` na tinutukoy bilang ang proporsyon ng mga predicted na positibo na talagang positibo. Tinatawag din itong [positive predictive value](https://en.wikipedia.org/wiki/Positive_predictive_value \"Positive predictive value\").\n",
|
|
"\n",
|
|
"🎓 Recall: `TP/(TP + FN)` na tinutukoy bilang ang proporsyon ng mga positibong resulta mula sa bilang ng mga sample na talagang positibo. Kilala rin bilang `sensitivity`.\n",
|
|
"\n",
|
|
"🎓 Specificity: `TN/(TN + FP)` na tinutukoy bilang ang proporsyon ng mga negatibong resulta mula sa bilang ng mga sample na talagang negatibo.\n",
|
|
"\n",
|
|
"🎓 Accuracy: `TP + TN/(TP + TN + FP + FN)` Ang porsyento ng mga label na tamang na-predict para sa isang sample.\n",
|
|
"\n",
|
|
"🎓 F Measure: Isang weighted average ng precision at recall, kung saan ang pinakamainam ay 1 at ang pinakamasama ay 0.\n",
|
|
"\n",
|
|
"Kalkulahin natin ang mga sukatan na ito!\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": [
|
|
"## I-visualize ang ROC curve ng modelong ito\n",
|
|
"\n",
|
|
"Gawin natin ang isa pang visualization upang makita ang tinatawag na [`ROC curve`](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": [
|
|
"Ang mga ROC curve ay madalas gamitin upang makita ang output ng isang classifier sa aspeto ng tunay na positibo kumpara sa maling positibo. Karaniwan, ang mga ROC curve ay may `True Positive Rate`/Sensitibidad sa Y axis, at `False Positive Rate`/1-Specificity sa X axis. Dahil dito, mahalaga ang pagkatarik ng kurba at ang espasyo sa pagitan ng linya sa gitna at ng kurba: nais mo ng kurba na mabilis na tumataas at lumalampas sa linya. Sa ating kaso, may mga maling positibo sa simula, at pagkatapos ay maayos na tumataas at lumalampas ang linya.\n",
|
|
"\n",
|
|
"Sa wakas, gamitin natin ang `yardstick::roc_auc()` upang kalkulahin ang aktwal na Area Under the Curve. Isang paraan ng pag-unawa sa AUC ay ang probabilidad na ang modelo ay magraranggo ng isang random na positibong halimbawa nang mas mataas kaysa sa isang random na negatibong halimbawa.\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": [
|
|
"Ang resulta ay nasa paligid ng `0.975`. Dahil ang AUC ay may saklaw mula 0 hanggang 1, nais mo ng mataas na score, dahil ang isang modelo na 100% tama sa mga prediksyon nito ay magkakaroon ng AUC na 1; sa kasong ito, ang modelo ay *medyo maganda*.\n",
|
|
"\n",
|
|
"Sa mga susunod na aralin tungkol sa mga klasipikasyon, matututuhan mo kung paano pahusayin ang mga score ng iyong modelo (tulad ng pagharap sa hindi balanseng datos sa kasong ito).\n",
|
|
"\n",
|
|
"## 🚀Hamunin\n",
|
|
"\n",
|
|
"Marami pang dapat tuklasin tungkol sa logistic regression! Ngunit ang pinakamainam na paraan upang matuto ay ang mag-eksperimento. Maghanap ng dataset na angkop para sa ganitong uri ng pagsusuri at bumuo ng modelo gamit ito. Ano ang natutunan mo? tip: subukan ang [Kaggle](https://www.kaggle.com/search?q=logistic+regression+datasets) para sa mga kawili-wiling dataset.\n",
|
|
"\n",
|
|
"## Pagsusuri at Pag-aaral sa Sarili\n",
|
|
"\n",
|
|
"Basahin ang unang ilang pahina ng [papel na ito mula sa Stanford](https://web.stanford.edu/~jurafsky/slp3/5.pdf) tungkol sa ilang praktikal na gamit ng logistic regression. Pag-isipan ang mga gawain na mas angkop para sa isa o ibang uri ng regression na pinag-aralan natin hanggang sa puntong ito. Ano ang mas angkop na gamitin?\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"\n---\n\n**Paunawa**: \nAng dokumentong ito ay isinalin gamit ang AI translation service na [Co-op Translator](https://github.com/Azure/co-op-translator). Bagama't sinisikap naming maging tumpak, pakitandaan na ang mga awtomatikong pagsasalin ay maaaring maglaman ng mga pagkakamali o hindi pagkakatugma. Ang orihinal na dokumento sa orihinal nitong wika ang dapat ituring na opisyal na sanggunian. Para sa mahalagang impormasyon, inirerekomenda ang propesyonal na pagsasalin ng tao. Hindi kami mananagot sa anumang hindi pagkakaunawaan o maling interpretasyon na maaaring magmula sa paggamit ng pagsasaling ito.\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-08-29T14:54:09+00:00",
|
|
"source_file": "2-Regression/4-Logistic/solution/R/lesson_4-R.ipynb",
|
|
"language_code": "tl"
|
|
}
|
|
},
|
|
"nbformat": 4,
|
|
"nbformat_minor": 1
|
|
} |