{ "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-08-29T23:09:02+00:00", "source_file": "2-Regression/1-Tools/solution/R/lesson_1-R.ipynb", "language_code": "mo" } }, "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", "
\n",
" \n",
"
\n",
"\n",
"> glimpse() 和 slice() 是 [`dplyr`](https://dplyr.tidyverse.org/) 中的函數。Dplyr 是 Tidyverse 的一部分,它是一種資料操作的語法,提供了一組一致的動詞,幫助你解決最常見的資料操作挑戰。\n",
"\n",
"
\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",
"
\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"
]
}
]
}