AI時代系列(1) 機器學習三部曲: 🔹 第一部:《機器學習 —— AI 智慧的啟航》
23/100 第三週:監督學習(回歸)
23. 正則化回歸(Lasso, Ridge, ElasticNet) 🎛 防止模型過擬合,讓預測能力更穩定!
🎛 正則化回歸(Lasso, Ridge, ElasticNet)
📌 防止模型過擬合,讓預測能力更穩定!
在多元線性回歸中,當特徵數量較多或特徵之間存在高相關性(共線性)時,模型容易過擬合(Overfitting),導致在測試集上的表現變差。正則化回歸(Regularization Regression) 透過 加入懲罰項 來限制模型的複雜度,使其更具泛化能力(Generalization)。
________________________________________
📌 1️⃣ 為什麼需要正則化回歸?
當模型過度擬合時,會發生什麼?
• 過擬合(Overfitting):模型在訓練數據表現很好,但在測試數據上表現很差
• 模型對噪聲過於敏感:如果有不相關的特徵,模型會錯誤地學習這些特徵
• 共線性問題:當特徵之間高度相關時,模型的權重係數(Weights)可能變得極端
📌 解決方案:使用 Lasso、Ridge、ElasticNet,讓模型更穩健!
________________________________________
📌 2️⃣ 正則化回歸的三種方法
🎯 (1) Ridge 回歸(L2 正則化)
• 核心概念:透過 L2 正則化,讓所有的回歸係數 wi 變小,而不會讓它們變為 0
• 適用情境:特徵較多,且希望「保留所有特徵」但減少過擬合
Ridge 回歸的公式,就是「模型預測誤差」加上「係數變大的懲罰」,兩者一起考慮,讓模型又準確又不會過度依賴某些特徵。
小比喻 🌟
就像一個人做事要準確(預測準確),但又不能用力過猛(係數太大),所以這個公式幫你兩邊兼顧,找到「準確但穩定」的好方案!
✅ 效果:
• 讓模型更穩定
• 減少過擬合,但不會讓某些權重變為 0
________________________________________
🎯 (2) Lasso 回歸(L1 正則化)
• 核心概念:透過 L1 正則化,可以讓某些特徵的權重變成 0,達到 特徵選擇(Feature Selection) 的效果
• 適用情境:當特徵較多,且希望「自動篩選不重要的特徵」
Lasso 回歸公式,就是「預測誤差」加上「係數大小的懲罰(用絕對值)」,這樣可以讓不重要的特徵自動被淘汰(權重變成 0),模型就會變得更簡單、更乾淨!
小比喻 🌟
你可以把它想像成:
做模型就像整理書架。Lasso 不只是整理書籍的順序,還會「直接把沒用的書丟掉」(係數變 0),讓你的書架(模型)乾淨又高效。
✅ 效果:
• 可自動選擇重要特徵,忽略不重要的特徵
• 當 α 變大時,部分特徵的 wi 變為 0
________________________________________
🎯 (3) ElasticNet 回歸(L1 + L2 正則化)
• 核心概念:結合 Lasso(L1)與 Ridge(L2),兼具「特徵選擇」與「防止過擬合」的效果
• 適用情境:特徵數量多,且有共線性問題
• 數學公式:ElasticNet 是把 Lasso(L1) 和 Ridge(L2) 兩種方法合併,既能「自動篩選掉不重要的特徵」,又能「避免模型過度依賴某些特徵」,達到平衡效果。
小比喻 🌟
你可以想像成:
ElasticNet 就像是在整理書櫃時,同時會
淘汰沒用的書(L1:特徵選擇),
又限制留下來的書不要佔太多空間(L2:防止過度依賴)。
✅ 效果:
• 讓部分權重變為 0(類似 Lasso)
• 但不會讓所有不重要的特徵完全消失(類似 Ridge)
________________________________________
📌 3️⃣ Python 實作(Ridge, Lasso, ElasticNet)
✅ (1) 產生數據
我們使用房價預測範例:
python
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.linear_model import Ridge, Lasso, ElasticNet, LinearRegression
from sklearn.model_selection import train_test_split
from sklearn.metrics import mean_squared_error, r2_score
# 產生隨機數據(50 筆數據)
np.random.seed(42)
X1 = np.random.randint(20, 200, size=50) # 房屋面積
X2 = np.random.randint(1, 50, size=50) # 房齡
X3 = np.random.randint(1, 10, size=50) # 樓層數
# 房價計算(模擬真實情況)
y = 5000 * X1 - 3000 * X2 + 2000 * X3 + 10000 + np.random.randint(-50000, 50000, size=50)
# 轉換為 DataFrame
df = pd.DataFrame({'面積': X1, '房齡': X2, '樓層': X3, '房價': y})
# 分割訓練集與測試集
X = df[['面積', '房齡', '樓層']]
y = df['房價']
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
________________________________________
✅ (2) 訓練模型
python
# 訓練普通線性回歸
lin_reg = LinearRegression()
lin_reg.fit(X_train, y_train)
# 訓練 Ridge 回歸(L2 正則化)
ridge_reg = Ridge(alpha=1.0)
ridge_reg.fit(X_train, y_train)
# 訓練 Lasso 回歸(L1 正則化)
lasso_reg = Lasso(alpha=1.0)
lasso_reg.fit(X_train, y_train)
# 訓練 ElasticNet 回歸(L1 + L2 正則化)
elasticnet_reg = ElasticNet(alpha=1.0, l1_ratio=0.5)
elasticnet_reg.fit(X_train, y_train)
________________________________________
✅ (3) 預測與評估
python
models = {
"線性回歸": lin_reg,
"Ridge 回歸": ridge_reg,
"Lasso 回歸": lasso_reg,
"ElasticNet 回歸": elasticnet_reg
}
for name, model in models.items():
y_pred = model.predict(X_test)
mse = mean_squared_error(y_test, y_pred)
r2 = r2_score(y_test, y_pred)
print(f"{name} - MSE: {mse:.2f}, R²: {r2:.4f}")
📌 結果解析
• 線性回歸(Linear Regression):可能會過擬合
• Ridge(L2):減少過擬合,但所有特徵仍被保留
• Lasso(L1):可能會將部分不重要特徵的權重設為 0
• ElasticNet(L1 + L2):適合特徵較多的情況,綜合 Lasso & Ridge 的優勢
________________________________________
📌 4️⃣ 如何選擇?
Ridge(L2 正則化)適合在特徵數量較多,但希望保留所有特徵的情境使用,它的優點是能有效降低過擬合風險,讓模型更穩定,但缺點是無法自動挑選出重要特徵,所有特徵都會被保留下來。
相比之下,Lasso(L1 正則化)更適用於當希望自動篩選出最重要特徵的場合,它的優勢在於可以讓部分特徵的權重變成零,實現特徵選擇,不過有時也可能過度忽略掉一些其實有用的特徵。
至於 ElasticNet 則結合了 Ridge 和 Lasso 的優點,特別適合特徵數量龐大又存在共線性問題的情境,它同時具備防止過擬合與自動篩選特徵的效果,但需要額外調整兩個超參數,才能達到最佳效果。
________________________________________
🎯 結論
✅ Ridge(L2):防止過擬合,適合特徵較多的情況
✅ Lasso(L1):能自動選擇重要特徵,適合特徵較多但部分不相關的數據
✅ ElasticNet(L1+L2):適合特徵相關性較高的情境
🚀 下一步:進一步探索「多項式回歸」來處理非線性關係! 🎯