對模型參數進行限制或者規范化能將一些參數朝着0收縮(shrink)。使用收縮的方法的效果提升是相當好的,嶺回歸(ridge regression,后續以ridge代稱),lasso和彈性網絡(elastic net)是常用的變量選擇的一般化版本。彈性網絡實際上是結合了嶺回歸和lasso的特點。
Lasso和Ridge比較
- Lasso的目標函數:
- Ridge的目標函數:
- ridge的正則化因子使用二階范數,雖然ridge可以將參數估計值向0收縮,但對於任何調優后的參數值,它都無法將某些參數值變為嚴格的0,盡管某些參數估計值變得非常小以至於可以忽略,但實際上它並沒有進行變量選擇。所以L1范數和L2范數正則化都有助於降低過擬合風險,但L1范數還帶來一個額外的好處,它比L2范數更易於獲得“稀疏(sparse)”解,即它所求的w會有更少的非零分量。
- 為何ridge到lasso,從L2范數變成L1范數,lasso就能夠把參數估計收縮為0而ridge就不行呢?對於Lasso而言,優化下面兩個方程是等價的:
也就是說,對每個超參λ,都存在相應的s值,使得上面兩個方程優化后得到的參數估計相同。
類似的,對於Ridge,下面兩個方程等價:
當參數維度p=2時,lasso的參數估計是在|β1|+|β2|<=s條件下,β1和β2最小化RSS的。ridge的參數估計是在β12+β22<=s的參數取值中最小化RSS的。當s很大時,限制條件幾乎是無效的,lasso和ridge退化為最小二乘法,相反,如果s很小時,那么可能的參數取值范圍就非常有限。
紅線是平方誤差項RSS的等值線,左側青綠色的正方形是L1范數約束下的(β1,β2)的取值空間,右側青綠色的圓形是L2范數約束下的(β1,β2)的取值空間。上面兩個方程組的解要在平方誤差項RSS和正則化項之間折中,及出現在圖中平方誤差項等值線與正則化項等值線相交處。從上圖可以看出,使用L1范數時平方誤差項等值線與正則化等值線的交點常常出現在坐標軸上,即w1或者w2為0,而在采用L2范數時,兩者交點往往出現在某個象限中,即w1或者w2均非0,也就是說,L1范數比L2范數更易得到稀疏解。
彈性網絡ElasticNet
彈性網絡的目標函數:
彈性網絡則是同時使用了L1和L2作為正則化項,ElasticNet在sklearn的地址:ElasticNet
-
參數中
l1_ratio
為L1范數懲罰項所占比例,0 <= l1_ratio <= 1。若l1_ratio =0時,彈性網絡退化為ridge(只剩L2范數的懲罰項)。 -
參數中alpha即為上式中的α,越大對參數懲罰越大,越不容易過擬合。
使用樣例:import numpy as np from sklearn import linear_model ############################################################################### # Generate sample data n_samples_train, n_samples_test, n_features = 75, 150, 500 np.random.seed(0) coef = np.random.randn(n_features) coef[50:] = 0.0 # only the top 10 features are impacting the model X = np.random.randn(n_samples_train + n_samples_test, n_features) y = np.dot(X, coef) # Split train and test data X_train, X_test = X[:n_samples_train], X[n_samples_train:] y_train, y_test = y[:n_samples_train], y[n_samples_train:] ############################################################################### # Compute train and test errors alphas = np.logspace(-5, 1, 60) enet = linear_model.ElasticNet(l1_ratio=0.7) train_errors = list() test_errors = list() for alpha in alphas: enet.set_params(alpha=alpha) enet.fit(X_train, y_train) train_errors.append(enet.score(X_train, y_train)) test_errors.append(enet.score(X_test, y_test)) i_alpha_optim = np.argmax(test_errors) alpha_optim = alphas[i_alpha_optim] print("Optimal regularization parameter : %s" % alpha_optim) # Estimate the coef_ on full data with optimal regularization parameter enet.set_params(alpha=alpha_optim) coef_ = enet.fit(X, y).coef_ ############################################################################### # Plot results functions import matplotlib.pyplot as plt plt.subplot(2, 1, 1) plt.semilogx(alphas, train_errors, label='Train') plt.semilogx(alphas, test_errors, label='Test') plt.vlines(alpha_optim, plt.ylim()[0], np.max(test_errors), color='k', linewidth=3, label='Optimum on test') plt.legend(loc='lower left') plt.ylim([0, 1.2]) plt.xlabel('Regularization parameter') plt.ylabel('Performance') # Show estimated coef_ vs true coef plt.subplot(2, 1, 2) plt.plot(coef, label='True coef') plt.plot(coef_, label='Estimated coef') plt.legend() plt.subplots_adjust(0.09, 0.04, 0.94, 0.94, 0.26, 0.26) plt.show()
周志華:機器學習
http://www4.stat.ncsu.edu/~post/josh/LASSO_Ridge_Elastic_Net_-_Examples.html
http://blog.csdn.net/qq_21904665/article/details/52315642
http://blog.peachdata.org/2017/02/07/Lasso-Ridge.html