XGBoost自定义目标函数-归一化平方误差

时间:2020-05-05 08:43:01

标签: python

我尝试使用https://xgboost.readthedocs.io/en/latest/tutorials/custom_metric_obj.html中的文档提示,将平方归一化误差用作XGBoostRegressor的目标函数。我的目标函数方程是:

(预测-观察)/ standard_deviation(观察)

在尝试开发它时,我遇到了以下问题:

  1. 我想知道是否允许这样的目标函数,因为标准差包含有关所有观察值(标签)的信息,而每个训练示例的损失都是单独计算的。
  2. 如果我的方法正确,我想知道如何计算该目标函数的粗麻布和梯度。我在这里分析了平方误差损失函数:Creating a Custom Objective Function in for XGBoost.XGBRegressor,但无法理解为什么将x =(预测-观察值)视为一个参数。换句话说,为什么我们将损失函数用作x ^ 2而不是(x-y)^ 2? x和y分别对应于预测和观察。

编辑:我将XGBoost用于光伏(PV)产量预测任务,并使用一种模型对多个系统进行预测。我希望所有系统的错误率都很低,尽管它们的大小。但是,平方误差使训练的重点放在最大的系统上,因为它们的误差自然是最大的。我将目标函数更改为:

(预测-观察)/ system_size

并将 system_size 设置为全局变量,因为不允许向梯度和hessian函数添加新的输入变量。该代码编译没有错误,但是预测范围很小。渐变可以除以system_sizes,因为除以常数不会更改导数。到目前为止,我开发的代码:

def gradient_sne(predt: np.ndarray, dtrain: DMatrix) -> np.ndarray:
    #Compute the gradient squared normalized error.
    y = dtrain.get_label()
    return 2*(predt - y)/system_sizes

def hessian_sne(predt: np.ndarray, dtrain: DMatrix) -> np.ndarray:
    #Compute the hessian for squared error
    y = dtrain.get_label()
    return 0*y + 2

def custom_sne(y_pred, y_true):
    #squared error objective. A simplified version of MSNE used as
    #objective function.
    grad = gradient_sne(y_pred, y_true)
    hess = hessian_sne(y_pred, y_true)
    return grad, hess

# Customized metric
def nrmse(predt: np.ndarray, dtrain: DMatrix):
    ''' Root mean squared normalized error metric. '''
    y = dtrain.get_label()
    predt[predt < 0] = 0 # all negative predictions are zero
    std_dev = np.std(y)
    elements = np.power(((y - predt) / std_dev), 2)
    return 'RMSNE', float(np.sqrt(np.sum(elements) / len(y)))

我使用python 3.7.5和xgboost 1.0.2。非常感谢您的帮助。

0 个答案:

没有答案