本教程将引导通过使用交叉验证和线性模型来对糖尿病数据集进行模型选择和参数调优。这个练习是统计学习教程中的一个部分,具体位于模型选择部分的交叉验证小节。本教程的是scikit-learn开发团队,并且遵循BSD-3-Clause许可证。
首先,需要导入必要的库,包括matplotlib.pyplot用于绘图,numpy用于数值计算,以及scikit-learn中的datasets和linear_model模块。然后,加载糖尿病数据集,并将其缩减到前150个样本以便于计算。接着,创建一个Lasso回归模型,并定义了一系列候选的alpha参数值。最后,使用GridSearchCV来寻找最佳的alpha参数。
import matplotlib.pyplot as plt
import numpy as np
from sklearn import datasets
from sklearn.linear_model import Lasso
from sklearn.model_selection import GridSearchCV
X, y = datasets.load_diabetes(return_X_y=True)
X = X[:150]
y = y[:150]
lasso = Lasso(random_state=0, max_iter=10000)
alphas = np.logspace(-4, -0.5, 30)
tuned_parameters = [{"alpha": alphas}]
n_folds = 5
clf = GridSearchCV(lasso, tuned_parameters, cv=n_folds, refit=False)
clf.fit(X, y)
scores = clf.cv_results_["mean_test_score"]
scores_std = clf.cv_results_["std_test_score"]
接下来,绘制了一组误差线,显示了分数的正负标准误差。这有助于直观地了解不同alpha参数下模型性能的变化情况。
plt.figure().set_size_inches(8, 6)
plt.semilogx(alphas, scores)
std_error = scores_std / np.sqrt(n_folds)
plt.semilogx(alphas, scores + std_error, "b--")
plt.semilogx(alphas, scores - std_error, "b--")
plt.fill_between(alphas, scores + std_error, scores - std_error, alpha=0.2)
plt.ylabel("CV score +/- std error")
plt.xlabel("alpha")
plt.axhline(np.max(scores), linestyle="--", color=".5")
plt.xlim([alphas[0], alphas[-1]])
在图表中,使用半对数坐标轴来展示alpha参数与交叉验证分数之间的关系。通过这种方式,可以更清楚地看到在不同数量级上的alpha参数对模型性能的影响。
为了回答这个问题,使用LassoCV对象,它可以通过内部交叉验证自动设置alpha参数。然后,使用外部交叉验证来观察在不同的交叉验证折叠中自动获得的alpha参数有多大的差异。
from sklearn.linear_model import LassoCV
from sklearn.model_selection import KFold
lasso_cv = LassoCV(alphas=alphas, random_state=0, max_iter=10000)
k_fold = KFold(3)
print("Answer to the bonus question: how much can you trust the selection of alpha?")
print()
print("Alpha parameters maximising the generalization score on different")
print("subsets of the data:")
for k, (train, test) in enumerate(k_fold.split(X, y)):
lasso_cv.fit(X[train], y[train])
print("[fold {0}] alpha: {1:.5f}, score: {2:.5f}".format(k, lasso_cv.alpha_, lasso_cv.score(X[test], y[test])))
print()
print("Answer: Not very much since we obtained different alphas for different")
print("subsets of the data and moreover, the scores for these alphas differ")
print("quite substantially.")
plt.show()
通过这个额外的练习,发现在不同的数据子集上,得到了不同的alpha参数,并且这些alpha参数对应的分数差异相当大。因此,不能过于依赖自动选择的alpha参数。
本教程的运行总时间为0.559秒。可以通过以下链接下载Jupyter笔记本和Python源代码:
相关示例还包括: