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 一起使用