XGBoost实现的多输出回归

47

使用训练具有多个连续输出(多元回归)的模型是否可能? 训练此类模型的目标是什么?

提前感谢任何建议。


如果输出有多个值,则需要像RNN(GRU,LSTM等)这样的序列模型。 [Keras](https://keras.io/)可以帮助您快速原型化此类模型。 - uyaseen
我知道RNN。我想知道在Xgboost中是否也可能有这样的东西,因为我已经知道提升树在我的问题空间中表现良好。我还应该注意到,我的输出向量大小可以固定。 - user1782011
1
如果输出之间的关系已知,您应该能够实现一个利用此优势的目标函数。这已经对于具有线性关系的随机森林完成了(参见:https://cran.r-project.org/web/packages/MultivariateRandomForest/MultivariateRandomForest.pdf)。而且XGBoost的作者认为这是可以做到的(参见:https://github.com/dmlc/xgboost/issues/680)。 - Adrien Renaud
4
这并不正确,只有在输出数量可变时才是如此(甚至这也不一定正确)。您可以拥有多个输出,并在它们之上计算总损失。 - Jan van der Vegt
7个回答

66

我的建议是使用sklearn.multioutput.MultiOutputRegressor作为xgb.XGBRegressor的包装器。 MultiOutputRegressor为每个目标训练一个回归器,并且只需要回归器实现fitpredict,而这正好是支持的。

# get some noised linear data
X = np.random.random((1000, 10))
a = np.random.random((10, 3))
y = np.dot(X, a) + np.random.normal(0, 1e-3, (1000, 3))

# fitting
multioutputregressor = MultiOutputRegressor(xgb.XGBRegressor(objective='reg:linear')).fit(X, y)

# predicting
print(np.mean((multioutputregressor.predict(X) - y)**2, axis=0))  # 0.004, 0.003, 0.005

这可能是使用回归多维目标的最简单方法,因为您不需要更改代码的任何其他部分(如果您最初使用 API)。

但是,此方法不利用任何可能存在的目标之间的关系。但是,您可以尝试设计一个自定义目标函数来实现。


4
可以给我一个例子吗?回归问题应该有固定的输入和输出形状,否则它不是一个单一的问题,应该分别处理。 - ComeOnGetMe
例如,您被要求预测不同粒子的位置(比如在一个位置数组中),有时某些粒子具有多个位置是有效的(例如最多6个有效位置)。 - Eran
也许你需要使用“特征哈希”(哈希技巧)这样的技术。 - Santino
5
这不是一个具有两个输出的模型,而是围绕两个模型的包装器。 - Itamar Mushkin
1
可能与此相关的人:在论文“我们真的需要深度学习来进行时间序列预测吗?”中,作者使用了sklearn的MultiOutputRegressor来执行多步时间序列预测(例如,预测某个变量未来24小时的值)。作者声称这种方法击败了许多基于神经网络的方法。论文代码 - KasperGL
显示剩余4条评论

11

1
这是个好消息!谢谢你分享! - Adib
独立为每个y目标拟合每个模型是否有任何区别? - olivia
4
显然,这个库实现仍然为每个输出构建单独的模型而不是共享模型:https://github.com/dmlc/xgboost/blob/master/doc/tutorials/multioutput.rst - Marcin Wojnarski

6

它会生成警告:

reg:linear现在已被弃用,推荐使用reg:squarederror

因此,我根据@ComeOnGetMe的答案进行了更新。

import numpy as np 
import pandas as pd 
import xgboost as xgb
from sklearn.multioutput import MultiOutputRegressor

# get some noised linear data
X = np.random.random((1000, 10))
a = np.random.random((10, 3))
y = np.dot(X, a) + np.random.normal(0, 1e-3, (1000, 3))

# fitting
multioutputregressor = MultiOutputRegressor(xgb.XGBRegressor(objective='reg:squarederror')).fit(X, y)

# predicting
print(np.mean((multioutputregressor.predict(X) - y)**2, axis=0))

输出:

[2.00592697e-05 1.50084441e-05 2.01412247e-05]

3

我想留下评论,但是我没有声望。除了@Jesse Anderson之外,若要安装最新版本,请从此处选择顶部链接: https://s3-us-west-2.amazonaws.com/xgboost-nightly-builds/list.html?prefix=master/

确保选择适合您操作系统的版本。

使用pip install命令来安装wheel。例如对于macOS:

pip install https://s3-us-west-2.amazonaws.com/xgboost-nightly-builds/master/xgboost-1.6.0.dev0%2B4d81c741e91c7660648f02d77b61ede33cef8c8d-py3-none-macosx_10_15_x86_64.macosx_11_0_x86_64.macosx_12_0_x86_64.whl


1
根据上述讨论,我已经扩展了单变量的XGBoostLSS到一个多变量框架,称为多目标XGBoostLSS回归,它在概率回归设置中建模多个目标及其依赖关系。代码即将发布。

你的回答可以通过提供更多支持信息来改进。请编辑以添加进一步的细节,例如引用或文档,以便他人可以确认你的答案是正确的。您可以在帮助中心中找到有关如何编写良好答案的更多信息。 - Community

1
2.0.0 xgboost release支持具有向量叶子输出的多目标树。 这意味着xgboost现在可以构建多输出树,其中叶子的大小等于目标的数量。必须使用树方法hist。 指定multi_strategy = "multi_output_tree"训练参数以构建多输出树:
clf = xgb.XGBClassifier(tree_method="hist", multi_strategy="multi_output_tree")

一个基于@ComeAndGetMe答案的回归示例:
import numpy as np 
import pandas as pd 
import xgboost as xgb

print('xgb version:', xgb.__version__)

# get some noised linear data
X = np.random.random((1000, 10))
a = np.random.random((10, 3))
y = np.dot(X, a) + np.random.normal(0, 1e-3, (1000, 3))

# fitting
multioutputregressor = xgb.XGBRegressor(objective      = "reg:squarederror",
                                        tree_method    = "hist", 
                                        multi_strategy = "multi_output_tree")
multioutputregressor.fit(X, y)

# predicting on the training data
print('mse:', np.mean((multioutputregressor.predict(X) - y)**2, axis=0))

输出:

xgb version: 2.0.0
mse: [9.43447858e-05 8.78643942e-05 9.99183540e-05]

设置multi_strategy="one_output_per_tree",默认情况下,将为每个目标构建一个模型。一般来说,我希望这个选项能够获得更好的结果。
另请参阅xgboost的多输出回归教程
截至目前为止,xgboost对于多个输出的支持被视为实验性质,只有Python版本经过了测试。

0

您可以使用 scikit-learn 中的线性回归、随机森林回归器和其他相关算法来生成多输出回归。不确定 XGboost 是否支持。Scikit 中的增强回归器不允许多个输出。对于那些提出疑问的人,需要使用多步时间序列预测,这是一个例子。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接