iT邦幫忙

2025 iThome 鐵人賽

DAY 3
0
AI & Data

30 天入門常見的機器學習演算法系列 第 3

(Day 3) 多項式迴歸 (Polynomial Regression)

  • 分享至 

  • xImage
  •  

昨天介紹了線性迴歸 (Linear Regression),它適合用來處理特徵與目標之間為線性關係的情境。然而,真實世界的資料往往並非純粹線性,而是呈現複雜的非線性關係,例如曲線、拋物線、甚至更複雜的波動趨勢。

就有了多項式特徵 (Polynomial Feature) 的出現,而線性迴歸搭配多項式特徵,就是所謂的多項式迴歸 (Polynomial Regression),便是為了解決線性模型難以處理的非線性問題。它的核心概念非常簡單就是透過對特徵進行多項式轉換,使模型能夠捕捉非線性趨勢。

模型介紹

模型邏輯與核心概念

這塊幾乎與昨天介紹的線性迴歸一樣,重複的部分就不多做介紹。因為多項式迴歸本質上仍是線性迴歸,但特徵空間經過非線性轉換,讓模型能擬合更複雜的曲線。以下為多項式迴歸的公式:

$$
\hat{y} = \beta_0 + \beta_1 x + \beta_2 x^2 + \dots + \beta_d x^d
$$

  • d 稱為 polynomial degree (多項式階數),是模型中最重要的超參數之一。
  • 特徵不只可以加入單一變數的高次項,也可加入多個變數間的交互項 (例如 $x_1x_2$)。

運作原理

  • 假設方程式 (degree = 3): $\hat{y} = \beta_0 + \beta_1 x + \beta_2 x^2 + \beta_3 x^3$
    • 透過將輸入特徵 $x$ 映射為高階次多項式 (如 $x^2, x^3, \dots$),使模型能擬合彎曲或非線性趨勢,特徵會經過變換形成新的變數,然後再應用一般線性回歸模型進行估計。
  • degree = 3 (對所有 features 做所有「總次數 ≤ 3」的項次組合)
    • 多項式特徵的處理會產生新的特徵
    • 要特別注意,如果在特徵工程有人工建立交互項,不可直接使用 PolynomialFeatures 來處理,因為不會辨識你手動做出的交互項,會產生重複或邏輯不一致的問題,要特別處理。
      • 舉例: 假設有一組資料,特徵有 ['x1', 'x2'],設定 degree=3 做 PolynomialFeatures,這組資料的特徵會變成 ['x1', 'x2', 'x1^2', 'x1 x2', 'x2^2', 'x1^3', 'x1^2 x2', 'x1 x2^2', 'x2^3'],他會自動做交互項處理,如果有手動生成交互項就不能再做 PolynomialFeatures

適用情境

  • 當資料呈現曲線趨勢時,線性回歸無法捕捉其變化

限制條件

  • degree 過高,容易導致 Overfitting (尤其在資料量小時)
  • 高維度下容易產生特徵爆炸
  • 對比 Linear Regression 其模型可解釋性下降

模型實作

資料集介紹

將使用經典的 Boston Housing Dataset 為例。由於 scikit-learn 已移除該資料集,我們改採自 Carnegie Mellon University 所提供的公開版本。樣本內容如下:

Image_2025-08-01_22-34-54.png

欄位說明:

  • CRIM: 每人平均犯罪率
  • ZN: 區域住宅用地比例
  • INDUS: 區域非零售商業用地比例
  • CHAS: 查爾斯河虛擬變數 (1 = 河流旁, 0 = 其他)
  • NOX: 一氧化氮濃度 (parts per 10 million)
  • RM: 每個住宅的平均房間數
  • AGE: 1940 年之前建造的自用住宅比例
  • DIS: 到波士頓五個中心區域的加權距離
  • RAD: 公路接近指數 (1 = 最接近, 24 = 最遠)
  • TAX: 每 $10,000 的財產稅率
  • PTRATIO: 學生與教師比例
  • B: 1000(Bk - 0.63)^2, Bk = 區域黑人比例
  • LSTAT: 區域人口中低收入者的比例
  • MEDV: 自用住宅的中位數價格 (單位: $1000s)

程式實例

import requests
import pandas as pd
from sklearn.pipeline import Pipeline
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import PolynomialFeatures, StandardScaler
from sklearn.linear_model import LinearRegression
from sklearn.metrics import mean_squared_error, r2_score


def get_boston_housing_data() -> pd.DataFrame:
    url = "http://lib.stat.cmu.edu/datasets/boston"  # Boston Housing Dataset from Carnegie Mellon University
    raw_data = requests.get(url).text.splitlines()[22:]  # 從第 23 行開始
    
    # 每筆資料分為 2 行 → 共 506 筆 → 總共 1012 行
    data = []
    for i in range(0, len(raw_data), 2):
        line_1 = list(map(float, raw_data[i].strip().split()))
        line_2 = list(map(float, raw_data[i + 1].strip().split()))
        data.append(line_1 + line_2)
    
    column_names = [
        "CRIM",  # 每人平均犯罪率
        "ZN",  # 區域住宅用地比例
        "INDUS",  # 區域非零售商業用地比例
        "CHAS",  # 查爾斯河虛擬變數 (1 = 河流旁, 0 = 其他)
        "NOX",  # 一氧化氮濃度 (parts per 10 million)
        "RM",  # 每個住宅的平均房間數
        "AGE",  # 1940 年之前建造的自用住宅比例
        "DIS",  # 到波士頓五個中心區域的加權距離
        "RAD",  # 公路接近指數 (1 = 最接近, 24 = 最遠)
        "TAX",  # 每 $10,000 的財產稅率
        "PTRATIO",  # 學生與教師比例
        "B",  # 1000(Bk - 0.63)^2, Bk = 區域黑人比例
        "LSTAT",  # 區域人口中低收入者的比例
        "MEDV",  # 自用住宅的中位數價格 (單位: $1000s)
    ]
    
    df = pd.DataFrame(data, columns=column_names)

    return df

