GridSearchCV - 跨测试访问预测值?

Posted

技术标签:

【中文标题】GridSearchCV - 跨测试访问预测值?【英文标题】:GridSearchCV - access to predicted values across tests? 【发布时间】:2018-09-12 23:31:19 【问题描述】:

有没有办法访问在 GridSearchCV 过程中计算的预测值?

我希望能够根据实际值(来自测试/验证集)绘制预测的 y 值。

网格搜索完成后,我可以使用

将其与其他一些数据相匹配
 ypred = grid.predict(xv)

但我希望能够绘制在网格搜索期间计算的值。也许有一种方法可以将点保存为 pandas 数据框?

from sklearn.preprocessing import StandardScaler
from sklearn.model_selection import GridSearchCV, KFold, 
cross_val_score, train_test_split
from sklearn.pipeline import Pipeline
from sklearn.svm import SVR

scaler = StandardScaler()
svr_rbf = SVR(kernel='rbf')
pipe = Pipeline(steps=[('scaler', scaler), ('svr_rbf', svr_rbf)])
grid = GridSearchCV(pipe, param_grid=parameters, cv=splits, refit=True, verbose=3, scoring=msescorer, n_jobs=4)
grid.fit(xt, yt)

【问题讨论】:

就我而言,你不能这样做(但我可能错了)。我能想到的解决方案是分别预测每个参数配置的值。但是,这不会复制GridSearchCV,因为您的测试/训练样本会有所不同(尤其是使用 KFoldValidation)。您可以尝试为每个参数值的范围绘制mean_test_score,同时保持所有其他参数不变。虽然,它也不是最优的,因为不同的参数配置会相互影响。 How to get predictions for each set of parameters using GridSearchCV?的可能重复 【参考方案1】:

一种解决方案是制作一个自定义记分器并将它接收到的参数保存到一个全局变量中:

from sklearn.grid_search import GridSearchCV
from sklearn.svm import SVR
from sklearn.metrics import mean_squared_error,make_scorer

X, y = np.random.rand(2,200)
clf = SVR()

ys = []

def MSE(y_true,y_pred):
    global ys
    ys.append(y_pred)
    mse = mean_squared_error(y_true, y_pred)
    return mse

def scorer():
    return make_scorer(MSE, greater_is_better=False)

n_splits = 3 
cv = GridSearchCV(clf, 'degree':[1,2,3], scoring=scorer(), cv=n_splits)
cv.fit(X.reshape(-1, 1), y)

然后我们需要将每个拆分收集到一个完整的数组中:

idxs = range(0, len(ys)+1, n_splits)
#e.g. [0, 3, 6, 9]
#collect every n_split elements into a single list
new = [ys[j[0]+1:j[1]] for j in zip(idxs,idxs[1:])]
#summing every such list
ys = [reduce(lambda x,y:np.concatenate((x,y), axis=0), i) for i in new]

【讨论】:

如果我在实例化GridSearchCV 时使用参数n_jobs,这不起作用。另外,我得到y_pred,但我想得到y_pred_proba。有什么解决方法吗? @DennyCeccon 你找到解决方案了吗? @AnIgnorantWanderer 是的,我做到了!让我把它贴在下面。【参考方案2】:

使用多个处理器并存储y_pred_proba 而不是y_pred 的解决方案。

首先我们需要启动一个多进程管理器:

import multiprocessing
manager = multiprocessing.Manager()

在实例化GridSearchCV 之前,我们需要创建一个虚拟记分器,它将捕获并存储概率值。就我而言,我使用了 ROC_AUC,但任何指标都可以:

scorers = 
def roc_auc_dummy(y_true, y_pred_proba):
    global ys # This will make sure `ys` is in the global, not local, scope
    ys.append(y_pred_proba)
    roc_auc = roc_auc_score(y_true, y_pred_proba)
    return roc_auc
scorers['roc_auc'] = make_scorer(roc_auc_dummy, needs_proba = True)

scorers 可以有其他适合您需要的评分功能。然后,我们需要使用管理器创建一个列表,实例化GridSearchCV,并对其进行拟合。

ys = manager.list()
clf = GridSearchCV(model, params, scoring = scorers)
clf.fit(X, y)

可以将ys 转换为列表来检索概率:

y_pred_probas = list(ys)

y_pred_probas 将是一个列表列表,其中每个内部列表的顺序与clf.cv_results_['params'] 中的顺序相同。

【讨论】:

以上是关于GridSearchCV - 跨测试访问预测值?的主要内容,如果未能解决你的问题,请参考以下文章

有没有办法在科学工具包中预测 GridSearchCV 中的多个模型?

在 GridSearch CV 之后进行预测时是不是遵循管道步骤

使用 GridSearchCV 进行超参数调整

GridsearchCV 不检查所有拆分 [关闭]

sklearn.SVC 在使用带有小型平衡数据集的 GridSearchCV 时返回完全不同的预测(模型)

时间序列——GridSearchCV&TimeSeriesSplit的调参(xgboost预测sin(x))