LASSO模型選擇:交叉驗證/AIC/BIC?
利用Akaike信息準則(AIC)、Bayes信息準則(BIC)和交叉驗證,選擇Lasso估計器正則化參數alpha的最優值。
用LassoLarsIC得到的結果是基于AIC/BIC準則的。
基于信息準則的模型選擇是非常快速的,但它依賴于適當的自由度估計,對大樣本(漸近結果)進行推導,并假定模型是正確的,即數據實際上是由該模型生成的。當問題條件不好時(特征多于樣本),它們也會崩潰。
我們都使用20折交叉驗證去計算2種算法計算Lasso路徑:坐標下降(由LassoCV類實現)和LAS(最小角度回歸)(由LassoLarsCV類實現)。這兩種算法給出的結果大致相同。它們在執行速度和數值誤差來源方面存在差異。的2種算法計算拉索路徑:坐標下降(由LassoCV類實現)和LAS(最小角度回歸)(由LassoLarsCV類實現)。這兩種算法給出的結果大致相同。它們在執行速度和數值誤差來源方面存在差異。
LARs只為路徑中的每個扭結計算路徑解決方案。因此,當只有少數幾個扭結時,它是非常有效的,如果沒有幾個特征或樣本,就會出現這種情況。此外,它還可以在不設置任何元參數的情況下計算完整路徑。相反,坐標下降計算預先指定的網格上的路徑點(這里我們使用默認值)。因此,如果網格點的數目小于路徑中的扭結數,則效率更高。如果特征的數量非常多,并且有足夠的樣本來選擇大量,那么這樣的策略可能會很有趣。在數值誤差方面,對于高度相關的變量,Lars會積累更多的誤差,而坐標下降算法只會對網格上的路徑進行采樣。
注意,alpha的最優值在每一次折疊時是如何變化的。這說明了為什么在試圖評估通過交叉驗證選擇參數的方法的性能時,嵌套交叉驗證是必要的:對于未見數據,這種參數選擇可能不是最優的。
Computing regularization path using the coordinate descent lasso...
Computing regularization path using the Lars lasso...
print(__doc__)
# Author: Olivier Grisel, Gael Varoquaux, Alexandre Gramfort
# License: BSD 3 clause
import time
import numpy as np
import matplotlib.pyplot as plt
from sklearn.linear_model import LassoCV, LassoLarsCV, LassoLarsIC
from sklearn import datasets
# This is to avoid division by zero while doing np.log10
EPSILON = 1e-4
X, y = datasets.load_diabetes(return_X_y=True)
rng = np.random.RandomState(42)
X = np.c_[X, rng.randn(X.shape[0], 14)] # add some bad features
# normalize data as done by Lars to allow for comparison
X /= np.sqrt(np.sum(X ** 2, axis=0))
# #############################################################################
# LassoLarsIC: least angle regression with BIC/AIC criterion
model_bic = LassoLarsIC(criterion='bic')
t1 = time.time()
model_bic.fit(X, y)
t_bic = time.time() - t1
alpha_bic_ = model_bic.alpha_
model_aic = LassoLarsIC(criterion='aic')
model_aic.fit(X, y)
alpha_aic_ = model_aic.alpha_
def plot_ic_criterion(model, name, color):
criterion_ = model.criterion_
plt.semilogx(model.alphas_ + EPSILON, criterion_, '--', color=color,
linewidth=3, label='%s criterion' % name)
plt.axvline(model.alpha_ + EPSILON, color=color, linewidth=3,
label='alpha: %s estimate' % name)
plt.xlabel(r'$\alpha$')
plt.ylabel('criterion')
plt.figure()
plot_ic_criterion(model_aic, 'AIC', 'b')
plot_ic_criterion(model_bic, 'BIC', 'r')
plt.legend()
plt.title('Information-criterion for model selection (training time %.3fs)'
% t_bic)
# #############################################################################
# LassoCV: coordinate descent
# Compute paths
print("Computing regularization path using the coordinate descent lasso...")
t1 = time.time()
model = LassoCV(cv=20).fit(X, y)
t_lasso_cv = time.time() - t1
# Display results
plt.figure()
ymin, ymax = 2300, 3800
plt.semilogx(model.alphas_ + EPSILON, model.mse_path_, ':')
plt.plot(model.alphas_ + EPSILON, model.mse_path_.mean(axis=-1), 'k',
label='Average across the folds', linewidth=2)
plt.axvline(model.alpha_ + EPSILON, linestyle='--', color='k',
label='alpha: CV estimate')
plt.legend()
plt.xlabel(r'$\alpha$')
plt.ylabel('Mean square error')
plt.title('Mean square error on each fold: coordinate descent '
'(train time: %.2fs)' % t_lasso_cv)
plt.axis('tight')
plt.ylim(ymin, ymax)
# #############################################################################
# LassoLarsCV: least angle regression
# Compute paths
print("Computing regularization path using the Lars lasso...")
t1 = time.time()
model = LassoLarsCV(cv=20).fit(X, y)
t_lasso_lars_cv = time.time() - t1
# Display results
plt.figure()
plt.semilogx(model.cv_alphas_ + EPSILON, model.mse_path_, ':')
plt.semilogx(model.cv_alphas_ + EPSILON, model.mse_path_.mean(axis=-1), 'k',
label='Average across the folds', linewidth=2)
plt.axvline(model.alpha_, linestyle='--', color='k',
label='alpha CV')
plt.legend()
plt.xlabel(r'$\alpha$')
plt.ylabel('Mean square error')
plt.title('Mean square error on each fold: Lars (train time: %.2fs)'
% t_lasso_lars_cv)
plt.axis('tight')
plt.ylim(ymin, ymax)
plt.show()
腳本的總運行時間:(0分1.212秒)