【scikit-learn基礎】--『監督學習』之 LASSO迴歸

wang_yb發表於2023-12-28

LASSOLeast Absolute Shrinkage and Selection Operator)迴歸模型一般都是用英文縮寫表示,
硬要翻譯的話,可翻譯為 最小絕對收縮和選擇運算元

它是一種線性迴歸模型的擴充套件,其主要目標是解決高維資料中的特徵選擇和正則化問題。

1. 概述

LASSO中,透過使用L1正則化項,它能夠在迴歸係數中引入稀疏性,
也就是允許某些係數在最佳化過程中縮減為零,從而實現特徵的選擇。

與嶺迴歸不同的是,LASSO的損失函式一般定義為:\(L(w) = (y-wX)^2+\lambda\parallel w\parallel_1\)
其中 \(\lambda\parallel w\parallel_1\),也就是 L1正則化項(嶺迴歸中用的是 L2正則化項)。

模型訓練的過程就是尋找讓損失函式\(L(w)\)最小的引數\(w\)
也就等價於:\(\begin{align} & arg\ min(y-wX)^2 \\ & s.t. \sum |w_{ij}| < s \end{align}\)
這兩個公式表示,在滿足約束條件 \(\sum |w_{ij}| < s\)的情況下,計算 \((y-wX)^2\)的最小值。

2. 建立樣本資料

相比於嶺迴歸模型,LASSO迴歸模型不僅對於共線性資料集友好,
對於高維資料的資料集,也有不錯的效能表現。

它透過將不重要的特徵的係數壓縮為零,幫助我們選擇最重要的特徵,從而提高模型的預測準確性和可解釋性。
下面我們模擬建立一些高維資料,建立一個特徵數比樣本數還多的樣本資料集。

from sklearn.datasets import make_regression

X, y = make_regression(n_samples=80, n_features=100, noise=10)

這個資料集中,只有80個樣本,每個樣本卻有100個特徵,並且噪聲也設定的很大(noise=10)。

3. 模型訓練

第一步,分割訓練集測試集

from sklearn.model_selection import train_test_split

# 分割訓練集和測試集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.1)

scikit-learn中的LASSO模型來訓練:

from sklearn.linear_model import Lasso

# 初始化LASSO線性模型
reg = Lasso()
# 訓練模型
reg.fit(X_train, y_train)

這裡使用的 Lasso()的預設引數來訓練模型,它的主要引數包括:

  1. alpha:正則化項係數。它控制了L1正則化項的強度,即對模型複雜度的懲罰。alpha越大,模型越簡單,但過大的alpha可能會導致模型欠擬合;alpha越小,模型越複雜,但過小的alpha可能會導致模型過擬合。預設值為1.0
  2. fit_intercept:布林值,指定是否需要計算截距b值。如果設為False,則不計算b值預設值為True
  3. normalize:布林值。如果設為True,則在模型訓練之前將資料歸一化。預設值為False
  4. precompute:布林值,指定是否預先計算X的平方和。如果設為True,則在每次迭代之前計算X的平方和。預設值為False
  5. copy_X:布林值,指定是否在訓練過程中複製X。如果設為True,則在訓練過程中複製X預設值為True
  6. max_iter:最大迭代次數。預設值為1000
  7. tol:閾值,用於判斷是否達到收斂條件。預設值為1e-4
  8. warm_start:布林值,如果設為True,則使用前一次的解作為本次迭代的起始點。預設值為False
  9. positive:布林值,如果設為True,則強制係數為正。預設值為False
  10. selection:用於在每次迭代中選擇係數的演演算法(有“cyclic”和“random”兩種選擇)。預設值為“cyclic”,即迴圈選擇。

最後驗證模型的訓練效果:

from sklearn import metrics

y_pred = reg.predict(X_test)
mse = metrics.mean_squared_error(y_test, y_pred)
r2 = metrics.r2_score(y_test, y_pred)
m_error = metrics.median_absolute_error(y_test, y_pred)

print("均方誤差:{}".format(mse))
print("複相關係數:{}".format(r2))
print("中位數絕對誤差:{}".format(m_error))

# 執行結果
均方誤差:441.07830708712186
複相關係數:0.9838880665687711
中位數絕對誤差:11.643348614829785

誤差看上去不小,因為這次實際生成的樣本,不僅數量小(80件)且噪聲大(noise=10)。

3.1. 與嶺迴歸模型比較

單獨看LASSO模型的訓練結果,看不出其處理高維資料的優勢。
同樣用上面分割好的訓練集測試集,來看看嶺迴歸模型的擬合效果。

from sklearn.linear_model import Ridge
# from sklearn.model_selection import train_test_split

mse, r2, m_error = 0.0, 0.0, 0.0

# 初始化嶺迴歸線性模型
reg = Ridge()
# 訓練模型
reg.fit(X_train, y_train)

y_pred = reg.predict(X_test)
mse = metrics.mean_squared_error(y_test, y_pred)
r2 = metrics.r2_score(y_test, y_pred)
m_error = metrics.median_absolute_error(y_test, y_pred)

print("均方誤差:{}".format(mse))
print("複相關係數:{}".format(r2))
print("中位數絕對誤差:{}".format(m_error))

# 執行結果
均方誤差:6315.046844910431
複相關係數:0.7693207470296398
中位數絕對誤差:60.65140692273637

對於高維資料,可以看出,嶺迴歸模型的誤差 遠遠大於 LASSO模型。

3.2. 與最小二乘法模型比較

同樣用上面分割好的訓練集測試集,再來看看線性模型(最小二乘法)的擬合效果。

from sklearn.linear_model import LinearRegression

mse, r2, m_error = 0.0, 0.0, 0.0

# 初始化最小二乘法線性模型
reg = LinearRegression()
# 訓練模型
reg.fit(X_train, y_train)

y_pred = reg.predict(X_test)
mse = metrics.mean_squared_error(y_test, y_pred)
r2 = metrics.r2_score(y_test, y_pred)
m_error = metrics.median_absolute_error(y_test, y_pred)

print("均方誤差:{}".format(mse))
print("複相關係數:{}".format(r2))
print("中位數絕對誤差:{}".format(m_error))

# 執行結果
均方誤差:5912.442445894787
複相關係數:0.7840272859181612
中位數絕對誤差:62.89225147465376

可以看出,線性模型的訓練效果和嶺迴歸模型差不多,但是都遠遠不如LASSO模型

4. 總結

總的來說,LASSO迴歸模型是一種流行的線性迴歸擴充套件,具有一些顯著的優勢和劣勢。
比如,在特徵選擇上,LASSO透過將某些係數壓縮為零,能夠有效地進行特徵選擇,這在高維資料集中特別有用。
此外,LASSO可以作為正則化工具,有助於防止過擬合。

不過,LASSO會假設特徵是線性相關的,對於非線性關係的資料,效果可能不佳。
而且,如果資料存在複雜模式或噪聲,LASSO可能會過度擬合這些模式。

相關文章