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

Posted

技术标签:

【中文标题】GridsearchCV 不检查所有拆分 [关闭]【英文标题】:GridsearchCV doesn't check all splits [closed] 【发布时间】:2021-12-06 02:16:48 【问题描述】:

我有一个复杂的项目,其中包括多输出预测和自定义评分功能(越低越好)。 我在网格的“平均测试分数”和我的测试集的成绩之间存在差距。

原来,网格只检查第一个分割;在其他拆分上,它返回 0。

在这个结果上,网格的得分是平均分,所以我得到了第一次分割的分数除以块数(在我的例子中是 5),我没有得到所有分割的平均值。

数据: 目标是这样构建的 - 两列数字连续变量,构建为 pandas df:

         a            b
0     89.993421     70.273583
1     88.089657     68.910432
2     88.412756     68.143213
3     87.360133     67.776393
4     83.236367     61.467078
 

功能 - 相同,50 个连续数字列(大约 5000 行),没有空值。

评分函数:

from sklearn.metrics import make_scorer


class LengthNotEqual(Exception):
    pass


def smape(observations, predictions):
    if len(observations) != len(predictions):
        raise LengthNotEqual(
            "the number of observasions and predictions don't match!")
    N = len(observations)
    return 100/N * np.sum(np.abs(observations - predictions) / ((np.abs(observations) + np.abs(predictions))/2))


def final_smape(y_true, y_predicted):
    y_true = pd.DataFrame(y_true)
    y_predicted = pd.DataFrame(y_predicted)
    final_smape = 0.25 * smape(y_true.iloc[:, 0], y_predicted.iloc[:, 0]) + \
        0.75 * smape(y_true.iloc[:, 1], y_predicted.iloc[:, 1])
    return final_smape


scorer = make_scorer(final_smape, greater_is_better=False) 

型号代码如下:

m = Pipeline([('std', StandardScaler()), ('dummy', DummyRegressor())])
model = GridSearchCV(estimator=m, param_grid=, scoring=scorer, n_jobs=-1)
model.fit(X_train, y_train)
display(pd.DataFrame(model.cv_results_))
display(model.best_estimator_)
print("best score:", np.abs(model.best_score_))
preds = model.predict(X_test)
print("test score:", final_smape(y_test, preds)) 

输出: 测试分数与网格分数之间的差距是这样的:

Pipeline(steps=[('std', StandardScaler()), ('dummy', DummyRegressor())])

best score: 1.9374532464119931
test score: 12.293068464422076 

并且在图片(cv_results_ 特征)中,您可以看到原因是网格仅检查 split0 并在其他拆分上返回 0:

我在我尝试过的所有模型中都遇到了同样的问题。

【问题讨论】:

您确定您的数据没有任何问题吗?先用 shuffle 运行一些测试,和/或使用更少的 CV 折叠 (2-3)...无论如何,我们都需要 minimal reproducible example。 我创建了一个随机数据数据框,它在那里工作。我认为你是对的,即使我检查了那里没有空值,数据也存在一些问题,并且减少 cv 编号也没有用。但我会再检查一次。谢谢! 不客气;改组数据应该是首先要尝试的事情。 我试过了,没用,但是当我找到一些东西时,我会更新问题。非常感谢@desertnaut 【参考方案1】:

我发现了问题: 是我的记分员混合了 numpy 和 pandas 的 dtype 和函数。

将 all 转换为 numpy 解决了这个问题。

y_test = y_test.to_numpy()
y_train = y_train.to_numpy()

def smape(y_true, y_pred):
    error = np.abs(y_true - y_pred)
    scale = (np.abs(y_true) + np.abs(y_pred)) / 2
    return np.mean(error / scale)


def final_smape(y_true, y_pred):
    rougher = smape(y_true[0], y_pred[0])
    final = smape(y_true[1], y_pred[1])
    return 0.25 * rougher + 0.75 * final

from sklearn.metrics import make_scorer
scorer = make_scorer(final_smape, greater_is_better=False)  

【讨论】:

以上是关于GridsearchCV 不检查所有拆分 [关闭]的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 KerasClassifier 验证拆分和使用 scikit 学习 GridSearchCV

将 GridSearchCV 与 TimeSeriesSplit 一起使用

GridSearchCV - 错误:具有多个元素的数组的真值不明确。使用 a.any() 或 a.all()

Gridsearchcv:内部逻辑

对网格搜索中的所有组合使用交叉验证

如何使用GridSearchCV获取所有模型(每组参数一个)?