0

我正在参加 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_

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

谢谢!

4

3 回答 3

0

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

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

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

于 2018-01-28T02:58:37.527 回答
0

你应该小心这个符号。

这里有两个优化级别:

  1. XGBRegressor拟合数据时优化的损失函数。
  2. 在网格搜索期间优化的评分函数。

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

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

于 2018-11-23T23:25:57.530 回答
0

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

于 2020-06-09T18:07:57.920 回答