我尝试使用https://xgboost.readthedocs.io/en/latest/tutorials/custom_metric_obj.html中的文档提示,将平方归一化误差用作XGBoostRegressor的目标函数。我的目标函数方程是:
(预测-观察)/ standard_deviation(观察)
在尝试开发它时,我遇到了以下问题:
编辑:我将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。非常感谢您的帮助。