如何使用 matplotlib 可视化模型性能和 alpha 的依赖性?

Posted

技术标签:

【中文标题】如何使用 matplotlib 可视化模型性能和 alpha 的依赖性?【英文标题】:how to visualize dependence of model performance & alpha with matplotlib? 【发布时间】:2018-07-25 13:30:46 【问题描述】:

我使用 GridSearchCV 拟合岭回归,但在使用 matplotlib 显示模型性能与正则化器(alpha)时遇到问题

有人可以帮忙吗?

我的代码:

from sklearn.datasets import fetch_california_housing
cal=fetch_california_housing()
X = cal.data
y = cal.target 

from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=0)

param_grid = 'alpha': np.logspace(-3, 3, 13)
print(param_grid)
grid = GridSearchCV(Ridge(normalize=True), param_grid, cv=10)
grid.fit(X_train, y_train)
print("Best cross-validation score: :.2f".format(grid.best_score_))
print("Best parameters: ", grid.best_params_)

import matplotlib.pyplot as plt
alphas = np.logspace(-3, 3, 13)
plt.semilogx(alphas, grid.fit(X_train, y_train), label='Train')
plt.semilogx(alphas, grid.fit(X_test, y_test), label='Test')

plt.legend(loc='lower left')
plt.ylim([0, 1.0])
plt.xlabel('alpha')
plt.ylabel('performance')

# the error code I got was "ValueError: x and y must have same first dimension"

基本上,我希望看到如下内容:

【问题讨论】:

【参考方案1】:

你应该绘制分数,而不是grid.fit()的结果。

首先使用return_train_score=True:

grid = GridSearchCV(Ridge(normalize=True), param_grid, cv=10, return_train_score=True)

然后在拟合模型后绘制如下:

plt.semilogx(alphas, grid.cv_results_['mean_train_score'], label='Train')
plt.semilogx(alphas, grid.cv_results_['mean_test_score'], label='Test')
plt.legend()

结果:

【讨论】:

【参考方案2】:

在绘制使用 GridSearch 产生的模型选择性能时,通常会绘制 cross_validation 折叠的测试集和训练集的均值和标准差。

还应注意确定在网格搜索中使用哪些评分标准来选择最佳模型。这通常是回归的 R 平方。

网格搜索返回一个字典(可通过.cv_results_ 访问),其中包含每个折叠训练/测试分数的分数以及训练/测试每个折叠所花费的时间。还使用平均值和标准偏差包括该数据的摘要。 PS。在较新版本的 pandas 中,您需要包含 return_train_score=True 附言使用网格搜索时,模型选择不需要将数据拆分为训练/测试,因为网格搜索会自动拆分数据(cv=10 表示将数据拆分为 10 折)

鉴于上述情况,我将代码修改为

import numpy as np
import matplotlib.pyplot as plt

from sklearn.linear_model import Ridge
from sklearn.model_selection import GridSearchCV
from sklearn.datasets import fetch_california_housing
cal = fetch_california_housing()
X = cal.data
y = cal.target


param_grid = 'alpha': np.logspace(-3, 3, 13)
print(param_grid)
grid = GridSearchCV(Ridge(normalize=True), param_grid,
                    cv=10, return_train_score=True, scoring='r2')
grid.fit(X, y)
print("Best cross-validation score: :.2f".format(grid.best_score_))
print("Best parameters: ", grid.best_params_)


alphas = np.logspace(-3, 3, 13)

train_scores_mean = grid.cv_results_["mean_train_score"]
train_scores_std = grid.cv_results_["std_train_score"]
test_scores_mean = grid.cv_results_["mean_test_score"]
test_scores_std = grid.cv_results_["std_test_score"]

plt.figure()
plt.title('Model')
plt.xlabel('$\\alpha$ (alpha)')
plt.ylabel('Score')
# plot train scores
plt.semilogx(alphas, train_scores_mean, label='Mean Train score',
             color='navy')
# create a shaded area between [mean - std, mean + std]
plt.gca().fill_between(alphas,
                       train_scores_mean - train_scores_std,
                       train_scores_mean + train_scores_std,
                       alpha=0.2,
                       color='navy')
plt.semilogx(alphas, test_scores_mean,
             label='Mean Test score', color='darkorange')

# create a shaded area between [mean - std, mean + std]
plt.gca().fill_between(alphas,
                       test_scores_mean - test_scores_std,
                       test_scores_mean + test_scores_std,
                       alpha=0.2,
                       color='darkorange')

plt.legend(loc='best')
plt.show()

结果图如下所示

【讨论】:

非常感谢,这很有帮助。但我很好奇你说“在使用网格搜索时,模型选择不需要将数据拆分为训练/测试”我不知道这一点,所以我总是拆分训练/测试数据,你介意传递一些参考吗? 不客气。这是一个匆忙获得的参考文献scikit-learn cross validation 仍然应该保留测试集以进行最终评估,但在进行 CV 时不再需要验证集。在称为 k-fold CV 的基本方法中,训练集被分成 k 个更小的集合(其他方法在下面描述,但通常遵循相同的原则)。对于 k 个“折叠”中的每一个,都遵循以下过程: 我提出上述观点的原因是您持有 33% 的数据进行验证。请注意,术语可能会令人困惑。我们绘制的测试分数与 kfolds 和 X_test 相关,当网格搜索选择模型时看不到 y_test。我建议使用不同的术语来增加混淆,即X_model_sel, X_val, y_model_sel, y_val = train_test_split(X, y, random_state=0) 谢谢。事实上,我只是尝试了拆分/不拆分,CV 分数变化很大(0.61 对 .51)。我认为原因(在我的情况下)是,在拆分时,gridsearch 仅在整个数据集的 70% 上执行此操作(这意味着 gridsearch 通过将其进一步拆分为另一个 70/30% 来对其进行 cv?)。虽然没有拆分,但 gridsearch 获取整个数据集并在 70% 的数据上运行 cv。你同意吗? 我同意小幅修正;当使用 cv=10 的交叉验证时,数据被分成 10 个部分,即 10% / 90%,然后每个部分用于训练,其余部分用于验证。我建议设置网格搜索参数grid = GridSearchCV(Ridge(normalize=True), param_grid, cv=10, return_train_score=True, verbose=5) 你会更好地了解网格搜索的工作原理

以上是关于如何使用 matplotlib 可视化模型性能和 alpha 的依赖性?的主要内容,如果未能解决你的问题,请参考以下文章

python使用matplotlib对比多个模型在测试集上的效果并可视化设置模型性能可视化结果柱状图(bar plot)标签的小数点位数(例如,强制柱状图标签0.7显示为两位小数0.70)

如何使用`matplotlib`可视化5-D功能集和回归结果?

如何使用 Matplotlib 可视化标量 2D 数据?

在 matplotlib/python 中可视化高维数据

使用matplotlib让你的数据更加生动

Matplotlib进行数据可视化的快速上手指南