使用Akaike信息标准(AIC),贝叶斯信息标准(BIC)和交叉验证来选择Lasso估计器的正则化参数alpha的最佳值。
LassoLarsIC 获得的结果基于AIC/BIC标准。
基于信息准则(Information-criterion)的模型选择速度非常快,但是它依赖于自由度的正确估计,是针对大样本(渐近结果)导出的,并且假设模型是正确的,即数据实际上是由该模型生成的。当问题条件很差时(特征比样本多),该模型容易崩溃。
对于交叉验证,我们使用20-fold 2种算法计算 Lasso 路径:坐标下降,由 LassoCV 类实现,Lars(最小角度回归)由LassoLarsCV 类实现。两种算法给出的结果大致相同。它们的执行速度和数值误差来源不同。
Lars只为路径中的每个结点计算路径解。因此,当只有很少的结点时非常有效,即只有很少的特征或样本的情况。此外,它还可以计算完整路径,而无需设置任何元(meta)参数。相反,坐标下降计算预先指定网格上的路径点(这里使用默认值)。因此,如果网格点的数目小于路径中结点的数目,则效率更高。如果特征的数量真的很大,并且有足够的样本来选择大量的特征,那么这样的策略可能会很有趣。在数值误差方面,对于高度相关的变量,Lars会积累更多的误差,而坐标下降算法只会在网格上采样路径。
请注意alpha的最佳值对于每个fold是如何变化的。这说明了为什么在试图评估通过交叉验证为其选择参数的方法的性能时需要嵌套交叉验证:对于未见过的数据,此参数选择可能不是最佳的。
输出:
Computing regularization path using the coordinate descent lasso...
Computing regularization path using the Lars lasso...
print(__doc__)
# 作者: Olivier Grisel, Gael Varoquaux, Alexandre Gramfort
# 许可证: 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
# 这是为了避免在执行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
# 像Lars一样规范化数据以进行比较
X /= np.sqrt(np.sum(X ** 2, axis=0))
# #############################################################################
# LassoLarsIC: 采用BIC / AIC标准的最小角度回归
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):
alpha_ = model.alpha_ + EPSILON
alphas_ = model.alphas_ + EPSILON
criterion_ = model.criterion_
plt.plot(-np.log10(alphas_), criterion_, '--', color=color,
linewidth=3, label='%s criterion' % name)
plt.axvline(-np.log10(alpha_), color=color, linewidth=3,
label='alpha: %s estimate' % name)
plt.xlabel('-log(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: 坐标下降
# 计算路径
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
# 显示结果
m_log_alphas = -np.log10(model.alphas_ + EPSILON)
plt.figure()
ymin, ymax = 2300, 3800
plt.plot(m_log_alphas, model.mse_path_, ':')
plt.plot(m_log_alphas, model.mse_path_.mean(axis=-1), 'k',
label='Average across the folds', linewidth=2)
plt.axvline(-np.log10(model.alpha_ + EPSILON), linestyle='--', color='k',
label='alpha: CV estimate')
plt.legend()
plt.xlabel('-log(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: 最小角度回归
# 计算路径
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
# 显示结果
m_log_alphas = -np.log10(model.cv_alphas_ + EPSILON)
plt.figure()
plt.plot(m_log_alphas, model.mse_path_, ':')
plt.plot(m_log_alphas, model.mse_path_.mean(axis=-1), 'k',
label='Average across the folds', linewidth=2)
plt.axvline(-np.log10(model.alpha_), linestyle='--', color='k',
label='alpha CV')
plt.legend()
plt.xlabel('-log(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 分 0.872 秒)
估计的内存使用量: 8 MB
下载python源代码: plot_lasso_model_selection.py
下载Jupyter notebook源代码: plot_lasso_model_selection.ipynb
由Sphinx-Gallery生成的画廊