def main():
    # ----- 讀取資料 -----
    
    original_data = get_boston_housing_data()  # 讀取資料
    
    # ----- 資料前處理 -----
    
    cleaned_data = original_data.copy()
    
    ## 因透過 print(cleaned_data.isnull().sum()) 檢查缺失值 (0 筆)
    ## 且 Pearson 相關係數檢查,相關係數 >= 0.8 (0 筆)    
    ### correlation_matrix = cleaned_data.corr()
    ### target_corr = correlation_matrix['MEDV']
    ### high_corr_features = target_corr[target_corr > 0.8].drop('MEDV')
    ### print(f"與 target 高度正相關的欄位:", high_corr_features)
    ## 故不做資料前處理
    
    # ----- 模型訓練 -----
    
    ## 資料分割
    X = cleaned_data.drop(columns=["MEDV"])
    y = cleaned_data["MEDV"]
    X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
    
    ## 建立模型
    model = Pipeline([
        ("poly", PolynomialFeatures(degree=2, include_bias=False)),
        ("scaler", StandardScaler()),
        ("lr", LinearRegression())
    ])
    
    model.fit(X_train, y_train)
    
    ## 預測
    y_train_pred = model.predict(X_train)
    y_test_pred = model.predict(X_test)
    
    ## 評估
    train_mse = mean_squared_error(y_train, y_train_pred)
    train_r2 = r2_score(y_train, y_train_pred)
    print(f"train data 均方誤差 (MSE): {train_mse:.4f}")
    print(f"train data 決定係數 R²: {train_r2:.4f}")
    
    test_mse = mean_squared_error(y_test, y_test_pred)
    test_r2 = r2_score(y_test, y_test_pred)
    print(f"test data 均方誤差 (MSE): {test_mse:.4f}")
    print(f"test data 決定係數 R²: {test_r2:.4f}")

if __name__ == '__main__':
    main()

執行結果

  • train data 均方誤差 (MSE): 5.1315
  • train data 決定係數 R²: 0.9409
  • test data 均方誤差 (MSE): 14.2573
  • test data 決定係數 R²: 0.8056

結果評估

本次模型使用二次多項式特徵 (PolynomialFeatures(degree=2)) 結合標準化處理與線性回歸進行建模。

從評估指標來看:

  • 訓練資料 R² 為 0.9409,代表模型在訓練集上可以解釋 94.09% 的房價變異,表現非常良好。
  • 測試資料 R² 為 0.8056,雖略低於訓練結果,但仍能解釋 80.56% 的變異,泛化能力尚可接受。
  • 測試 MSE 為 14.2573,對應均方根誤差(RMSE)約為 $3,775 美元,表示模型對房價的預測誤差多集中於 ±4 千元內,具備實用性。

然而,我們也觀察到訓練與測試間的 R² 存在明顯落差 (0.94 → 0.81),這可能表示模型在高階特徵下已出現一定程度的過擬合 (overfitting) 現象,應持續關注其在新資料上的穩定性。

下一步建議

為進一步強化模型的泛化能力與解釋力,採取以下方向優化:

  • 嘗試正則化回歸 (如 Ridge / Lasso / Elastic Net)
    • 可有效控制多項式展開後參數數量膨脹所造成的 overfitting。
    • 搭配交叉驗證 (GridSearchCV) 選取最佳懲罰係數。
  • 特徵選擇與降維
    • 探索是否有冗餘或低貢獻的特徵,例如使用 SelectKBest、PCA、或基於模型的重要性 (feature importance) 進行刪減。
  • 異常值檢查與資料轉換
    • 若殘差分布存在明顯偏態,可考慮對目標變數 (如 MEDV) 做 log 轉換以提升穩定性。
    • 同時可檢查極端房價樣本對模型的影響程度 (例如 Cook’s distance)。

總體而言,本次結果已具備相當良好的建模基礎,後續重點將轉向「控制模型複雜度」與「提升泛化能力」,以邁向穩定、可解釋、可部署的預測系統。

結語

多項式迴歸提供了一個簡單卻強大的手段,讓我們能在不改變演算法本身的情況下,用非線性特徵轉換擴展模型的表達能力。只需對原始特徵做一次轉換,就能讓線性模型擬合出曲線趨勢,這正是它的魅力所在。

但能力越強,風險越高。多項式階數的提升固然能增加擬合度,但也極易導致過擬合 (overfitting),特別是在資料量有限或特徵多樣時。此時就需要引入新的工具來協助我們控制模型的複雜度──這就是「正則化迴歸」。

在邁向正則化模型之前,請記得: 多項式擬合本質上不是解決非線性的萬靈丹,它是一種「特徵空間重構」的技巧,適用於低維資料、可視化分析與 baseline 建立,但不適合直接套用在高維或多雜訊的真實問題中。


上一篇
(Day 2) 線性迴歸 (Linear Regression)
下一篇
(Day 4) 正規化迴歸 (Regularization Regression)
系列文
30 天入門常見的機器學習演算法30
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言