XGB-6: 单调性约束Monotonic Constraints

2024-02-09 21:28

本文主要是介绍XGB-6: 单调性约束Monotonic Constraints,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

在建模问题或项目中,通常情况下,可接受模型的函数形式会以某种方式受到约束。这可能是由于业务考虑,或者由于正在研究的科学问题的类型。在某些情况下,如果对真实关系有非常强烈的先验信念,可以使用约束来提高模型的预测性能

在这种情况下的一种常见约束类型是,某些特征与预测响应呈单调关系

f ( x 1 , x 2 , … , x , … , x n − 1 , x n ) ≤ f ( x 1 , x 2 , … , x ′ , … , x n − 1 , x n ) f(x_1, x_2, \ldots, x, \ldots, x_{n-1}, x_n) \leq f(x_1, x_2, \ldots, x', \ldots, x_{n-1}, x_n) f(x1,x2,,x,,xn1,xn)f(x1,x2,,x,,xn1,xn)

无论何时 x ≤ x ′ x \leq x' xx是一个增加约束;或者

f ( x 1 , x 2 , … , x , … , x n − 1 , x n ) ≥ f ( x 1 , x 2 , … , x ′ , … , x n − 1 , x n ) f(x_1, x_2, \ldots, x, \ldots, x_{n-1}, x_n) \geq f(x_1, x_2, \ldots, x', \ldots, x_{n-1}, x_n) f(x1,x2,,x,,xn1,xn)f(x1,x2,,x,,xn1,xn)

无论何时 x ≤ x ′ x \leq x' xx是一个递减约束;

XGBoost具有对增强模型中使用的任何特征执行单调性约束的能力。

简单示例

为了说明,创建一些模拟数据,其中包含两个特征和一个响应,符合以下方案

y = 5 x 1 + sin ⁡ ( 10 π x 1 ) − 5 x 2 − cos ⁡ ( 10 π x 2 ) + N ( 0 , 0.01 ) x 1 , x 2 ∈ [ 0 , 1 ] y = 5 x_1 + \sin(10 \pi x_1) - 5 x_2 - \cos(10 \pi x_2) + N(0, 0.01) x_1, x_2 \in [0, 1] y=5x1+sin(10πx1)5x2cos(10πx2)+N(0,0.01)x1,x2[0,1]

响应通常随着 x 1 x_1 x1特征的增加而增加,但叠加了正弦变化,导致真实效果是非单调的。对于 x 2 x_2 x2特征,变化是减小的,具有正弦变化。

https://raw.githubusercontent.com/dmlc/web-data/master/xgboost/monotonic/two.feature.sample.data.png

现在对这些数据进行拟合,而不施加任何单调性约束:

https://raw.githubusercontent.com/dmlc/web-data/master/xgboost/monotonic/two.feature.no.constraint.png

黑色曲线显示了从模型中推断出的每个特征的趋势。为了制作这些图,将突出显示的特征 x 1 x_1 x1传递给模型,其值在一维网格上变化,而所有其他特征(在这种情况下只有一个其他特征)被设置为它们的平均值。可以看到该模型很好地捕捉了周期波动的总体趋势。

这是相同的模型,但使用了单调性约束进行拟合:

https://raw.githubusercontent.com/dmlc/web-data/master/xgboost/monotonic/two.feature.with.constraint.png

从上图可以看到约束的效果。对于每个变量,趋势的一般方向仍然明显,但振荡行为不再存在,因为这违反了强加的约束。

在 XGBoost 中强制执行单调约束

在XGBoost中强制执行单调性约束非常简单。这里将使用Python进行示例,但相同的一般思想可以推广到其他平台。

假设以下代码在没有单调性约束的情况下拟合模型:

model_no_constraints = xgb.train(params, dtrain,num_boost_round = 1000, evals = evallist,early_stopping_rounds = 10)

然后拟合单调性约束只需要添加单个参数

params_constrained = params.copy()
params_constrained['monotone_constraints'] = (1, -1)model_with_constraints = xgb.train(params_constrained, dtrain,num_boost_round = 1000, evals = evallist,early_stopping_rounds = 10)

在这个例子中,训练数据 X 有两列,通过使用参数值 (1,-1),告诉 XGBoost 对第一个预测器施加递增约束,并对第二个预测器施加递减约束。

其他一些例子:

  • (1, 0): 对第一个预测器施加递增约束,对第二个预测器没有约束
  • (0, -1): 对第一个预测器没有约束,对第二个预测器施加递减约束

注意

‘hist’ tree construction algorithm的注意事项。如果将tree_method设置为histapprox,启用单调性约束可能会导致树变得不必要地浅。这是因为hist方法减少了在每个分裂处考虑的候选分裂数。单调性约束可能会清除所有可用的分裂候选项,如果发生这种情况,将不会进行分裂。为减少影响,可能需要增加max_bin参数以考虑更多的分裂候选项。

使用特征名称

XGBoost的Python包支持使用特征名称而不是特征索引来指定约束。假设有一个包含列 [ " f 0 " , " f 1 " , " f 2 " ] ["f0", "f1", "f2"] ["f0","f1","f2"]的数据框,可以将单调性约束指定为 " f 0 " : 1 , " f 2 " : − 1 {"f0": 1, "f2": -1} "f0":1,"f2":1,而"f1"将默认为0(无约束)。

import xgboost as xgb
import numpy as np
import matplotlib.pyplot as plt# Simulated data
np.random.seed(42)
num_samples = 1000
X = np.random.rand(num_samples, 2)def calculate_y(X):x1 = X[:, 0]x2 = X[:, 1]return 5 * x1 + np.sin(10 * np.pi * x1) - 5 * x2 - np.cos(10 * np.pi * x2) + np.random.normal(0, 0.01, len(X))y = calculate_y(X)# Fitting a model without monotonicity constraints
params = {'objective': 'reg:squarederror', 'booster': 'gbtree'}
model = xgb.XGBRegressor(**params)
model.fit(X, y)y_pred = model.predict(X)# Fitting a model with monotonicity constraints
params_constrained = {'objective': 'reg:squarederror', 'booster': 'gbtree', 'monotone_constraints': '(1, -1)'}
model_constrained = xgb.XGBRegressor(**params_constrained)
model_constrained.fit(X, y)y_constrained_pred = model_constrained.predict(X)fig, axs = plt.subplots(2, 2, figsize=(12, 10))axs[0, 0].scatter(X[:, 0], y_pred)
axs[0, 0].set_xlabel('X1')
axs[0, 0].set_ylabel('Y')
axs[0, 0].set_title('X1-Y Relationship')axs[0, 1].scatter(X[:, 1], y_pred)
axs[0, 1].set_xlabel('X2')
axs[0, 1].set_ylabel('Y')
axs[0, 1].set_title('X2-Y Relationship')axs[1, 0].scatter(X[:, 0], y_constrained_pred)
axs[1, 0].set_xlabel('X1')
axs[1, 0].set_ylabel('Y')
axs[1, 0].set_title('X1-Y constraints Relationship')axs[1, 1].scatter(X[:, 1], y_constrained_pred)
axs[1, 1].set_xlabel('X2')
axs[1, 1].set_ylabel('Y')
axs[1, 1].set_title('X2-Y constraints Relationship')plt.tight_layout()plt.show()

KbeCA.png

参考

  • https://xgboost.readthedocs.io/en/latest/tutorials/monotonic.html

这篇关于XGB-6: 单调性约束Monotonic Constraints的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/695324

相关文章

SQL中的外键约束

外键约束用于表示两张表中的指标连接关系。外键约束的作用主要有以下三点: 1.确保子表中的某个字段(外键)只能引用父表中的有效记录2.主表中的列被删除时,子表中的关联列也会被删除3.主表中的列更新时,子表中的关联元素也会被更新 子表中的元素指向主表 以下是一个外键约束的实例展示

poj 3159 (spfa差分约束最短路) poj 1201

poj 3159: 题意: 每次给出b比a多不多于c个糖果,求n最多比1多多少个糖果。 解析: 差分约束。 这个博客讲差分约束讲的比较好: http://www.cnblogs.com/void/archive/2011/08/26/2153928.html 套个spfa。 代码: #include <iostream>#include <cstdio>#i

poj 3169 spfa 差分约束

题意: 给n只牛,这些牛有些关系。 ml个关系:fr 与 to 牛间的距离要小于等于 cost。 md个关系:fr 与 to 牛间的距离要大于等于 cost。 隐含关系: d[ i ] <= d[ i + 1 ] 解析: 用以上关系建图,求1-n间最短路即可。 新学了一种建图的方法。。。。。。 代码: #include <iostream>#include

POJ 1364差分约束

给出n个变量,m个约束公式 Sa + Sa+1 + .... + Sa+b < ki or > ki ,叫你判断是否存在着解满足这m组约束公式。 Sa + Sa+1   +   .+ Sa+b =  Sum[a+b] - Sum[a-1]  . 注意加入源点n+1 。 public class Main {public static void main(Strin

POJ1631最长单调递增子序列

最长单调递增子序列 import java.io.BufferedReader;import java.io.InputStream;import java.io.InputStreamReader;import java.io.PrintWriter;import java.math.BigInteger;import java.util.StringTokenizer;publ

创建表时添加约束

查询表中的约束信息: SHOW KEYS FROM 表名; 示例: 创建depts表包含department_id该列为主键自动增长,department_name列不允许重复,location_id列不允许有空值。 create table depts(department_id int primary key auto_increment,department_name varcha

力扣 739. 每日温度【经典单调栈题目】

1. 题目 理解题意: 1.1. 给一个温度集合, 要返回一个对应长度的结果集合, 这个结果集合里面的元素 i 是 当前 i 位置的元素的下一个更高温度的元素的位置和当前 i 位置的距离之差, 若是当前元素不存在下一个更高温度的元素, 则这个位置用0代替; 2. 思路 本题用单调栈来求解;单调栈就适用于来求当前元素左边或者右边第一个比当前元素大或者小的元素;【单调栈:让栈中的元素保持单调

非空约束(Not Null)

修改表添加非空约束 使用DDL语句添加非空约束 ALTER TABLE 表名 MODIFY 列名 类型 NOT NULL; 示例: 向emp表中的salary添加非空约束。 alter table emp modify salary float(8,2) not NULL; 删除非空约束 使用DDL语句删除非空约束 ALTER TABLE 表名 MODIFY 列名 类型 NULL;

双指针(5)_单调性_有效三角形的个数

个人主页:C++忠实粉丝 欢迎 点赞👍 收藏✨ 留言✉ 加关注💓本文由 C++忠实粉丝 原创 双指针(5)_单调性_有效三角形的个数 收录于专栏【经典算法练习】 本专栏旨在分享学习C++的一点学习笔记,欢迎大家在评论区交流讨论💌 目录 1. 题目链接: 2.题目描述 : 3.解法 :     解法一(暴力枚举) :     算法思路 :     代码展示 : 暴力枚

机器学习模型中的因果关系:引入单调约束

单调约束是使机器学习模型可行的关键,但它们仍未被广泛使用欢迎来到雲闪世界。 碳ausality 正在迅速成为每个数据科学家工具包中必不可少的组成部分。 这是有充分理由的。 事实上,因果模型在商业中具有很高的价值,因为它们为“假设”情景提供了更可靠的估计,特别是在用于做出影响业务结果的决策时。 在本文中,我将展示如何通过简单的更改(实际上添加一行代码)将传统的 ML 模型(如随机森林、L