Scikit-Learn:GridSearchCV 的自定义损失函数

Posted

技术标签:

【中文标题】Scikit-Learn:GridSearchCV 的自定义损失函数【英文标题】:Scikit-Learn: Custom Loss Function for GridSearchCV 【发布时间】:2018-07-06 23:03:11 【问题描述】:

我正在参加 Kaggle 比赛 (https://www.kaggle.com/c/house-prices-advanced-regression-techniques#evaluation),它指出我的模型将由以下人员评估:

Submissions are evaluated on Root-Mean-Squared-Error (RMSE) between the logarithm of the predicted value and the logarithm of the observed sales price. (Taking logs means that errors in predicting expensive houses and cheap houses will affect the result equally.)

我在文档中找不到这个(基本上是RMSE(log(truth), log(prediction)),所以我开始编写一个自定义记分器:

def custom_loss(truth, preds):
    truth_logs = np.log(truth)
    print(truth_logs)
    preds_logs = np.log(preds)
    numerator = np.sum(np.square(truth_logs - preds_logs))
    return np.sum(np.sqrt(numerator / len(truth)))

custom_scorer = make_scorer(custom_loss, greater_is_better=False)

两个问题:

1) 我的自定义损失函数是否应该返回一个 numpy 分数数组(每个(真相,预测)对一个?或者它应该是这些(真相,预测)对的总损失,返回一个数字?

我查看了文档,但它们对我的自定义损失函数应该返回的内容并没有太大帮助。

2) 当我跑步时:

xgb_model = xgb.XGBRegressor()
params = "max_depth": [3, 4], "learning_rate": [0.05],
         "n_estimators": [1000, 2000], "n_jobs": [8], "subsample": [0.8], "random_state": [42]
grid_search_cv = GridSearchCV(xgb_model, params, scoring=custom_scorer,
                             n_jobs=8, cv=KFold(n_splits=10, shuffle=True, random_state=42), verbose=2)

grid_search_cv.fit(X, y)

grid_search_cv.best_score_

我回来了:

-0.12137097567803554

这是非常令人惊讶的。鉴于我的损失函数采用RMSE(log(truth) - log(prediction)),我不应该能够得到负的best_score_

知道为什么它是负面的吗?

谢谢!

【问题讨论】:

【参考方案1】:

1) 您应该返回一个数字作为损失,而不是数组。 GridSearchCV 将根据该记分器的结果对参数进行排序。

顺便说一句,您可以使用mean_squared_log_error,而不是定义自定义指标,它可以满足您的需求。

2) 为什么它返回负数? - 没有你的实际数据和完整的代码我们不能说。

【讨论】:

【参考方案2】:

你应该小心这个符号。

这里有2个优化级别:

    XGBRegressor 拟合到数据时优化的损失函数。 在网格搜索过程中优化的评分功能。

我更喜欢调用第二个 scoring 函数而不是 loss 函数,因为损失函数通常是指在模型拟合过程中需要优化的术语。 但是,您的自定义函数仅指定 2. 而保持 1. 不变。如果您想更改XGBRegressor 的损失函数,请参阅here。大多数回归模型都有几个标准可供您选择,例如mean_square_errormean_absolute_error

请注意,目前不支持传递自定义损失函数(请参阅原因 here 和 here)。

【讨论】:

【参考方案3】:

如果greater_is_better 为False,则make_scorer 函数符号翻转

【讨论】:

以上是关于Scikit-Learn:GridSearchCV 的自定义损失函数的主要内容,如果未能解决你的问题,请参考以下文章

Scikit-learn 中的 GridSearchCV 输出问题

Scikit-Learn:GridSearchCV 的自定义损失函数

Scikit-learn 多输出分类器使用:GridSearchCV、Pipeline、OneVsRestClassifier、SGDClassifier

scikit-learn GridSearchCV 弃用警告

scikit-learn 中 LogisticRegression 上的 GridSearchCV

使用 GridSearchCV 调整 scikit-learn 的随机森林超参数