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/hk/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:43:50+00:00",
"source_file": "2-Regression/1-Tools/solution/R/lesson_1-R.ipynb",
"language_code": "hk"
}
},
"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.hk.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本文件已使用人工智能翻譯服務 [Co-op Translator](https://github.com/Azure/co-op-translator) 進行翻譯。儘管我們致力於提供準確的翻譯,但請注意,自動翻譯可能包含錯誤或不準確之處。原始語言的文件應被視為具權威性的來源。對於重要信息,建議使用專業人工翻譯。我們對因使用此翻譯而引起的任何誤解或錯誤解釋概不負責。\n"
]
}
]
}