LASSO
(L
east A
bsolute S
hrinkage and S
election O
perator)迴歸模型一般都是用英文縮寫表示,
硬要翻譯的話,可翻譯為 最小絕對收縮和選擇運算元。
它是一種線性迴歸模型的擴充套件,其主要目標是解決高維資料中的特徵選擇和正則化問題。
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()
的預設引數來訓練模型,它的主要引數包括:
- alpha:正則化項係數。它控制了L1正則化項的強度,即對模型複雜度的懲罰。
alpha
越大,模型越簡單,但過大的alpha
可能會導致模型欠擬合;alpha
越小,模型越複雜,但過小的alpha
可能會導致模型過擬合。預設值為1.0。 - fit_intercept:布林值,指定是否需要計算截距b值。如果設為
False
,則不計算b值。預設值為True。 - normalize:布林值。如果設為
True
,則在模型訓練之前將資料歸一化。預設值為False。 - precompute:布林值,指定是否預先計算X的平方和。如果設為True,則在每次迭代之前計算X的平方和。預設值為False。
- copy_X:布林值,指定是否在訓練過程中複製
X
。如果設為True
,則在訓練過程中複製X
。預設值為True。 - max_iter:最大迭代次數。預設值為1000。
- tol:閾值,用於判斷是否達到收斂條件。預設值為1e-4。
- warm_start:布林值,如果設為
True
,則使用前一次的解作為本次迭代的起始點。預設值為False。 - positive:布林值,如果設為
True
,則強制係數為正。預設值為False。 - 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
可能會過度擬合這些模式。