python scale()函数_xgboost如何使用MAE或MAPE作为目标函数?

xgboost被誉为各大数据竞赛中的“重型武器”,好的效果,并行计算的速度都是其显著的优势。xgboost参数中默认的目标函数有限,很多情况下,需要根据任务自定义目标函数。关于如何在代码中定义目标函数,可以参考:https://github.com/dmlc/xgboost/blob/master/demo/guide-python/custom_objective.py

xgboost需要目标函数的二阶导数信息(或者hess矩阵),在回归问题中经常将MAE或MAPE作为目标函数,然而看两者的计算公式就可以知道:这两个目标函数二阶导数不存在

式中,

是真实值,
是算法的预测值

解决这个问题的高质量解答很少,xgboost 使用 MAE或MAPE 作为目标函数这个博客以及里面给出的链接回答都比较模糊,下面是我对于这个问题的解决方法。

解决这个问题的两个主流方法:

1.利用可导的函数逼近MAE或者MAPE,这种方法更符合严谨的逻辑,所以后面重点阐述

2.直接自己定义一个二阶导数的值,比如直接将

定义为二阶导数,这中方法没有严谨的数学推理,但在很多应用中可以work。

利用MSE进行逼近是最简单的一种方法,但是MSE在训练初始误差较大的时候,loss是其平方,会使得训练偏离MAE的目标函数,一般难以达到高精度的要求。

利用Huber loss(Huber loss - Wikipedia)进行逼近,是更好的办法。其定义如下所示:

图1 是利用Hber loss逼近MAE的示意图,

是可调的参数(来源:Xgboost-How to use "mae" as objective function?)

图1 Hber loss逼近MAE

但是值得注意的是Huber loss仍然不可导,实际又利用了Huber loss的可导逼近形式:Pseudo-Huber loss function作为目标函数(很多文章中没有讲清这一点)其定义为:

一阶导数为:

二阶导数为:

的情况下,对应的目标函数定义为(这个实验Python代码):
def 

代码中的h就是公式中的

,实际应用中调节
来调整逼近效果。

图2及图3分别是以Pseudo-Huber loss function和MAE loss作为逼近函数在同一个任务上,validation集上的实验结果(实验中

)。

图2 Pseudo-Huber loss function逼近下的validation error

图3 MSE loss逼近下的validation error

由上两图可以看出:Pseudo-Huber loss function逼近下的误差更小,收敛速度更快!

还可以用ln(cosh(x))以及 log(exp(-x) + exp(x))进行逼近,可以看一下几者的函数曲线

图4 小范围函数曲线对比

图5 大范围函数曲线对比

ln(cosh(x))的一阶导数:

tanh(x)

ln(cosh(x))的二阶导数:

1-tanh(x)*tanh(x)

ln(cosh(x))的代码:

def 

可以对比一下ln(cosh(x))的Pseudo-Huber loss function的一阶,二阶导数图像:

图6 一阶导数图像对比

图7 二阶导数对比

可以看出,两者的一阶、二阶导数非常像!

在实践中选择适合自己问题的逼近函数形式吧!

对于MAPE的处理情况,就很简单了,将逼近函数的一阶和二阶导数除以

(不明白的话,看MAPE的定义式)

你可能感兴趣的:(python,scale()函数,python,xgboost)