使用xgboost训练具有多个连续输出(多元回归)的模型是否可能? 训练此类模型的目标是什么?
提前感谢任何建议。
使用xgboost训练具有多个连续输出(多元回归)的模型是否可能? 训练此类模型的目标是什么?
提前感谢任何建议。
我的建议是使用sklearn.multioutput.MultiOutputRegressor作为xgb.XGBRegressor
的包装器。 MultiOutputRegressor
为每个目标训练一个回归器,并且只需要回归器实现fit
和predict
,而这正好是xgboost支持的。
# 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
这可能是使用xgboost回归多维目标的最简单方法,因为您不需要更改代码的任何其他部分(如果您最初使用sklearn API)。
但是,此方法不利用任何可能存在的目标之间的关系。但是,您可以尝试设计一个自定义目标函数来实现。
多输出回归现在可以在 XGBoost 的夜间版本中使用,并将包含在 XGBoost 1.6.0 中。
请参阅https://github.com/dmlc/xgboost/blob/master/demo/guide-python/multioutput_regression.py获取示例。
它会生成警告:
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]
我想留下评论,但是我没有声望。除了@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
hist
。
指定multi_strategy = "multi_output_tree"
训练参数以构建多输出树:clf = xgb.XGBClassifier(tree_method="hist", multi_strategy="multi_output_tree")
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"
,默认情况下,将为每个目标构建一个模型。一般来说,我希望这个选项能够获得更好的结果。您可以使用 scikit-learn 中的线性回归、随机森林回归器和其他相关算法来生成多输出回归。不确定 XGboost 是否支持。Scikit 中的增强回归器不允许多个输出。对于那些提出疑问的人,需要使用多步时间序列预测,这是一个例子。