XGB-16:自定义目标和评估指标

概述

XGBoost被设计为一个可扩展的库。通过提供自定义的训练目标函数和相应的性能监控指标,可以扩展它。本文介绍了如何为XGBoost实现自定义的逐元评估指标和目标。

注意:

排序不能自定义

在接下来的两个部分中,将逐步介绍如何实现平方对数误差(Squared Log Error,SLE)目标函数

1 2 [ log ⁡ ( p r e d + 1 ) − log ⁡ ( l a b e l + 1 ) ] 2 \frac{1}{2}[\log(pred + 1) - \log(label + 1)]^2 21[log(pred+1)log(label+1)]2

以及它的默认评估指标均方根对数误差(Root Mean Squared Log Error,RMSLE

1 N [ log ⁡ ( p r e d + 1 ) − log ⁡ ( l a b e l + 1 ) ] 2 \sqrt{\frac{1}{N}[\log(pred + 1) - \log(label + 1)]^2} N1[log(pred+1)log(label+1)]2

定制目标函数

尽管XGBoost本身已经原生支持这些功能,但为了演示的目的,使用它来比较自己实现的结果和XGBoost内部实现的结果。完成本教程后,应该能够为快速实验提供自己的函数。最后,将提供一些关于非恒等链接函数的注释,以及在scikit-learn接口中使用自定义度量和目标的示例。

如果计算所述目标函数的梯度:

g = ∂ o b j e c t i v e ∂ p r e d = log ⁡ ( p r e d + 1 ) − log ⁡ ( l a b e l + 1 ) p r e d + 1 g = \frac{\partial{objective}}{\partial{pred}} = \frac{\log(pred + 1) - \log(label + 1)}{pred + 1} g=predobjective=pred+1log(pred+1)log(label+1)

以及 hessian(目标的二阶导数):

h = ∂ 2 o b j e c t i v e ∂ p r e d = − log ⁡ ( p r e d + 1 ) + log ⁡ ( l a b e l + 1 ) + 1 ( p r e d + 1 ) 2 h = \frac{\partial^2{objective}}{\partial{pred}} = \frac{ - \log(pred + 1) + \log(label + 1) + 1}{(pred + 1)^2} h=pred2objective=(pred+1)2log(pred+1)+log(label+1)+1

在模型训练过程中,目标函数起着重要的作用:基于模型预测和观察到的数据标签(或目标),提供梯度信息,包括一阶和二阶梯度。因此,有效的目标函数应接受两个输入,即预测值和标签。对于实现SLE,定义:

import numpy as np
import xgboost as xgb
from typing import Tupledef gradient(predt: np.ndarray, dtrain: xgb.DMatrix) -> np.ndarray:'''Compute the gradient squared log error.'''y = dtrain.get_label()return (np.log1p(predt)-np.log1p(y)) / (predt+1)def hessian(predt: np.ndarray, dtrain: xgb.DMatrix) -> np.ndarray:'''Compute the hessian for squared log error.'''y = dtrain.get_label()return ((-np.log1p(predt)+np.log1p(y)+1) /np.power(predt+1, 2))def squared_log(predt: np.ndarray,dtrain: xgb.DMatrix) -> Tuple[np.ndarray, np.ndarray]:'''Squared Log Error objective. A simplified version for RMSLE used asobjective function.'''predt[predt < -1] = -1 + 1e-6grad = gradient(predt, dtrain)hess = hessian(predt, dtrain)return grad, hess

在上面的代码片段中,squared_log是想要的目标函数。它接受一个numpy数组predt作为模型预测值,以及用于获取所需信息的训练DMatrix,包括标签和权重(此处未使用)。然后,在训练过程中,通过将其作为参数传递给xgb.train,将此目标函数用作XGBoost的回调函数:

xgb.train({'tree_method': 'hist', 'seed': 1994},   # any other tree method is fine.dtrain=dtrain,num_boost_round=10,obj=squared_log)

注意,在定义目标函数时,从预测值中减去标签或从标签中减去预测值,这是很重要的。如果发现训练错误上升而不是下降,这可能是原因。

定制度量函数

因此,在拥有自定义目标函数之后,还需要一个相应的度量标准来监控模型的性能。如上所述,SLE 的默认度量标准是 RMSLE。同样,定义另一个类似的回调函数作为新的度量标准:

def rmsle(predt: np.ndarray, dtrain: xgb.DMatrix) -> Tuple[str, float]:''' Root mean squared log error metric.'''y = dtrain.get_label()predt[predt < -1] = -1 + 1e-6elements = np.power(np.log1p(y) - np.log1p(predt), 2)return 'PyRMSLE', float(np.sqrt(np.sum(elements) / len(y)))

与目标函数类似,度量也接受 predtdtrain 作为输入,但返回度量本身的名称和一个浮点值作为结果。将其作为 custom_metric 参数传递给 XGBoost:

xgb.train({'tree_method': 'hist', 'seed': 1994,'disable_default_eval_metric': 1},dtrain=dtrain,num_boost_round=10,obj=squared_log,custom_metric=rmsle,evals=[(dtrain, 'dtrain'), (dtest, 'dtest')],evals_result=results)

能够看到 XGBoost 打印如下内容:

[0] dtrain-PyRMSLE:1.37153  dtest-PyRMSLE:1.31487
[1] dtrain-PyRMSLE:1.26619  dtest-PyRMSLE:1.20899
[2] dtrain-PyRMSLE:1.17508  dtest-PyRMSLE:1.11629
[3] dtrain-PyRMSLE:1.09836  dtest-PyRMSLE:1.03871
[4] dtrain-PyRMSLE:1.03557  dtest-PyRMSLE:0.977186
[5] dtrain-PyRMSLE:0.985783 dtest-PyRMSLE:0.93057
...

注意,参数 disable_default_eval_metric 用于禁用 XGBoost 中的默认度量。

完整可复制的源代码参阅定义自定义回归目标和度量的演示。

转换链接函数

在使用内置目标函数时,原始预测值会根据目标函数进行转换。当提供自定义目标函数时,XGBoost 不知道其链接函数,因此用户需要对目标和自定义评估度量进行转换。对于具有身份链接的目标,如平方误差squared error,这很简单,但对于其他链接函数,如对数链接或反链接,差异很大。

在 Python 包中,可以通过 predict 函数中的 output_margin 参数来控制预测的行为。当使用 custom_metric 参数而没有自定义目标函数时,度量函数将接收经过转换的预测,因为目标是由 XGBoost 定义的。然而,当同时提供自定义目标和度量时,目标和自定义度量都将接收原始预测。以下示例比较了多类分类模型中两种不同的行为。首先,我们定义了两个不同的 Python 度量函数,实现了相同的底层度量以进行比较。其中 merror_with_transform 在同时使用自定义目标时使用,否则会使用更简单的 merror,因为 XGBoost 可以自行执行转换。

import xgboost as xgb
import numpy as npdef merror_with_transform(predt: np.ndarray, dtrain: xgb.DMatrix):"""Used when custom objective is supplied."""y = dtrain.get_label()n_classes = predt.size // y.shape[0]# Like custom objective, the predt is untransformed leaf weight when custom objective# is provided.# With the use of `custom_metric` parameter in train function, custom metric receives# raw input only when custom objective is also being used.  Otherwise custom metric# will receive transformed prediction.assert predt.shape == (d_train.num_row(), n_classes)out = np.zeros(dtrain.num_row())for r in range(predt.shape[0]):i = np.argmax(predt[r])out[r] = iassert y.shape == out.shapeerrors = np.zeros(dtrain.num_row())errors[y != out] = 1.0return 'PyMError', np.sum(errors) / dtrain.num_row()

仅当想要使用自定义目标并且 XGBoost 不知道如何转换预测时才需要上述函数。多类误差函数的正常实现是:

def merror(predt: np.ndarray, dtrain: xgb.DMatrix):"""Used when there's no custom objective."""# No need to do transform, XGBoost handles it internally.errors = np.zeros(dtrain.num_row())errors[y != out] = 1.0return 'PyMError', np.sum(errors) / dtrain.num_row()

接下来需要自定义 softprob 目标:

def softprob_obj(predt: np.ndarray, data: xgb.DMatrix):"""Loss function.  Computing the gradient and approximated hessian (diagonal).Reimplements the `multi:softprob` inside XGBoost."""# Full implementation is available in the Python demo script linked below...return grad, hess

最后可以使用 objcustom_metric 参数训练模型:

Xy = xgb.DMatrix(X, y)
booster = xgb.train({"num_class": kClasses, "disable_default_eval_metric": True},m,num_boost_round=kRounds,obj=softprob_obj,custom_metric=merror_with_transform,evals_result=custom_results,evals=[(m, "train")],
)

如果不需要自定义目标,只是想提供一个XGBoost中不可用的指标:

booster = xgb.train({"num_class": kClasses,"disable_default_eval_metric": True,"objective": "multi:softmax",},m,num_boost_round=kRounds,# Use a simpler metric implementation.custom_metric=merror,evals_result=custom_results,evals=[(m, "train")],
)

使用multi:softmax来说明转换后预测的差异。使用softprob时,输出预测数组的形状是(n_samples, n_classes),而对于softmax,它是(n_samples, )。关于多类目标函数的示例也可以在创建自定义多类目标函数的示例中找到。此外,更多解释请参见Intercept。

Scikit-Learn 接口

XGBoost的scikit-learn接口提供了一些工具,以改善与标准的scikit-learn函数的集成,用户可以直接使用scikit-learn的成本函数(而不是评分函数):

from sklearn.datasets import load_diabetes
from sklearn.metrics import mean_absolute_errorX, y = load_diabetes(return_X_y=True)
reg = xgb.XGBRegressor(tree_method="hist",eval_metric=mean_absolute_error,
)
reg.fit(X, y, eval_set=[(X, y)])

对于自定义目标函数,用户可以在不访问DMatrix的情况下定义目标函数:

def softprob_obj(labels: np.ndarray, predt: np.ndarray) -> Tuple[np.ndarray, np.ndarray]:rows = labels.shape[0]classes = predt.shape[1]grad = np.zeros((rows, classes), dtype=float)hess = np.zeros((rows, classes), dtype=float)eps = 1e-6for r in range(predt.shape[0]):target = labels[r]p = softmax(predt[r, :])for c in range(predt.shape[1]):g = p[c] - 1.0 if c == target else p[c]h = max((2.0 * p[c] * (1.0 - p[c])).item(), eps)grad[r, c] = ghess[r, c] = hgrad = grad.reshape((rows * classes, 1))hess = hess.reshape((rows * classes, 1))return grad, hessclf = xgb.XGBClassifier(tree_method="hist", objective=softprob_obj)

参考

  • https://xgboost.readthedocs.io/en/latest/tutorials/custom_metric_obj.html
  • https://xgboost.readthedocs.io/en/latest/python/examples/custom_rmsle.html#sphx-glr-python-examples-custom-rmsle-py

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/719681.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【EAI 027】Learning Interactive Real-World Simulators

Paper Card 论文标题&#xff1a;Learning Interactive Real-World Simulators 论文作者&#xff1a;Mengjiao Yang, Yilun Du, Kamyar Ghasemipour, Jonathan Tompson, Leslie Kaelbling, Dale Schuurmans, Pieter Abbeel 作者单位&#xff1a;UC Berkeley, Google DeepMind, …

【 Docker 容器详细介绍和说明】

Docker 容器详细介绍和说明 Docker 容器详细介绍和说明Docker 安装步骤&#xff08;以Ubuntu为例&#xff09;&#xff1a;使用Docker创建并运行容器&#xff1a;VSCode远程连接Docker容器&#xff1a;步骤1&#xff1a;配置Docker环境步骤2&#xff1a;配置PyCharm步骤3&#…

日本发动全面侵华战争他们在怕什么?为何不敢动陕西,

日本全面侵华战争之谜&#xff1a;恐惧与野心的交织 在二十世纪三十年代&#xff0c;日本帝国主义以令人发指的暴行和残忍手段&#xff0c;对中国发动了全面侵华战争。然而&#xff0c;在这场战争中&#xff0c;有一个引人关注的现象&#xff1a;日本侵略者在进攻过程中&#…

python和nodejs一键安装当前项目所有依赖

python和nodejs一键安装当前项目所有依赖。群里有人问怎么快速安装网上下载的源码里面的依赖。所以在这里分享一下。更多问题可以自己加群917400262问我。 目录导航 1.0 python一键安装当前项目所有依赖2.0 nodejs一键安装当前项目所有依赖 1.0 python一键安装当前项目所有依赖…

snakemake: 基础知识

为了有效地学习和使用 Snakemake&#xff0c;你需要具备一定的基础知识。这些基础知识将帮助你更好地理解 Snakemake 的工作原理和如何在你的项目中应用它。以下是学习 Snakemake 所需的一些基础知识&#xff1a; 1. Python 编程 Snakemake 是用 Python 编写的&#xff0c;并…

聊聊国内「类Sora模型」发展现状,和 Sora 的差距到底有多大?

2024 年 2 月 16 日。 就在谷歌发布他新一代的多模态大模型 Gemini 1.5 Pro 的同一天&#xff0c;OpenAI 带着新一代的文生视频模型 Sora 再次抓住了全世界人们的眼球。 “颠覆”、“炸裂”、“变天”、“疯狂”&#xff0c;类似的形容词一夜之间簇拥在 Sora 周围&#xff0c;…

网络传输基本流程(封装,解包)+图解(同层直接通信的证明),报头分离问题,协议定位问题,协议多路复用

目录 网络传输基本流程 引入 封装 过程梳理 图解 报文 解包 过程梳理 图解 -- 同层直接通信的证明 总结 解包时的报头分离问题 举例 -- 倒水 介绍 自底向上传输时的协议定位问题 介绍 解决方法 协议多路复用 介绍 优势 网络传输基本流程 引入 首先,我们明确…

VS查看C++头文件(.h文件)的函数列表

这里使用的是VS2019举例 如下图查看Actor.h文件中的函数列表 设置步骤如下图

【d35】【Java】【力扣】28. 找出字符串中第一个匹配项的下标

题目 给你两个字符串 haystack 和 needle &#xff0c;请你在 haystack 字符串中找出 needle 字符串的第一个匹配项的下标&#xff08;下标从 0 开始&#xff09;。如果 needle 不是 haystack 的一部分&#xff0c;则返回 -1 。 示例 1&#xff1a; 输入&#xff1a;haystac…

【大数据】通过 docker-compose 快速部署 MinIO 保姆级教程

文章目录 一、概述二、MinIO 与 Ceph 对比1&#xff09;架构设计对比2&#xff09;数据一致性对比3&#xff09;部署和管理对比4&#xff09;生态系统和兼容性对比 三、前期准备1&#xff09;部署 docker2&#xff09;部署 docker-compose 四、创建网络五、MinIO 编排部署1&…

【SQL】608. 树节点(流控制语句 CASE + IF语句)

前述 知识点推荐学习&#xff1a; sql中的 IF 条件语句的用法 MySQL&#xff1a;if语句、if…else语句、case语句&#xff0c;使用方法解析 题目描述 leetcode 题目&#xff1a;608. 树节点 思路 关键点&#xff1a;如何确定有没有子节点 根节点&#xff1a;父节点为空内节…

基于Redo log Undo log的MySQL的崩溃恢复

基于Redo log & Undo log的MySQL的崩溃恢复 Redo log Undo log Redo log 重做日志,记录,修改过的数据 Undo log 回滚日志,记录修改之前的数据 两个我不做详细的介绍了,redo log就是记录哪些地方被修改了 undo log是记录修改之前我们的数据长什么样 更新流程 我们来捋一…

python封装,继承,复写详解

目录 1.封装 2.继承 复写和使用父类成员 1.封装 class phone:__voltage 0.5def __keepsinglecore(self):print("单核运行")def callby5g(self):if self.__voltage > 1:print("5g通话开启")else:self.__keepsinglecore()print("不能开启5g通…

Redis集群(主从)

1.主从集群 集群结构: 一.单机安装redis 1.上传压缩包并解压&#xff0c;编译 tar -xzf redis-6.2.4.tar.gz cd redis-6.2.4 make && make install 2.修改redis.config的配置并启动redis # 绑定地址&#xff0c;默认是127.0.0.1&#xff0c;会导致只能在本地访问。…

Tomcat布署及优化-----JDK和Tomcat

1.Tomcat简介 Tomcat 是 Java 语言开发的&#xff0c;Tomcat 服务器是一个免费的开放源代码的 Web 应用服务器&#xff0c;Tomcat 属于轻量级应用服务器&#xff0c;在中小型系统和并发访问用户不是很多的场合下被普遍使用&#xff0c;是开发和调试 JSP 程序的首选。一般来说&…

C++ //练习 10.2 重做上一题,但读取string序列存入list中。

C Primer&#xff08;第5版&#xff09; 练习 10.2 练习 10.2 重做上一题&#xff0c;但读取string序列存入list中。 环境&#xff1a;Linux Ubuntu&#xff08;云服务器&#xff09; 工具&#xff1a;vim 代码块 /******************************************************…

Vue前端加密后的数据发送到服务器端

首先&#xff0c;定义了一个名为 PUBLIC_KEY 的公钥和一个名为 PRIVATE_KEY 的私钥。然后&#xff0c;通过 JSEncrypt 创建了两个实例 encrypt 和 decrypt&#xff0c;分别用于加密和解密操作。 对于加密操作&#xff0c;调用了 encrypt.setPublicKey() 方法设置公钥&#xff…

升级Centos7的openssh到openssh-9.6p1版本 shell脚本 漏扫整改

升级Centos7的openssh到openssh-9.6p1版本 shell脚本 漏扫整改 #!/bin/bash# 声明: 该脚本适用于升级Centos7的openssh到openssh-9.6p1版本# 定义源码包版本号 OPENSSH_VERSIONopenssh-9.6p1 OPENSSL_VERSIONopenssl-3.2.1 ZILB_VERSIONzlib-1.3.1# 安装编译环境 yum -y insta…

【前端面试题5】利用 border 属性画一个三角形

举例1&#xff1a;利用 border 属性画一个三角形&#xff08;小技巧&#xff09; 完整代码如下&#xff1a; div{width: 0;height: 0;border: 50px solid transparent;border-top-color: red;border-bottom: none; }步骤如下&#xff1a; &#xff08;1&#xff09;当我们设…

【QT+QGIS跨平台编译】之五十六:【QGIS_CORE跨平台编译】—【qgsmeshcalclexer.cpp生成】

文章目录 一、Flex二、生成来源三、构建过程一、Flex Flex (fast lexical analyser generator) 是 Lex 的另一个替代品。它经常和自由软件 Bison 语法分析器生成器 一起使用。Flex 最初由 Vern Paxson 于 1987 年用 C 语言写成。 “flex 是一个生成扫描器的工具,能够识别文本中…