@ -1,137 +1,136 @@
# 使用 Scikit-learn 建立迴歸模型:四種迴歸方法
# 使用 Scikit-learn 建立迴歸模型:四種迴歸方式
## 初學者注 記
## 初學者筆 記
線性迴歸用於當我們想要預測< strong > 數值< / strong > (例如,房價、溫度或銷售額)時。
線性迴歸透過尋找一條最佳代表輸入特徵和輸出之間關係的直線來運作。
當我們想要預測< strong > 數值< / strong > (例如房屋價格、溫度或銷售額)時,會使用線性迴歸。它是透過尋找最能代表輸入特徵與輸出之間關係的直線來進行預測。
在本課程中,我們著重於先理解概念,再探索 更進階的迴歸技術。

> 資訊圖由 [Dasani Madipalli ](https://twitter.com/dasani_decoded ) 製作
本課程將先專注於理解概念,稍後再探討 更進階的迴歸技術。

> 資訊圖表 由 [Dasani Madipalli ](https://twitter.com/dasani_decoded ) 製作
## [課前小測驗 ](https://ff-quizzes.netlify.app/en/ml/ )
> ### [本課程 亦有 R 版本!](../../../../2-Regression/3-Linear/solution/R/lesson_3.html )
### 介紹
> ### [本課程 也提供 R 語言 版本!](../../../../2-Regression/3-Linear/solution/R/lesson_3.html )
### 導言
到目前為止,您已經使用南瓜價格資料集探索了什麼是迴歸,並且使用 Matplotlib 做了資料 視覺化。
到目前為止,你已經用南瓜定價資料集探討了迴歸概念,並使用 Matplotlib 進行 視覺化。
現在您已準備深入了解機器學習的迴歸。雖然視覺化可以幫助理解資料, 但機器學習的真正威力來自於_訓練模型_。模型是基於歷史資料訓練而成, 能自動捕捉資料間的依賴關係, 並能對之前沒看過的新資料預測結果 。
現在你準備深入了解 ML 中的迴歸應用。視覺化讓你理解資料,真正的機器學習威力來自於「訓練模型」。模型會基於歷史資料自動捕捉資料關聯,並能對未見過的新資料進行預測 。
在本課中, 您將學習兩種迴歸: _基本線性迴歸_及_多項式迴歸_, 以及其中一些數學原理。這些模型將讓我們根 據不同輸入資料預測南瓜價格。
本課程將介紹兩種迴歸方式:_基本線性迴歸_和_多項式迴歸_,並涵蓋這些技術背後的數學原理。這些模型將幫助我們依 據不同輸入資料預測南瓜價格。
[](https://youtu.be/CRxFT8oTDMg "機器學習入門 - 理解線性迴歸")
[](https://youtu.be/CRxFT8oTDMg "初學者 機器學習 - 理解線性迴歸")
> 🎥 點擊上方圖片觀看線性迴歸的簡短影片概述 。
> 🎥 點擊上方圖片觀看線性迴歸的簡短影片介紹 。
> 在整個課程中,我們假設學員的數學知識量少,並力求讓其他領域的學生都能理解,因此會有註解、🧮 重點標註、圖解及其他學習工具協助理解 。
> 本課程假設極少的數學背景,並致力讓非相關領域的學生也能理解,請留意課堂筆記、🧮 數學補充、圖表等學習輔助工具 。
### 先備 知識
### 先修 知識
您應該已熟悉我們正在檢視的南瓜資料結構。這份資料已預先載入並清理好,在本課的 _notebook.ipynb_ 檔案中。檔中南瓜價格以每蒲式耳價格顯示於新的資料框中。請確保您能在 Visual Studio Code 的環境中執行這些筆記本 。
你現在應熟悉我們分析的南瓜資料結構。資料已預先載入並清理,存於本課程的 _notebook.ipynb_ 。在該檔案中,南瓜價格以「每蒲式耳」價格呈現。請確定你能在 Visual Studio Code 的 kernel 執行這些 notebook 。
### 準備工作
提醒您,載入這些資料是為了探究一些 問題:
提醒你,載入資料是為了向它提出 問題:
- 何時購買南瓜最划算?
- 一箱迷你南瓜的價格 大約是 多少?
- 應該買半蒲式耳的籃子,還是 1又1/9蒲式耳的箱子?
讓我們繼續挖掘這些 資料。
- 什麼時候買南瓜最划算?
- 一箱迷你南瓜大約多少錢 ?
- 我該買半蒲式耳籃裝還是 1 1/9 蒲式耳箱裝?
讓我們持續深入挖掘 資料。
前一課中,您建立了 Pandas 資料框,並填入原始資料的部分,且將價格以蒲式耳標準化。但如此一來,只收集了約 400 筆資料,且僅涵蓋秋季 。
上一課中,你建立了 Pandas dataframe 並用原始數據部分填充,還根據蒲式耳標準化了價格。不過,那時僅蒐集約 400 筆資料,也只涵蓋秋季月份 。
請看看本課附帶筆記本所載入的資料,我們已有初始散點圖繪出月份資料。也許透過更多清理,我們能獲得這資料本質的更多細節 。
請看看本課 notebook 中預載的資料。資料已預先載入,並藉由散佈圖初步描繪出月份資料。也許我們可以進一步清理,以更細緻了解資料本質 。
## 線性迴歸線
## 線性迴歸直 線
如您在第一課學到的,線性迴歸的目標是能繪出一條線, 以:
如第一課所學,線性迴歸的目的是畫出一條線,用 以:
- < strong > 展示變數間關係< / strong > 。展現變數的相互關係
- < strong > 進行預測< / strong > 。準確預測新資料點在線上的落點
- < strong > 顯示變數關係< / strong > 。展示變數間的關聯。
- < strong > 進行預測< / strong > 。對新數據點相較這條線的落點做出精準預測。
< strong > 最小平方法迴歸< / strong > 通常用於繪製此類線條。所謂「最小平方法」是指最小化模型總誤差的過程。對每個資料點,我們測量該點與迴歸線間的垂直距離(稱為 殘差)。
此類線通常由 < strong > 最小平方法回歸< / strong > 繪出。「最小平方法」指的是最小化模型總誤差的過程。對每筆資料點,測量實際點與迴歸線間的垂直距離(稱作 殘差)。
我們將這些距離平方,主要有兩個原因 :
這些距離會被平方,理由有二 :
1. < strong > 重視誤差大小而非方向< / strong > :誤差 -5 與誤差 +5 對我們而言應同等重要,平方能將所有誤差轉為正數 。
1. < strong > 大小勝過方向< / strong > :我們希望把 -5 與 +5 的誤差同等對待,平方後皆轉為正值 。
2. < strong > 對離群值加重懲罰< / strong > :平方會加重較大誤差的權重,促使線條貼近偏遠 點。
2. < strong > 懲罰離群點< / strong > :平方強化較大誤差權重,迫使線條更貼近遠離的 點。
接著將所有平方後的誤差相加,希望求出誤差和最小的那條線——這即是「最小平方法」的由來 。
接著將所有平方值加總。目標是找到能使平方誤差加總最低(最小值)的線,因此稱為「最小平方法」 。
> ** 🧮 為我展示數學推導 **
> ** 🧮 數學公式展現 **
>
> 這條線稱為_最適合線_, 可用[一個方程 ](https://en.wikipedia.org/wiki/Simple_linear_regression)表示 :
> 此線稱為_最佳擬合線_,可用[以下方程式表達 ](https://en.wikipedia.org/wiki/Simple_linear_regression):
>
> ```
> Y = a + bX
> ```
>
> `X` 為「解釋變數」;`Y` 為「應變數」。線的斜率是 `b` ,而 `a` 是 y 截距,表示當 `X = 0` 時 `Y` 的數 值。
>
>
>
> 首 先計算斜率 `b` 。資訊圖由 [Jen Looper ](https://twitter.com/jenlooper ) 提供
>
> 換句話說,針對南瓜資料的原始問題:「根據月份預測每蒲式耳南瓜價格」,`X` 是指價格而 `Y` 是銷售的月份。
>
>
>
> 計算 Y 的數值。如果您付約 $4, 就應該是四月! 資訊圖由 [Jen Looper ](https://twitter.com/jenlooper ) 提供
>
> 計算該線的數學必須展示斜率,也取決於截距,也就是 `X = 0` 時 `Y` 所在位置。
>
> 您 可參考 [Math is Fun ](https://www.mathsisfun.com/data/least-squares-regression.html ) 網站來觀察此計算方法;也可使用 [此最小平方法計算器 ](https://www.mathsisfun.com/data/least-squares-calculator.html ) 來觀察數字如何影響迴歸線 。
>
> `X` 是「解釋變數」,`Y` 是「被解釋變數」。線的斜率是 `b` , `a` 是 y 軸截距,即當 `X = 0` 時的 `Y` 值。
>
>
>
> 先計算斜率 `b` 。資訊圖表 由 [Jen Looper ](https://twitter.com/jenlooper ) 製作。
>
> 換句話說,根據我們的南瓜數據的問題:「依月份預測每蒲式耳南瓜價格」,`X` 指價格,`Y` 指銷售月份。
>
>
>
> 計算 Y 的值。如果你付了約 4 美元,那一定是四月!資訊圖表由 [Jen Looper ](https://twitter.com/jenlooper ) 製作。
>
> 計算線條的數學必須反映出斜率,也取決於截距,即當 `X = 0` 時 `Y` 的位置。
>
> 你 可參考 [Math is Fun ](https://www.mathsisfun.com/data/least-squares-regression.html ) 網站了解計算方法,也可以使用[這個最小平方法計算器](https://www.mathsisfun.com/data/least-squares-calculator.html) 觀察數值如何影響線條 。
## 相關係數
另一重要詞彙是給定 `X` 與 `Y` 變數間的< strong > 相關係數</ strong > 。透過散點圖,您能快速直觀地看見此係數。若資料點沿著一條整齊的線散佈,代表高度相關;若資料點分佈分散在 `X` 和 `Y` 之間,則代表相關性 低。
另一重要概念是給定 X 和 Y 變數間的< strong > 相關係數< / strong > 。利用散佈圖,能快速看出相關輕重。若資料點沿一條整齊線排列,相關程度高;若資料點在 X、Y 間散布成零散狀,則相關度 低。
一個好的線性迴歸模型,其相關係數用最小平方法計算得到的值應該是高的(接近 1, 而非 0) 。
一個良好的線性迴歸模型,會有接近 1( 比 0 大得多)的高相關係數,並採用最小平方法找到最適回歸線 。
✅ 執行本課附帶的筆記本並觀察「月份對價格」的散點圖。從這散點圖視覺判斷,與南瓜銷售之月對價格的資料,看起來是高還是低相關?如果改為使用更細緻的時間尺度取代月份,例如「一年中第幾天」(自年初起的天數 ),結果會改變嗎?
✅ 執行本課附帶的 notebook, 觀察「月份對價格」的散佈圖。依你目測, 南瓜銷售的「月份/ 價格」資料是高相關還是低相關? 換用更細膩的時間單位, 如「年中第幾天」( Day of Year ),結果會改變嗎?
接下來的程式中,我們假設資料已清理完畢,並產生類似以下的 `new_pumpkins` 資料框 :
下面程式碼示範假設資料已清理乾淨,並取得名為 `new_pumpkins` 的資料框,內容大致如下 :
ID | 月份 | 一年中第幾天 | 品種 | 城市 | 包裝 | 最低價 | 最高價 | 價格
---|-----|--------|------|------|-------|-------|-------|-------
70 | 9 | 267 | 派用型 | 巴爾的摩 | 1又1/9蒲式耳箱 | 15.0 | 15.0 | 13.636364
71 | 9 | 267 | 派用型 | 巴爾的摩 | 1又1/9蒲式耳箱 | 18.0 | 18.0 | 16.363636
72 | 10 | 274 | 派用型 | 巴爾的摩 | 1又1/9蒲式耳箱 | 18.0 | 18.0 | 16.363636
73 | 10 | 274 | 派用型 | 巴爾的摩 | 1又1/9蒲式耳箱 | 17.0 | 17.0 | 15.454545
74 | 10 | 281 | 派用型 | 巴爾的摩 | 1又1/9蒲式耳箱 | 15.0 | 15.0 | 13.636364
ID | Month | DayOfYear | Variety | City | Package | Low Price | High Price | Price
---|-------|-----------|---------|------|---------|-----------|------------|-------
70 | 9 | 267 | PIE TYPE | BALTIMORE | 1 1/9 bushel cartons | 15.0 | 15.0 | 13.636364
71 | 9 | 267 | PIE TYPE | BALTIMORE | 1 1/9 bushel cartons | 18.0 | 18.0 | 16.363636
72 | 10 | 274 | PIE TYPE | BALTIMORE | 1 1/9 bushel cartons | 18.0 | 18.0 | 16.363636
73 | 10 | 274 | PIE TYPE | BALTIMORE | 1 1/9 bushel cartons | 17.0 | 17.0 | 15.454545
74 | 10 | 281 | PIE TYPE | BALTIMORE | 1 1/9 bushel cartons | 15.0 | 15.0 | 13.636364
> 資料清理的程式碼請參見 [`notebook.ipynb` ](notebook.ipynb )。我們執行了與上一課相同的清理步驟,並用下式計算出 `DayOfYear` 欄位:
> 清理資料的程式碼可在 [`notebook.ipynb` ](notebook.ipynb ) 中找到。我們做了和前一課相同的清理步驟,`DayOfYear` 欄位是用以下公式計算的:
```python
day_of_year = pd.to_datetime(pumpkins['Date']).apply(lambda dt: (dt-datetime(dt.year,1,1)).days)
```
現在您已了解線性迴歸的數學原理,讓我們建立迴歸模型,看看是否能預測出哪種包裝的南瓜價格最划算。想要打造南瓜節慶角落的購買者,會希望知悉這資訊以最佳化南瓜包裝的購買決策 。
理解線性迴歸背後的數學後,讓我們來建立一個迴歸模型,看看能否預測哪種包裝的南瓜價格較低。要在節慶南瓜園採購南瓜時,這資訊有助於優化選購方案 。
## 尋找相關性
[](https://youtu.be/uoRq-lW2eQo "機器學習入門 - 尋找相關性:線性迴歸的關鍵")
[](https://youtu.be/uoRq-lW2eQo "初學者 機器學習 - 尋找相關性:線性迴歸的關鍵")
> 🎥 點擊上方圖片觀看相關性的簡短影片概述 。
> 🎥 點擊圖片觀看相關性的簡短影片介紹 。
在先前的課堂中,您大概已看到不同月份的平均價格如下 :
前一課你可能已見過不同月份平均價格如下圖 :
< img alt = "各月份平均價格" src = "../../../../translated_images/zh-HK/barchart.a833ea9194346d76.webp" width = "50%" / >
這顯示應該存在某種相關性,我們可以嘗試訓練線性迴歸模型來預測 `Month` 與 `Price` 或 `DayOfYear` 與 `Price` 間的關係。下圖展示後者的散點 圖:
這代表應該會有某種相關性,我們可以嘗試訓練線性迴歸模型,去預測 `Month` 與 `Price` 或 `DayOfYear` 與 `Price` 之間的關係。下圖是後者的散佈 圖:
< img alt = "價格與 一年中第幾天散點 圖" src = "../../../../translated_images/zh-HK/scatter-dayofyear.bc171c189c9fd553.webp" width = "50%" / >
< img alt = "價格與 年中日散佈 圖" src = "../../../../translated_images/zh-HK/scatter-dayofyear.bc171c189c9fd553.webp" width = "50%" / >
我們用 `corr` 函式來看看有無相關性 :
讓我們用 `corr` 函式檢視相關係數 :
```python
print(new_pumpkins['Month'].corr(new_pumpkins['Price']))
print(new_pumpkins['DayOfYear'].corr(new_pumpkins['Price']))
```
看來相關性非常小,使用 `Month` 為 -0.15,使用 `DayOfMonth` 為 -0.17,但可能還有另一個重要的關係。價格在不同南瓜品種間似乎分成不同群聚。為了驗證此假設,我們用不同顏色來繪製各南瓜類別。透過給 `scatter` 函式傳入 `ax` 參數,可以將所有點繪製在同一張圖上 :
看起來相關性偏低,`Month` 約為 -0.15, `DayOfYear` 約 -0.17,但似乎有其他重要因素。不同南瓜品種對應不同價格群聚。為驗證,將每種南瓜用不同顏色繪圖。傳入 `ax` 參數至 `scatter` 繪圖函式可同時在同張圖上繪出所有點 :
```python
ax=None
@ -140,75 +139,75 @@ for i,var in enumerate(new_pumpkins['Variety'].unique()):
df = new_pumpkins[new_pumpkins['Variety']==var]
ax = df.plot.scatter('DayOfYear','Price',ax=ax,c=colors[i],label=var)
```
< img alt = "一年中第幾天與價格散點圖(有顏色區分)" src = "../../../../translated_images/zh-HK/scatter-dayofyear-color.65790faefbb9d54f.webp" width = "50%" / >
研究顯示品種對價格影響比銷售日期更大。我們用長條圖來說明:
< img alt = "價格與年中日散佈圖(彩色品種區分)" src = "../../../../translated_images/zh-HK/scatter-dayofyear-color.65790faefbb9d54f.webp" width = "50%" / >
結果顯示品種對價格影響較大,勝過實際銷售日期。下圖柱狀圖呈現此結果:
```python
new_pumpkins.groupby('Variety')['Price'].mean().plot(kind='bar')
```
< img alt = "品種與價格長條圖" src = "../../../../translated_images/zh-HK/price-by-variety.744a2f9925d9bcb4.webp" width = "50%" / >
暫時只聚焦於一種南瓜品種「派用型」,來看看日期對價格的影響:
< img alt = "不同品種價格柱狀圖" src = "../../../../translated_images/zh-HK/price-by-variety.744a2f9925d9bcb4.webp" width = "50%" / >
暫時只聚焦於南瓜品種中的「派用型」( pie type) , 觀察日期對價格的影響:
```python
pie_pumpkins = new_pumpkins[new_pumpkins['Variety']=='PIE TYPE']
pie_pumpkins.plot.scatter('DayOfYear','Price')
```
< img alt = " 一天中日期與價格散點圖 " src = "../../../../translated_images/zh-HK/pie-pumpkins-scatter.d14f9804a53f927e.webp" width = "50%" / >
< img alt = " 價格與年中日散佈圖(派用型) " src = "../../../../translated_images/zh-HK/pie-pumpkins-scatter.d14f9804a53f927e.webp" width = "50%" / >
如果這時用 `corr` 函式計算 `Price` 與 `DayOfYear` 的相關性,大約是 `-0.27` ,意味著訓練預測模型是合理 的。
接著以 `corr` 函式計算 `Price` 與 `DayOfYear` 的相關係數,可能得出約 `-0.27` ,顯示訓練預測模型是有意義 的。
> 在訓練線性迴歸前,務必確保資料乾淨。線性迴歸對缺漏值不友善,因此最好去除所有空值儲存格 :
> 訓練線性迴歸模型前,務必確認資料是乾淨的。線性迴歸不適用於遺失值,因此應排除所有空白欄位 :
```python
pie_pumpkins.dropna(inplace=True)
pie_pumpkins.info()
```
另一個作法是使用相對應欄位的平均值填充這些空值 。
另一種做法是用該欄位平均值填補空白資料 。
## 簡單線性迴歸
[](https://youtu.be/e4c_UP2fSjg "機器學習入門 - 使用 Scikit-learn 線性與多項式迴歸")
[](https://youtu.be/e4c_UP2fSjg "初學者 機器學習 - 使用 Scikit-learn 的 線性與多項式迴歸")
> 🎥 點擊上方圖片觀看線性與多項式迴歸的簡短影片概述 。
> 🎥 點擊圖片觀看線性及多項式迴歸的簡短影片介紹 。
我們將使用 **Scikit-learn** 函式庫來訓練線性迴歸模型 。
訓練線性迴歸模型時,我們會使用 **Scikit-learn** 函式庫 。
```python
from sklearn.linear_model import LinearRegression
from sklearn.metrics import mean_squared_error
from sklearn.model_selection import train_test_split
```
首先將輸入值(特徵)與預期輸出(標籤)分開存成 numpy 陣列:
我們先將輸入特徵( features) 與預期輸出( label) 分別存為兩個 numpy 陣列:
```python
X = pie_pumpkins['DayOfYear'].to_numpy().reshape(-1,1)
y = pie_pumpkins['Price']
```
> 注意我們必須對輸入資料做 `reshape` ,讓線性迴歸模組可正確理解。線性迴歸要求輸入為二維陣列,陣列中每一列代表一組輸入特徵向量。由於我們只有一個輸入特徵,故需為形狀 N× 1 的陣列, N 為資料集大小。
接著,需將資料劃分為訓練集和測試集,以便訓練後驗證模型:
> 注意我們必須對輸入資料做 `reshape` ,讓 Linear Regression 套件能識別。線性迴歸期待輸入為二維陣列,每列為一組特徵向量。因為我們只有一個輸入變數,須將陣列形狀調整為 N× 1, 其中 N 是資料筆數。
接著,將資料切分成訓練集與測試集,方便訓練後評估模型:
```python
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=0)
```
最後,訓練線性迴歸模型只需兩行程式:定義 `LinearRegression` 物件,並用 `fit` 方法擬合模型 :
最後,訓練線性迴歸模型只要兩行程式碼。定義 `LinearRegression` 物件,並用 `fit` 方法套用資料 :
```python
lin_reg = LinearRegression()
lin_reg.fit(X_train,y_train)
```
` fit` 後的 `LinearRegression` 對象包含了回歸的所有係數,可以通過 `.coef_` 屬性訪問。在我們的情況下 ,只有一個係數,應該約為 `-0.017` 。這意味著價格似乎 隨時間略有下降,但不多,大約每天下降 2 分錢。我們還可以使用 `lin_reg.intercept_` 訪問回歸與 Y 軸的交點 — 在我們的情況下將 約為 `21` ,表示年初的價格。
` LinearRegression` 對象在 `fit` 之後包含了迴歸的所有係數,可以通過 `.coef_` 屬性訪問。在我們的例子中 ,只有一個係數,應該約為 `-0.017` 。這意味著價格隨時間略有下降,但不多,大約每天下降 2 分錢。我們還可以通過 `lin_reg.intercept_` 訪問迴歸與 Y 軸的截距 — 在我們的例子中 約為 `21` ,表示年初的價格。
為了查看我們模型的準確度, 我們可以在測試數據集上進行價格預測, 然後測量預測值與預期值的接近程度。這可以通過均方根誤差( RMSE) 指標完成, 該指標是所有預期值與預測值差的平方平均 的平方根。
為了檢視模型的準確度,我們可以在測試數據集上預測價格,然後測量預測結果與期望值的接近程度。這可以使用均方根誤差 (RMSE) 指標計算,即期望值與預測值所有平方差均值 的平方根。
```python
pred = lin_reg.predict(X_test)
@ -217,15 +216,15 @@ rmse = np.sqrt(mean_squared_error(y_test,pred))
print(f'RMSE: {rmse:3.3} ({rmse/np.mean(pred)*100:3.3}%)')
```
我們的誤差約為 2 點,約為 17%。不太理想。另一個模型質量的指標是 < strong > 決定係數< / strong > ,可以如下 獲得:
我們的誤差約為 2 點,約為 17%。表現不是很好。另一個評估模型質量的指標是 < strong > 決定係數< / strong > ,可以這樣 獲得:
```python
score = lin_reg.score(X_train,y_train)
print('Model determination: ', score)
```
若該值為 0, 表示模型未考慮輸入數據, 行為就像< em > 最差的 線性預測器< / em > ,即結果的均值。值為 1 表示我們可以完美預測所有預期輸出。在我們的情況下,係數約為 0.06,較 低。
如果值為 0, 表示模型沒有考慮輸入數據, 表現為< em > 最差 線性預測器< / em > ,即結果的平 均值。值為 1 表示我們可以完美預測所有預期輸出。在我們的例子中,係數約為 0.06,相當 低。
我們還可以將測試數據與回歸線繪製在一起,以更好地觀察回歸情況 :
我們還可以將測試數據與迴歸線一起繪圖,更清楚地觀察迴歸效果 :
```python
plt.scatter(X_test,y_test)
@ -234,19 +233,19 @@ plt.plot(X_test,pred)
< img alt = "Linear regression" src = "../../../../translated_images/zh-HK/linear-results.f7c3552c85b0ed1c.webp" width = "50%" / >
## 多項式回 歸
## 多項式迴 歸
另一種線性回歸是多項式回歸。有時變量之間呈線性關係——比如體積越大的南瓜價格越高——但有時這種 關係無法用平面或直線表示。
另一種線性迴歸類型是多項式迴歸。有時候變量之間是線性關係 — 譬如南瓜體積越大,價格越高 — 但有時這些 關係無法用平面或直線表示。
✅ 這裡有[一些額外範例](https://online.stat.psu.edu/stat501/lesson/9/9.8)數據適合用多項式回歸
✅ 這裡有一些[更多範例](https://online.stat.psu.edu/stat501/lesson/9/9.8)適合使用多項式迴歸的資料
再看看日期和價格的關係。這個散點圖是否一定要用直線分析?價格難道不會波動嗎?這種情況下,可以嘗試多項式回 歸。
再看看日期與價格的關係。散點圖是否一定要用直線分析?價格難道不會波動?此時可以嘗試多項式迴 歸。
✅ 多項式是由一個或多個變量及係數構成 的數學表達式
✅ 多項式是可能包含一個或多個變量及係數 的數學表達式
多項式回歸產生一條曲線,更好地擬合非線性數據。在我們的案例中,若將平方的 `DayOfYear` 變量加入輸入資料,應能用拋物線曲線擬合數據,曲線在一年中某點處 有最小值。
多項式迴歸會擬合曲線以更好地適應非線性資料。在我們的例子中,如果將平方的 `DayOfYear` 變量加入輸入資料,就能用拋物線擬合數據,且拋物線會在年度中的某點 有最小值。
Scikit-learn 提供了方便 的[管道 API](https://scikit-learn.org/stable/modules/generated/sklearn.pipeline.make_pipeline.html?highlight=pipeline#sklearn.pipeline.make_pipeline)來將不同的數據處理步驟組合起來 。< strong > 管道< / strong > 是一系列 的< strong > 估計器< / strong > 。在這裡,我們創建一個管道,先加入多項式特徵,然後進行回歸訓練 :
Scikit-learn 提供了實用 的[管道 API](https://scikit-learn.org/stable/modules/generated/sklearn.pipeline.make_pipeline.html?highlight=pipeline#sklearn.pipeline.make_pipeline),用來串聯資料處理的各步驟 。< strong > 管道< / strong > 是一連串 的< strong > 估計器< / strong > 。在此,我們會先產生多項式特徵,再培訓迴歸模型 :
```python
from sklearn.preprocessing import PolynomialFeatures
@ -257,36 +256,58 @@ pipeline = make_pipeline(PolynomialFeatures(2), LinearRegression())
pipeline.fit(X_train,y_train)
```
使用 `PolynomialFeatures(2)` 表示我們將包含所有二次項多項式。對於一個變量僅為 `DayOfYear` 的平方,但對兩個輸入變量 X 和 Y 則為 X< sup > 2</ sup > 、XY、Y< sup > 2</ sup > 。我們也可以使用更高次多項式。
使用 `PolynomialFeatures(2)` 表示我們將包括輸入數據中所有二次多項式。對我們來說,只有 `DayOfYear` < sup > 2</ sup > ,但如果有兩個輸入變量 X 與 Y, 則會加上 X< sup > 2</ sup > 、XY 與 Y< sup > 2</ sup > 。如果想,也可以使用更高次數的多項式。
管道的用法與原本的 `LinearRegression` 物件相同,即先 `fit` 管道,接著用 `predict` 得到預測結果:
```python
pred = pipeline.predict(X_test)
rmse = np.sqrt(mean_squared_error(y_test,pred))
print(f'RMSE: {rmse:3.3} ({rmse/np.mean(pred)*100:3.3}%)')
score = pipeline.score(X_train,y_train)
print('Model determination: ', score)
```
為了繪製平滑擬合曲線,我們使用 `np.linspace` 產生均勻分布的輸入值,而非直接在無序的測試資料中繪圖(否則線條會鋸齒狀):
```python
X_range = np.linspace(X_test.min(), X_test.max(), 100).reshape(-1,1)
y_range = pipeline.predict(X_range)
plt.scatter(X_test, y_test)
plt.plot(X_range, y_range)
```
管道可以像原始的 `LinearRegression` 對象那樣使用,即可 `fit` 管道,然後用 `predict` 獲取預測結果。下面的圖展示了測試數據和擬合的曲線:
以下是測試資料與擬合曲線的圖示 :
< img alt = "Polynomial regression" src = "../../../../translated_images/zh-HK/poly-results.ee587348f0f1f60b.webp" width = "50%" / >
使用多項式回歸,我們可以獲得稍低的均方誤差和更高的決定係數,但提升不明顯。需要考慮其他特徵!
使用多項式迴歸,我們可以得到稍低的 RMSE 與較高的決定係數,但幅度有限。我們還 需要考慮其他特徵!
> 你可以看到最小南瓜價格出現在萬聖節前後。你如何解釋這種現象?
> 你可以看到最低的南瓜價格出現在萬聖節附近。你怎麼解釋這個現象?
🎃 恭喜,你剛剛建立了一個能幫助預測派南瓜價格的模型。你也可以用同樣的方法針對所有南瓜品種建立模型,但那會很繁瑣。接下來學習如何將南瓜品種納入模型考慮!
🎃 恭喜你剛完成可以預測派用南瓜價格的模型。你大概也可以用同樣流程對其他南瓜種類進行建模,但會很費時。接下來讓我們學習如何將南瓜品種納入模型 !
## 類別特徵
理想狀況下,我們希望用同一模型預測不同南瓜品種的價格。但 `Variety` 欄位與 `Month` 不同,因為它包含非數字值。這類欄位稱為< strong > 類別特徵( categorical) </ strong > 。
理想情況下,我們希望能 用同一模型預測不同南瓜品種的價格。但 `Variety` 欄位與 `Month` 欄位 不同,因為它包含非數字的 值。這類欄位稱為< strong > 類別欄位(categorical) </ strong > 。
[](https://youtu.be/DYGliioIAE0 "ML for beginners - Categorical Feature Predictions with Linear Regression")
> 🎥 點擊上圖觀看簡短影片,了解如何使用類別特徵。
> 🎥 點擊上圖觀看使用類別特徵的簡短影片 。
這裡展示了平均價格與品種的關係:
這裡可以看到不同品種的平均價格 :
< img alt = "Average price by variety" src = "../../../../translated_images/zh-HK/price-by-variety.744a2f9925d9bcb4.webp" width = "50%" / >
要考慮品種,首先要將其轉為數字 形式,即< strong > 編碼< / strong > 。有幾種方法:
為了考慮品種,我們首先要將其轉換成數值 形式,即< strong > 編碼< / strong > 。有幾種方法:
* 簡單的< strong > 數字編碼< / strong > 會建一個包含各品種的表格,然後用對應索引替換品種名稱。這對線性回歸不是最佳方案,因為線性回歸使用索引的數字值乘以係數再加總,然而指標號碼和價格的關係顯然非線性,即使索引有特定排序也無法保證 。
* < strong > 獨熱編碼( One-hot encoding) </ strong > 則把 `Variety` 欄拆成 4 個不同欄位(每個品種一欄)。對應行屬該品種的欄位為 `1` ,否則為 `0` 。這意味著線性回歸中會有四個係數,分別表示各品種的「起始價格」或「額外價格」 。
* 簡單的 < strong > 數值編碼< / strong > 是建立一張不同品種的索引表,再將品種名以該表的索引數替代。這對線性迴歸不算好,因為線性迴歸直接用該數字乘上係數,然後加到結果中。我們的例子中,索引與價格的關係明顯非線性,即使我們確保索引有特定順序 。
* **One-hot 編碼** 會將 `Variety` 欄位拆成四個不同欄位,對應四種品種。每個欄位若該行是此品種則為 `1` ,否則為 `0` 。這會產生四個線性迴歸係數,分別代表每種南瓜品種的「基準價格」(或者更準確來說,是「額外價格」) 。
下面代碼演示如何獨熱編碼品種 :
下面的程式碼展示如何對品種使用 one-hot 編碼 :
```python
pd.get_dummies(new_pumpkins['Variety'])
@ -303,14 +324,14 @@ pd.get_dummies(new_pumpkins['Variety'])
1741 | 0 | 1 | 0 | 0
1742 | 0 | 1 | 0 | 0
要用獨熱編碼的品種作為輸入訓練線性回歸,只要正確初始化 `X` 和 `y` 數據即可 :
要用 one-hot 編碼品種的資料訓練線性迴歸,我們只要正確初始化 `X` 和 `y` :
```python
X = pd.get_dummies(new_pumpkins['Variety'])
y = new_pumpkins['Price']
```
其餘代碼與之前用於訓練線性回歸的相同。試驗後會看到均方誤差約相同,但決定係數大幅提升至約 77%。要想更精確,也可納入更多類別特徵和數值特徵,如 `Month` 或 `DayOfYear` 。為了拼成一個大 特徵陣列,可使用 `join` :
其餘程式碼與我們之前用來訓練線性迴歸的相同。如果你嘗試,你會發現均方誤差差不多,但決定係數大幅提升到約 77%。要得到更準確的預測,我們還可以考慮更多類別型特徵及數值型特徵,如 `Month` 或 `DayOfYear` 。為了合併成一個 特徵陣列,可使用 `join` :
```python
X = pd.get_dummies(new_pumpkins['Variety']) \
@ -320,11 +341,11 @@ X = pd.get_dummies(new_pumpkins['Variety']) \
y = new_pumpkins['Price']
```
這裡我們還考慮了 `City` 和 `Package` 類型,結果為 MSE 2.84(約 10%) , 決定係數 0.94!
這裡我們還加入了 `City` 和 `Package` 類型,結果是 RMSE 2.84( 10.5%)與 決定係數 0.94!
## 綜合應用
## 全面整合
為構建最佳模型,我們可以將上述示例中一熱編碼類別+數值的特徵結合多項式回歸。以下是完整代碼,方便參考 :
要做出最佳模型, 我們可以用上述合併的( one-hot 編碼類別 + 數值)特徵資料,同時套用多項式迴歸。方便起見,這是完整程式碼 :
```python
# 設置訓練數據
@ -334,46 +355,46 @@ X = pd.get_dummies(new_pumpkins['Variety']) \
.join(pd.get_dummies(new_pumpkins['Package']))
y = new_pumpkins['Price']
# 進行訓練和測試 分割
# 製作訓練和測試數據 分割
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=0)
# 設置並訓練流程
# 設置及訓練管道
pipeline = make_pipeline(PolynomialFeatures(2), LinearRegression())
pipeline.fit(X_train,y_train)
# 預測測試數據結果
pred = pipeline.predict(X_test)
# 計算均方誤差和決 定係數
mse = np.sqrt(mean_squared_error(y_test,pred) )
print(f'Mean error: {mse:3.3} ({mse/np.mean(pred )*100:3.3}%)')
# 計算均方根誤差及判 定係數
rmse = mean_squared_error(y_test, pred, squared=False )
print(f'RMSE: {rmse:3.3} ({rmse/pred.mean( )*100:3.3}%)')
score = pipeline.score(X_train,y_train)
print('Model determination: ', score)
```
預計獲得近乎 97% 的最佳決定係數,以及 MSE=2.23(約 8% 預測誤差)。
這應該會得到接近 97% 的最高決定係數, RMSE=2.23(約 8% 的 預測誤差)。
| 模型 | MSE | 決定係數 |
|-------|-----|--------------- |
| `DayOfYear` 線性 | 2.77 (17.2%) | 0.07 |
| `DayOfYear` 多項式 | 2.73 (17.0%) | 0.08 |
| `Variety` 線性 | 5.24 (19.7%) | 0.77 |
| 所有特徵 線性 | 2.84 (10.5%) | 0.94 |
| 所有特徵 多項式 | 2.23 (8.25%) | 0.97 |
| 模型 | R MSE | 決定係數 |
|-------|-----|---------|
| `DayOfYear` 線性迴歸 | 2.77 (17.2%) | 0.07 |
| `DayOfYear` 多項式迴歸 | 2.73 (17.0%) | 0.08 |
| `Variety` 線性迴歸 | 5.24 (19.7%) | 0.77 |
| 所有特徵 線性迴歸 | 2.84 (10.5%) | 0.94 |
| 所有特徵 多項式迴歸 | 2.23 (8.25%) | 0.97 |
🏆 做得好!本課程你建立了四種回歸模型,並將模型質量提升至 97%。最後一節關於回歸,會介紹用於分類 的邏輯迴歸。
🏆 做得好!你在一課中創建了四個迴歸模型,並將模型質量提升至 97%。在迴歸的最後部分,你將學習用來判別類別 的邏輯迴歸。
---
## 🚀挑戰
## 🚀 挑戰
試驗本筆記本中的多種變數,看看相關性如何影響模型準確度 。
在這個筆記本中嘗試幾個不同變量,看看它們的相關性如何對模型準確度造成影響 。
## [課後 測驗](https://ff-quizzes.netlify.app/en/ml/ )
## [課後 小 測驗](https://ff-quizzes.netlify.app/en/ml/ )
## 複習與自學
本課學習了線性回歸。還有其他重要的回歸類型。請閱讀逐步回歸、嶺回歸、套索回歸和彈性網技術。學習更多可參考 [史丹佛統計學習課程](https://online.stanford.edu/courses/sohs-ystatslearning-statistical-learning)
本課我們學到了線性迴歸。還有其他重要類型的迴歸。可以閱讀關於逐步、嶺回歸 (Ridge)、套索 (Lasso) 和彈性網路 (Elasticnet) 的技術。推薦研習的課程是 [史丹佛統計學習課程](https://online.stanford.edu/courses/sohs-ystatslearning-statistical-learning)
## 作業
@ -383,5 +404,5 @@ print('Model determination: ', score)
<!-- CO - OP TRANSLATOR DISCLAIMER START -->
**免責聲明**:
本文件由 AI 翻譯服務 [Co-op Translator ](https://github.com/Azure/co-op-translator ) 翻譯而成。雖然我們致力於準確性 ,請注意自動翻譯可能包含錯誤或不準確之處。原始文件的母語版本應被視為權威來源。對於重要資訊,建議聘請專業人工翻譯。對於因使用本翻譯而產生的任何誤解或錯誤詮釋,我們概不負責 。
本文件係使用 AI 翻譯服務 [Co-op Translator ](https://github.com/Azure/co-op-translator ) 翻譯而成。雖然我們致力於確保翻譯 準確,但 請注意, 自動翻譯可能包含錯誤或不準確之處。原始文件之原文版本應被視為權威來源。對於重要資訊,建議採用專業人工翻譯。我們不對因使用本翻譯而引致的任何誤解或誤譯承擔責任 。
<!-- CO - OP TRANSLATOR DISCLAIMER END -->