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.
ML-For-Beginners/translations/tw/2-Regression/1-Tools/solution/R/lesson_1-R.ipynb

447 lines
16 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

{
"nbformat": 4,
"nbformat_minor": 2,
"metadata": {
"colab": {
"name": "lesson_1-R.ipynb",
"provenance": [],
"collapsed_sections": [],
"toc_visible": true
},
"kernelspec": {
"name": "ir",
"display_name": "R"
},
"language_info": {
"name": "R"
},
"coopTranslator": {
"original_hash": "c18d3bd0bd8ae3878597e89dcd1fa5c1",
"translation_date": "2025-09-03T19:44:33+00:00",
"source_file": "2-Regression/1-Tools/solution/R/lesson_1-R.ipynb",
"language_code": "tw"
}
},
"cells": [
{
"cell_type": "markdown",
"source": [],
"metadata": {
"id": "YJUHCXqK57yz"
}
},
{
"cell_type": "markdown",
"source": [
"## 回歸分析入門 - 第一課\n",
"\n",
"#### 放到情境中來看\n",
"\n",
"✅ 回歸方法有很多種類,選擇哪一種取決於你想要解答的問題。如果你想預測某個年齡的人可能的身高,你會使用 `線性回歸`,因為你在尋找一個**數值**。如果你想了解某種菜餚是否應該被視為純素,你在尋找的是一個**類別分配**,因此你會使用 `邏輯回歸`。稍後你會學到更多關於邏輯回歸的內容。試著思考一些你可以向數據提出的問題,以及哪種方法更適合回答這些問題。\n",
"\n",
"在本節中,你將使用一個[關於糖尿病的小型數據集](https://www4.stat.ncsu.edu/~boos/var.select/diabetes.html)。想像一下,你想要測試一種針對糖尿病患者的治療方法。機器學習模型可能幫助你判斷哪些患者基於變數的組合會對治療有更好的反應。即使是一個非常基礎的回歸模型,當可視化時,也可能顯示出一些關於變數的信息,幫助你組織理論上的臨床試驗。\n",
"\n",
"說到這裡,讓我們開始這項任務吧!\n",
"\n",
"<p >\n",
" <img src=\"../../images/encouRage.jpg\"\n",
" width=\"630\"/>\n",
" <figcaption>插畫作者:@allison_horst</figcaption>\n",
"\n",
"<!--![插畫作者:\\@allison_horst](../../../../../../translated_images/encouRage.e75d5fe0367fb9136b78104baf4e2032a7622bc42a2bc34c0ad36c294eeb83f5.tw.jpg)<br>插畫作者:@allison_horst-->\n"
],
"metadata": {
"id": "LWNNzfqd6feZ"
}
},
{
"cell_type": "markdown",
"source": [
"## 1. 加載工具集\n",
"\n",
"在這項任務中,我們需要以下套件:\n",
"\n",
"- `tidyverse` [tidyverse](https://www.tidyverse.org/) 是一個[由 R 套件組成的集合](https://www.tidyverse.org/packages),旨在讓數據科學更快速、更簡單、更有趣!\n",
"\n",
"- `tidymodels` [tidymodels](https://www.tidymodels.org/) 框架是一個[由套件組成的集合](https://www.tidymodels.org/packages),用於建模和機器學習。\n",
"\n",
"您可以使用以下指令安裝它們:\n",
"\n",
"`install.packages(c(\"tidyverse\", \"tidymodels\"))`\n",
"\n",
"以下腳本會檢查您是否擁有完成此模組所需的套件,並在缺少某些套件時為您安裝。\n"
],
"metadata": {
"id": "FIo2YhO26wI9"
}
},
{
"cell_type": "code",
"execution_count": 2,
"source": [
"suppressWarnings(if(!require(\"pacman\")) install.packages(\"pacman\"))\n",
"pacman::p_load(tidyverse, tidymodels)"
],
"outputs": [
{
"output_type": "stream",
"name": "stderr",
"text": [
"Loading required package: pacman\n",
"\n"
]
}
],
"metadata": {
"id": "cIA9fz9v7Dss",
"colab": {
"base_uri": "https://localhost:8080/"
},
"outputId": "2df7073b-86b2-4b32-cb86-0da605a0dc11"
}
},
{
"cell_type": "markdown",
"source": [
"現在,讓我們載入這些很棒的套件並使它們在我們目前的 R 工作環境中可用。(這僅是為了說明,`pacman::p_load()` 已經為您完成了這項工作)\n"
],
"metadata": {
"id": "gpO_P_6f9WUG"
}
},
{
"cell_type": "code",
"execution_count": null,
"source": [
"# load the core Tidyverse packages\r\n",
"library(tidyverse)\r\n",
"\r\n",
"# load the core Tidymodels packages\r\n",
"library(tidymodels)\r\n"
],
"outputs": [],
"metadata": {
"id": "NLMycgG-9ezO"
}
},
{
"cell_type": "markdown",
"source": [
"## 2. 糖尿病數據集\n",
"\n",
"在這個練習中,我們將展示回歸分析的技能,並使用糖尿病數據集進行預測。[糖尿病數據集](https://www4.stat.ncsu.edu/~boos/var.select/diabetes.rwrite1.txt) 包含 `442 個樣本` 的糖尿病相關數據,包括 10 個預測特徵變數:`年齡`、`性別`、`身體質量指數`、`平均血壓` 和 `六項血清測量值`,以及一個結果變數 `y`:基準一年後疾病進展的定量測量。\n",
"\n",
"|觀測數量|442|\n",
"|----------------------|:---|\n",
"|預測變數數量|前 10 列為數值型預測變數|\n",
"|結果/目標|第 11 列為基準一年後疾病進展的定量測量|\n",
"|預測變數資訊|- 年齡(以年計算)\n",
"||- 性別\n",
"||- bmi 身體質量指數\n",
"||- bp 平均血壓\n",
"||- s1 tc總血清膽固醇\n",
"||- s2 ldl低密度脂蛋白\n",
"||- s3 hdl高密度脂蛋白\n",
"||- s4 tch總膽固醇 / HDL\n",
"||- s5 ltg可能是血清甘油三酯水平的對數\n",
"||- s6 glu血糖水平|\n",
"\n",
"> 🎓 記住,這是監督式學習,我們需要一個名為 'y' 的目標變數。\n",
"\n",
"在使用 R 操作數據之前,您需要將數據導入 R 的內存,或者建立一個 R 可以用來遠程訪問數據的連接。\n",
"\n",
"> [readr](https://readr.tidyverse.org/) 套件是 Tidyverse 的一部分,它提供了一種快速且友好的方式將矩形數據讀入 R。\n",
"\n",
"現在,讓我們加載來自以下來源 URL 的糖尿病數據集:<https://www4.stat.ncsu.edu/~boos/var.select/diabetes.html>\n",
"\n",
"此外,我們將使用 `glimpse()` 對數據進行基本檢查,並使用 `slice()` 顯示前 5 行。\n",
"\n",
"在繼續之前,讓我們介紹一個您在 R 代碼中經常會遇到的東西 🥁🥁:管道運算符 `%>%`\n",
"\n",
"管道運算符 (`%>%`) 通過將一個對象向前傳遞到函數或調用表達式中,按邏輯順序執行操作。您可以將管道運算符理解為代碼中的 \"然後\"。\n"
],
"metadata": {
"id": "KM6iXLH996Cl"
}
},
{
"cell_type": "code",
"execution_count": null,
"source": [
"# Import the data set\r\n",
"diabetes <- read_table2(file = \"https://www4.stat.ncsu.edu/~boos/var.select/diabetes.rwrite1.txt\")\r\n",
"\r\n",
"\r\n",
"# Get a glimpse and dimensions of the data\r\n",
"glimpse(diabetes)\r\n",
"\r\n",
"\r\n",
"# Select the first 5 rows of the data\r\n",
"diabetes %>% \r\n",
" slice(1:5)"
],
"outputs": [],
"metadata": {
"id": "Z1geAMhM-bSP"
}
},
{
"cell_type": "markdown",
"source": [
"`glimpse()` 告訴我們這份資料有 442 行和 11 列,所有的列都是 `double` 資料型別。\n",
"\n",
"<br>\n",
"\n",
"> glimpse() 和 slice() 是 [`dplyr`](https://dplyr.tidyverse.org/) 中的函數。Dplyr 是 Tidyverse 的一部分,是一種資料操作的語法,提供了一組一致的動詞,幫助解決最常見的資料操作挑戰。\n",
"\n",
"<br>\n",
"\n",
"現在我們已經有了資料,讓我們聚焦到其中一個特徵(`bmi`),作為這次練習的目標。這需要我們選擇所需的列。那麼,我們該如何做到呢?\n",
"\n",
"[`dplyr::select()`](https://dplyr.tidyverse.org/reference/select.html) 允許我們在資料框中*選擇*(並可選擇性地重新命名)列。\n"
],
"metadata": {
"id": "UwjVT1Hz-c3Z"
}
},
{
"cell_type": "code",
"execution_count": null,
"source": [
"# Select predictor feature `bmi` and outcome `y`\r\n",
"diabetes_select <- diabetes %>% \r\n",
" select(c(bmi, y))\r\n",
"\r\n",
"# Print the first 5 rows\r\n",
"diabetes_select %>% \r\n",
" slice(1:10)"
],
"outputs": [],
"metadata": {
"id": "RDY1oAKI-m80"
}
},
{
"cell_type": "markdown",
"source": [
"## 3. 訓練與測試資料\n",
"\n",
"在監督式學習中,通常會將資料*分割*成兩個子集;一個(通常較大的)用來訓練模型的集合,以及一個較小的「保留」集合,用來檢視模型的表現。\n",
"\n",
"現在我們已經準備好資料,可以看看機器是否能幫助我們在這個數據集中找到一個合理的分割方式。我們可以使用 [rsample](https://tidymodels.github.io/rsample/) 套件,這是 Tidymodels 框架的一部分,來建立一個包含如何分割資料資訊的物件,然後使用另外兩個 rsample 函數來提取生成的訓練和測試集合:\n"
],
"metadata": {
"id": "SDk668xK-tc3"
}
},
{
"cell_type": "code",
"execution_count": null,
"source": [
"set.seed(2056)\r\n",
"# Split 67% of the data for training and the rest for tesing\r\n",
"diabetes_split <- diabetes_select %>% \r\n",
" initial_split(prop = 0.67)\r\n",
"\r\n",
"# Extract the resulting train and test sets\r\n",
"diabetes_train <- training(diabetes_split)\r\n",
"diabetes_test <- testing(diabetes_split)\r\n",
"\r\n",
"# Print the first 3 rows of the training set\r\n",
"diabetes_train %>% \r\n",
" slice(1:10)"
],
"outputs": [],
"metadata": {
"id": "EqtHx129-1h-"
}
},
{
"cell_type": "markdown",
"source": [
"## 4. 使用 Tidymodels 訓練線性回歸模型\n",
"\n",
"現在我們準備好訓練模型了!\n",
"\n",
"在 Tidymodels 中,您可以使用 `parsnip()` 來指定模型,並定義以下三個概念:\n",
"\n",
"- 模型**類型**區分不同的模型,例如線性回歸、邏輯回歸、決策樹模型等。\n",
"\n",
"- 模型**模式**包括常見選項如回歸和分類;某些模型類型支持這兩種模式,而有些僅支持其中一種。\n",
"\n",
"- 模型**引擎**是用來擬合模型的計算工具。通常這些是 R 套件,例如 **`\"lm\"`** 或 **`\"ranger\"`**。\n",
"\n",
"這些建模資訊會被捕捉到模型規範中,所以讓我們來建立一個吧!\n"
],
"metadata": {
"id": "sBOS-XhB-6v7"
}
},
{
"cell_type": "code",
"execution_count": null,
"source": [
"# Build a linear model specification\r\n",
"lm_spec <- \r\n",
" # Type\r\n",
" linear_reg() %>% \r\n",
" # Engine\r\n",
" set_engine(\"lm\") %>% \r\n",
" # Mode\r\n",
" set_mode(\"regression\")\r\n",
"\r\n",
"\r\n",
"# Print the model specification\r\n",
"lm_spec"
],
"outputs": [],
"metadata": {
"id": "20OwEw20--t3"
}
},
{
"cell_type": "markdown",
"source": [
"在模型被*指定*之後,可以使用 [`fit()`](https://parsnip.tidymodels.org/reference/fit.html) 函數來進行模型的`估算`或`訓練`,通常需要使用公式和一些數據。\n",
"\n",
"`y ~ .` 的意思是我們將 `y` 作為預測的量/目標,由所有的預測變數/特徵來解釋,也就是 `.`(在這個例子中,我們只有一個預測變數:`bmi`)。\n"
],
"metadata": {
"id": "_oDHs89k_CJj"
}
},
{
"cell_type": "code",
"execution_count": null,
"source": [
"# Build a linear model specification\r\n",
"lm_spec <- linear_reg() %>% \r\n",
" set_engine(\"lm\") %>%\r\n",
" set_mode(\"regression\")\r\n",
"\r\n",
"\r\n",
"# Train a linear regression model\r\n",
"lm_mod <- lm_spec %>% \r\n",
" fit(y ~ ., data = diabetes_train)\r\n",
"\r\n",
"# Print the model\r\n",
"lm_mod"
],
"outputs": [],
"metadata": {
"id": "YlsHqd-q_GJQ"
}
},
{
"cell_type": "markdown",
"source": [
"從模型輸出中,我們可以看到訓練過程中學到的係數。這些係數代表最佳擬合線的係數,該線能使實際變數與預測變數之間的整體誤差降到最低。\n",
"<br>\n",
"\n",
"## 5. 在測試集上進行預測\n",
"\n",
"現在我們已經訓練了一個模型,可以使用 [parsnip::predict()](https://parsnip.tidymodels.org/reference/predict.model_fit.html) 來對測試數據集的疾病進展 y 進行預測。這將用於繪製數據組之間的分界線。\n"
],
"metadata": {
"id": "kGZ22RQj_Olu"
}
},
{
"cell_type": "code",
"execution_count": null,
"source": [
"# Make predictions for the test set\r\n",
"predictions <- lm_mod %>% \r\n",
" predict(new_data = diabetes_test)\r\n",
"\r\n",
"# Print out some of the predictions\r\n",
"predictions %>% \r\n",
" slice(1:5)"
],
"outputs": [],
"metadata": {
"id": "nXHbY7M2_aao"
}
},
{
"cell_type": "markdown",
"source": [
"哇哦!💃🕺 我們剛剛訓練了一個模型並用它進行了預測!\n",
"\n",
"在進行預測時tidymodels 的慣例是始終生成一個具有標準化列名的 tibble/資料框結果。這使得將原始數據和預測結果結合成一個可用格式變得非常簡單,方便後續操作,例如繪圖。\n",
"\n",
"`dplyr::bind_cols()` 可以高效地將多個資料框的列綁定在一起。\n"
],
"metadata": {
"id": "R_JstwUY_bIs"
}
},
{
"cell_type": "code",
"execution_count": null,
"source": [
"# Combine the predictions and the original test set\r\n",
"results <- diabetes_test %>% \r\n",
" bind_cols(predictions)\r\n",
"\r\n",
"\r\n",
"results %>% \r\n",
" slice(1:5)"
],
"outputs": [],
"metadata": {
"id": "RybsMJR7_iI8"
}
},
{
"cell_type": "markdown",
"source": [
"## 6. 繪製模型結果\n",
"\n",
"現在是時候用視覺化來呈現了 📈。我們將建立一個散佈圖,展示測試集中的所有 `y` 和 `bmi` 值,然後使用預測結果繪製一條線,將模型的數據分組以最合適的方式連接起來。\n",
"\n",
"R 有多種繪圖系統,但 `ggplot2` 是其中最優雅且最具靈活性的。它允許你通過**組合獨立的組件**來構建圖表。\n"
],
"metadata": {
"id": "XJbYbMZW_n_s"
}
},
{
"cell_type": "code",
"execution_count": null,
"source": [
"# Set a theme for the plot\r\n",
"theme_set(theme_light())\r\n",
"# Create a scatter plot\r\n",
"results %>% \r\n",
" ggplot(aes(x = bmi)) +\r\n",
" # Add a scatter plot\r\n",
" geom_point(aes(y = y), size = 1.6) +\r\n",
" # Add a line plot\r\n",
" geom_line(aes(y = .pred), color = \"blue\", size = 1.5)"
],
"outputs": [],
"metadata": {
"id": "R9tYp3VW_sTn"
}
},
{
"cell_type": "markdown",
"source": [
"✅ 想一想這裡發生了什麼。一條直線穿過許多小數據點,但它究竟在做什麼?你能否看出如何利用這條直線來預測一個新的、未見過的數據點應該如何與圖表的 y 軸產生關聯?試著用語言描述這個模型的實際用途。\n",
"\n",
"恭喜你!你已經建立了你的第一個線性回歸模型,使用它進行了預測,並在圖表中展示了結果!\n"
],
"metadata": {
"id": "zrPtHIxx_tNI"
}
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\n---\n\n**免責聲明** \n本文件使用 AI 翻譯服務 [Co-op Translator](https://github.com/Azure/co-op-translator) 進行翻譯。儘管我們致力於提供準確的翻譯,請注意自動翻譯可能包含錯誤或不準確之處。原始文件的母語版本應被視為權威來源。對於重要資訊,建議尋求專業人工翻譯。我們對因使用此翻譯而產生的任何誤解或錯誤解釋不承擔責任。\n"
]
}
]
}