多输出回归是涉及根据输入示例预测两个或多个数值的回归问题。
一个例子可能是根据输入预测一个坐标,例如预测x和y值。另一个例子是多步时间序列预测,这涉及预测给定变量的多个未来时间序列。
许多机器学习算法旨在预测单个数值,通常简称为回归。一些算法本身就支持多输出回归,例如线性回归和决策树。还有一些特殊的解决方法模型,可以用来包装和使用那些不原生支持预测多个输出的算法。
在本教程中,您将了解如何开发多输出回归的机器学习模型。
完成本教程后,您将了解:
- 机器学习中的多输出回归问题。
- 如何开发原生支持多输出回归的机器学习模型。
- 如何开发包装器模型,使不支持原生多输出的算法可以用于多输出回归。
启动您的项目,阅读我的新书《Python集成学习算法》,其中包括分步教程和所有示例的Python源代码文件。
让我们开始吧。
- 更新于2020年8月:扩展了包装器模型的示例。

如何在Python中开发多输出回归模型
照片由a_terracini拍摄,保留部分权利。
教程概述
本教程分为五个部分;它们是:
- 多输出回归问题
- 检查Scikit-Learn版本
- 多输出回归测试问题
- 原生多输出回归算法
- 线性回归用于多输出回归
- k-最近邻用于多输出回归
- 通过交叉验证评估多输出回归
- 包装器多输出回归算法
- 直接多输出回归
- 链式多输出回归
多输出回归问题
回归是指涉及预测数值的预测建模问题。
例如,预测尺寸、重量、数量、销售额和点击次数都是回归问题。通常,根据输入变量预测一个数值。
有些回归问题需要预测两个或多个数值。例如,预测x和y坐标。
这些问题被称为多输出回归。
- 回归:根据输入预测单个数值输出。
- 多输出回归:根据输入预测两个或多个数值输出。
在多输出回归中,输出通常取决于输入以及它们彼此之间的关系。这意味着输出之间通常不是独立的,可能需要一个能够同时预测两个输出,或者根据其他输出预测每个输出的模型。
多步时间序列预测可以被视为一种多输出回归,其中预测未来值的序列,并且每个预测值都依赖于序列中的先前值。
有许多处理多输出回归的策略,我们将在本教程中探讨其中一些。
想开始学习集成学习吗?
立即参加我为期7天的免费电子邮件速成课程(附示例代码)。
点击注册,同时获得该课程的免费PDF电子书版本。
检查Scikit-Learn版本
首先,请确认您已安装了最新版本的scikit-learn库。
这一点很重要,因为本教程中我们将要探讨的一些模型需要较新版本的库。
您可以使用以下代码示例检查库的版本
1 2 3 |
# 检查 scikit-learn 版本 import sklearn print(sklearn.__version__) |
运行示例将打印出库的版本。
在撰写本文时,大约是0.22版本。您需要使用此版本的scikit-learn或更高版本。
1 |
0.22.1 |
多输出回归测试问题
我们可以定义一个测试问题来演示不同的建模策略。
我们将使用make_regression()函数来创建多输出回归的测试数据集。我们将生成1000个示例,其中包含10个输入特征,其中5个是冗余的,5个是信息性的。该问题将需要预测两个数值。
- 问题输入:10个数值变量。
- 问题输出:2个数值变量。
以下示例生成数据集并总结其形状。
1 2 3 4 5 6 |
# 多输出回归测试问题的示例 from sklearn.datasets import make_regression # 创建数据集 X, y = make_regression(n_samples=1000, n_features=10, n_informative=5, n_targets=2, random_state=1, noise=0.5) # 总结数据集 print(X.shape, y.shape) |
运行示例创建了数据集,并总结了数据集的输入和输出元素的形状,以供建模,确认了所选的配置。
1 |
(1000, 10) (1000, 2) |
接下来,让我们直接进行建模。
原生多输出回归算法
一些回归机器学习算法直接支持多输出。
这包括scikit-learn库中实现的大多数流行的机器学习算法,例如
- LinearRegression(及其相关算法)
- KNeighborsRegressor
- DecisionTreeRegressor
- RandomForestRegressor(及其相关算法)
让我们看几个具体示例。
线性回归用于多输出回归
以下示例在多输出回归数据集上拟合线性回归模型,然后使用拟合模型进行单次预测。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
# 线性回归用于多输出回归 from sklearn.datasets import make_regression from sklearn.linear_model import LinearRegression # 创建数据集 X, y = make_regression(n_samples=1000, n_features=10, n_informative=5, n_targets=2, random_state=1, noise=0.5) # 定义模型 模型 = LinearRegression() # 拟合模型 model.fit(X, y) # 进行预测 row = [0.21947749, 0.32948997, 0.81560036, 0.440956, -0.0606303, -0.29257894, -0.2820059, -0.00290545, 0.96402263, 0.04992249] yhat = model.predict([row]) # 总结预测 print(yhat[0]) |
运行示例拟合模型,然后对一个输入进行预测,确认模型预测了两个必需的值。
1 |
[-11.73511093 52.78406297] |
k-最近邻用于多输出回归
以下示例在多输出回归数据集上拟合k-最近邻模型,然后使用拟合模型进行单次预测。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
# k-最近邻用于多输出回归 from sklearn.datasets import make_regression from sklearn.neighbors import KNeighborsRegressor # 创建数据集 X, y = make_regression(n_samples=1000, n_features=10, n_informative=5, n_targets=2, random_state=1, noise=0.5) # 定义模型 model = KNeighborsRegressor() # 拟合模型 model.fit(X, y) # 进行预测 row = [0.21947749, 0.32948997, 0.81560036, 0.440956, -0.0606303, -0.29257894, -0.2820059, -0.00290545, 0.96402263, 0.04992249] yhat = model.predict([row]) # 总结预测 print(yhat[0]) |
运行示例拟合模型,然后对一个输入进行预测,确认模型预测了两个必需的值。
1 |
[-11.73511093 52.78406297] |
决策树用于多输出回归
以下示例在多输出回归数据集上拟合决策树模型,然后使用拟合模型进行单次预测。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
# 决策树用于多输出回归 from sklearn.datasets import make_regression from sklearn.tree import DecisionTreeRegressor # 创建数据集 X, y = make_regression(n_samples=1000, n_features=10, n_informative=5, n_targets=2, random_state=1, noise=0.5) # 定义模型 模型 = DecisionTreeRegressor() # 拟合模型 model.fit(X, y) # 进行预测 row = [0.21947749, 0.32948997, 0.81560036, 0.440956, -0.0606303, -0.29257894, -0.2820059, -0.00290545, 0.96402263, 0.04992249] yhat = model.predict([row]) # 总结预测 print(yhat[0]) |
运行示例拟合模型,然后对一个输入进行预测,确认模型预测了两个必需的值。
1 |
[49.93137149 64.08484989] |
通过交叉验证评估多输出回归
我们可能希望使用k折交叉验证来评估多输出回归。
这可以与评估任何其他机器学习模型的方法相同。
我们将使用10折交叉验证和三次重复,在测试问题上拟合和评估一个DecisionTreeRegressor模型。我们将使用平均绝对误差(MAE)作为性能指标。
完整的示例如下所示。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
# 使用k折交叉验证评估多输出回归模型 from numpy import absolute from numpy import mean from numpy import std from sklearn.datasets import make_regression 来自 sklearn.tree 导入 DecisionTreeRegressor from sklearn.model_selection import cross_val_score from sklearn.model_selection import RepeatedKFold # 创建数据集 X, y = make_regression(n_samples=1000, n_features=10, n_informative=5, n_targets=2, random_state=1, noise=0.5) # 定义模型 模型 = DecisionTreeRegressor() # 定义评估过程 cv = RepeatedKFold(n_splits=10, n_repeats=3, random_state=1) # 评估模型并收集分数 n_scores = cross_val_score(model, X, y, scoring='neg_mean_absolute_error', cv=cv, n_jobs=-1) # 使分数变为正数 n_scores = absolute(n_scores) # 总结性能 print('MAE: %.3f (%.3f)' % (mean(n_scores), std(n_scores))) |
运行示例评估了决策树模型在测试问题上的多输出回归性能。平均绝对误差(MAE)的平均值和标准差是根据所有折叠和所有重复计算得出的。
注意:由于算法的随机性或评估程序的差异,或者数值精度的差异,您的结果可能有所不同。请考虑运行示例几次并比较平均结果。
重要的是,错误是同时针对两个输出变量报告的,而不是为每个输出变量分别报告错误分数。
1 |
MAE: 51.817 (2.863) |
包装器多输出回归算法
并非所有回归算法都支持多输出回归。
一个例子是支持向量机,尽管对于回归,它被称为支持向量回归,或SVR。
该算法不支持多输出回归问题,并将引发错误。我们可以通过下面的示例来演示这一点。
1 2 3 4 5 6 7 8 9 10 |
# 支持向量回归在多输出回归中失败(会导致错误) from sklearn.datasets import make_regression from sklearn.svm import LinearSVR # 创建数据集 X, y = make_regression(n_samples=1000, n_features=10, n_informative=5, n_targets=2, random_state=1) # 定义模型 model = LinearSVR() # 拟合模型 # (这将导致错误!) model.fit(X, y) |
运行示例将报告一个错误消息,表明该模型不支持多输出回归。
1 |
ValueError: bad input shape (1000, 2) |
一种用于将为单个值预测设计的回归模型用于多输出回归的解决方法是,将多输出回归问题划分为多个子问题。
最明显的方法是将多输出回归问题划分为多个单输出回归问题。
例如,如果一个多输出回归问题需要根据输入X预测三个值y1、y2和y3,那么这可以划分为三个单输出回归问题:
- 问题1:根据X,预测y1。
- 问题2:根据X,预测y2。
- 问题3:根据X,预测y3。
有两种主要方法可以实现此技术。
第一种方法是为要预测的每个输出值开发一个独立的回归模型。我们可以将其视为一种直接方法,因为每个目标值都被直接建模。
第二种方法是第一种方法的扩展,只是模型被组织成一个链。第一个模型的预测被用作第二个模型的输入,并且输出到输入的依赖过程沿着模型链重复。
- 直接多输出:为要预测的每个数值开发独立的模型。
- 链式多输出:开发一系列依赖模型以匹配要预测的数值数量。
让我们逐一仔细看看这些技术。
直接多输出回归
多输出回归的直接方法涉及将回归问题划分为要预测的每个目标变量的独立问题。
这假设输出彼此独立,但这可能是一个不正确的假设。尽管如此,这种方法在各种问题上都能提供出乎意料的有效预测,并且可能值得尝试,至少作为性能基准。
例如,您的问题的输出可能实际上是大部分独立,如果不是完全独立的话,这种策略可以帮助您找出。
此方法得到了MultiOutputRegressor类的支持,该类将回归模型作为参数。然后,它将为问题中的每个输出创建提供的模型的一个实例。
以下示例演示了如何首先创建一个单输出回归模型,然后使用MultiOutputRegressor类包装该回归模型并添加对多输出回归的支持。
1 2 3 4 5 |
... # 定义基本模型 model = LinearSVR() # 定义直接多输出包装器模型 wrapper = MultiOutputRegressor(model) |
我们可以用合成的多输出回归问题来演示这种策略。
以下示例演示了如何使用线性SVR和重复k折交叉验证来评估MultiOutputRegressor类,并报告所有折叠和重复的平均平均绝对误差(MAE)。
完整的示例如下所示。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
# 使用SVM模型的直接多输出回归评估示例 from numpy import mean from numpy import std from numpy import absolute from sklearn.datasets import make_regression from sklearn.model_selection import cross_val_score from sklearn.model_selection import RepeatedKFold from sklearn.multioutput import MultiOutputRegressor from sklearn.svm import LinearSVR # 定义数据集 X, y = make_regression(n_samples=1000, n_features=10, n_informative=5, n_targets=2, random_state=1, noise=0.5) # 定义基本模型 model = LinearSVR() # 定义直接多输出包装器模型 wrapper = MultiOutputRegressor(model) # 定义评估过程 cv = RepeatedKFold(n_splits=10, n_repeats=3, random_state=1) # 评估模型并收集分数 n_scores = cross_val_score(wrapper, X, y, scoring='neg_mean_absolute_error', cv=cv, n_jobs=-1) # 使分数变为正数 n_scores = absolute(n_scores) # 总结性能 print('MAE: %.3f (%.3f)' % (mean(n_scores), std(n_scores))) |
运行示例将报告直接包装器的平均值和标准差MAE。
注意:由于算法的随机性或评估程序的差异,或者数值精度的差异,您的结果可能有所不同。请考虑运行示例几次并比较平均结果。
在这种情况下,我们可以看到,通过直接多输出回归策略包装的线性SVR模型实现了约0.419的MAE。
1 |
MAE: 0.419 (0.024) |
我们还可以将直接多输出回归包装器用作最终模型,并在新数据上进行预测。
首先,模型在所有可用数据上进行拟合,然后可以调用predict()函数对新数据进行预测。
以下示例在我们的合成多输出回归数据集上演示了这一点。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
# 使用直接多输出回归模型进行预测的示例 from sklearn.datasets import make_regression from sklearn.multioutput import MultiOutputRegressor from sklearn.svm import LinearSVR # 定义数据集 X, y = make_regression(n_samples=1000, n_features=10, n_informative=5, n_targets=2, random_state=1, noise=0.5) # 定义基本模型 model = LinearSVR() # 定义直接多输出包装器模型 wrapper = MultiOutputRegressor(model) # 在整个数据集上拟合模型 wrapper.fit(X, y) # 进行单次预测 row = [0.21947749, 0.32948997, 0.81560036, 0.440956, -0.0606303, -0.29257894, -0.2820059, -0.00290545, 0.96402263, 0.04992249] yhat = wrapper.predict([row]) # 总结预测 print('Predicted: %s' % yhat[0]) |
运行示例会拟合整个数据集上的直接包装器模型,然后将其用于预测新数据行,就像我们在应用程序中使用模型时一样。
1 |
Predicted: [50.01932887 64.49432991] |
现在我们熟悉了直接多输出回归包装器的使用,让我们看看链式方法。
链式多输出回归
使用单输出回归模型进行多输出回归的另一种方法是创建模型线性序列。
序列中的第一个模型使用输入并预测一个输出;第二个模型使用输入和第一个模型的输出进行预测;第三个模型使用输入和前两个模型的输出进行预测,依此类推。
例如,如果一个多输出回归问题需要根据输入X预测三个值y1、y2和y3,那么这可以划分为三个依赖的单输出回归问题,如下所示:
- 问题1:根据X,预测y1。
- 问题2:根据X和yhat1,预测y2。
- 问题3:根据X, yhat1, and yhat2,预测y3。
这可以通过scikit-learn库中的RegressorChain类来实现。
模型的顺序可以基于数据集中的输出顺序(默认)或通过“order”参数指定。例如,order=[0,1]将首先预测第0个输出,然后是第1个输出,而order=[1,0]将首先预测最后一个输出变量,然后是我们测试问题中的第一个输出变量。
以下示例演示了如何首先创建一个单输出回归模型,然后使用RegressorChain类包装该回归模型并添加对多输出回归的支持。
1 2 3 4 5 |
... # 定义基本模型 model = LinearSVR() # 定义链式多输出包装器模型 wrapper = RegressorChain(model, order=[0,1]) |
我们可以用合成的多输出回归问题来演示这种策略。
以下示例演示了如何使用线性SVR和重复k折交叉验证来评估RegressorChain类,并报告所有折叠和重复的平均平均绝对误差(MAE)。
完整的示例如下所示。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
# 使用SVM模型的链式多输出回归评估示例 from numpy import mean from numpy import std from numpy import absolute from sklearn.datasets import make_regression from sklearn.model_selection import cross_val_score from sklearn.model_selection import RepeatedKFold from sklearn.multioutput import RegressorChain from sklearn.svm import LinearSVR # 定义数据集 X, y = make_regression(n_samples=1000, n_features=10, n_informative=5, n_targets=2, random_state=1, noise=0.5) # 定义基本模型 model = LinearSVR() # 定义链式多输出包装器模型 wrapper = RegressorChain(model) # 定义评估过程 cv = RepeatedKFold(n_splits=10, n_repeats=3, random_state=1) # 评估模型并收集分数 n_scores = cross_val_score(wrapper, X, y, scoring='neg_mean_absolute_error', cv=cv, n_jobs=-1) # 使分数变为正数 n_scores = absolute(n_scores) # 总结性能 print('MAE: %.3f (%.3f)' % (mean(n_scores), std(n_scores))) |
运行示例将报告链式包装器的平均值和标准差MAE。
请注意,在运行示例时您可能会看到ConvergenceWarning,可以安全地忽略。
注意:由于算法的随机性或评估程序的差异,或者数值精度的差异,您的结果可能有所不同。请考虑运行示例几次并比较平均结果。
在这种情况下,我们可以看到,通过链式多输出回归策略包装的线性SVR模型实现了约0.643的MAE。
1 |
MAE: 0.643 (0.313) |
我们还可以将链式多输出回归包装器用作最终模型,并在新数据上进行预测。
首先,模型在所有可用数据上进行拟合,然后可以调用predict()函数对新数据进行预测。
以下示例在我们的合成多输出回归数据集上演示了这一点。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
# 使用链式多输出回归模型进行预测的示例 from sklearn.datasets import make_regression from sklearn.multioutput import RegressorChain from sklearn.svm import LinearSVR # 定义数据集 X, y = make_regression(n_samples=1000, n_features=10, n_informative=5, n_targets=2, random_state=1, noise=0.5) # 定义基本模型 model = LinearSVR() # 定义链式多输出包装器模型 wrapper = RegressorChain(model) # 在整个数据集上拟合模型 wrapper.fit(X, y) # 进行单次预测 row = [0.21947749, 0.32948997, 0.81560036, 0.440956, -0.0606303, -0.29257894, -0.2820059, -0.00290545, 0.96402263, 0.04992249] yhat = wrapper.predict([row]) # 总结预测 print('Predicted: %s' % yhat[0]) |
运行示例会拟合整个数据集上的链式包装器模型,然后将其用于预测新数据行,就像我们在应用程序中使用模型时一样。
1 |
Predicted: [50.03206 64.73673318] |
进一步阅读
如果您想深入了解,本节提供了更多关于该主题的资源。
API
- 多类和多标签算法,API.
- sklearn.datasets.make_regression API.
- sklearn.multioutput.MultiOutputRegressor API.
- sklearn.multioutput.RegressorChain API.
总结
在本教程中,您了解了如何开发多输出回归的机器学习模型。
具体来说,你学到了:
- 机器学习中的多输出回归问题。
- 如何开发原生支持多输出回归的机器学习模型。
- 如何开发包装器模型,使不支持原生多输出的算法可以用于多输出回归。
你有什么问题吗?
在下面的评论中提出你的问题,我会尽力回答。
感谢这篇帖子。我不知道scikit-learn有那些包装器类。这非常方便。
感谢以非常清晰直接的方式展示了如何使用它们。
不客气。
非常感兴趣。
谢谢。
太棒了。谢谢
不客气!
嗨,Jason博士,
感谢这篇有意义的教程文章,对我帮助很大。
我刚刚测试并发现所有代码在sklearn 0.20中都能正常工作,所以我们不一定需要更新到0.22或更高版本。
再次感谢这篇精彩的文章,期待下一篇。
谢谢,这是个好提示!
布朗利博士,您好,
感谢您的出色工作!
我有一个问题,包装器模型(无论是使用MultiOutputRegressor还是RegressorChain)是否可以与cross_val_score函数一起使用?我测试了以下代码,发现分数是0.0,是不是有什么问题?
from numpy import absolute
from numpy import mean
from numpy import std
from sklearn.datasets import make_regression
from sklearn.multioutput import MultiOutputRegressor
from sklearn.svm import LinearSVR
from sklearn.model_selection import cross_val_score
from sklearn.model_selection import RepeatedKFold
# 创建数据集
X, y = make_regression(n_samples=1000, n_features=10, n_informative=5, n_targets=2, random_state=1)
# 定义模型
model = LinearSVR()
wrapper = MultiOutputRegressor(model)
# 评估模型
cv = RepeatedKFold(n_splits=10, n_repeats=3, random_state=1)
n_scores = cross_val_score(wrapper, X, y, scoring=’neg_mean_absolute_error’, cv=cv, n_jobs=-1, error_score=’raise’)
# 总结性能
n_scores = absolute(n_scores)
print(‘Result: %.3f (%.3f)’ % (mean(n_scores), std(n_scores)))
提前感谢您!
是的。
得分为0表示预测完美。
非常感谢这篇非常好的教学式教程。完全符合我的需求!🙂
谢谢,我很高兴听到这个!
嗨,Jason!
精彩的教程。是否可以将目标转换回归器应用于这些多输出回归模型?
提前感谢!
可能可以。您可能需要进行实验以确认它能如预期那样工作。
嗨,Jason,
非常感谢本教程。它非常适合我的需求。
我有一个关于不同Y变量之间相关性的问题。KNN或随机森林模型在预测时会自动考虑不同Y变量之间的相关性吗?如果它们这样做了,是否有关于如何实现的文档?我尝试在线查找,但一无所获。您能指导我一些资源吗?谢谢。
不客气。
不,但有些算法不受共线性输入的影响(我认为是树的集成),而有些则会(线性模型)。
感谢这篇非常有趣的教程。我有一个问题,对于一些情况,例如大约有500个输入和200个输出。这种多输出回归方式适用于这类问题吗?(事实上,我有大约20个特征和500个输入点是从scan-1和2提取的,以及200个输出点是从scan-2提取的。)
不客气。
也许可以开发一个快速原型,看看这些方法是否合适且有效?
谢谢你的回复 :), 问题是我的当前数据还没有完全准备好,我必须等待,所以我也在考虑深度学习方法,比如卷积,但我需要对此进行一些研究。你对此类问题有什么建议吗?它有点像图像处理,因为输入数据和输出数据是从扫描(图像)中提取的点。
如果输入数据是图像,那么CNN将是一个不错的探索方法。
实际上,输入数据是从图像中提取的数字。但是,由于我的样本数据数量有限(约30个样本),我无法使用CNN。我决定将一张图像转换为大约500个点/数字。您能告诉我您的看法吗?
测试一套数据准备和模型,找出最适合您数据集的方法。
这很棒。但我有一个关于这些指标的问题。根据您的测试,您认为哪一个提供了最佳预测?
这取决于您的数据集。
您必须使用对照实验来找出最适合您项目的方法。
为什么不直接使用具有输出层多个神经元的神经网络,或者构建一个多目标决策树,让模型自己找出模式,而不是我们(模型开发者)必须决定输出是否相关/有序?如果输出有序有很强的理由,那么RegressorChain可能是一个不错的选择。
PS:我相信根据这篇文章,sklearn的决策树默认情况下可以适应这种情况 https://stackoverflow.com/questions/46062774/does-scikit-learns-decisiontreeregressor-do-true-multi-output-regression
您可以使用神经网络,但我们无法知道哪种模型最适合给定的数据集,因此我们必须测试许多不同的方法并选择最简单且表现良好的模型。
Jason,你的教程简直太棒了。我喜欢它们!
恭喜你取得如此出色的成绩。
谢谢!
似乎包装器方法在某些集成模型上不起作用,我尝试过这个
model = GradientBoostingRegressor(ExtraTreesRegressor())
wrapper = MultiOutputRegressor(model)
wrapper.fit(x,y)
它显示“TypeError: unsupported format string passed to ExtraTreesRegressor.__format__”
但它适用于AdaBoostRegressor。
总之,这是一个很好的教程,它为我的毕业设计提供了许多想法,谢谢Jason!
不客气。
有意思。
我认为树的集成模型直接支持多输出回归——例如,不需要包装器。
但是,如果随机森林直接执行多输出,则无法考虑多个Y输出之间的相关性(例如y1和y2)。为了考虑y1和y2之间的相关性,我是否可以将随机森林引入链式回归?
非常感谢!!我一直在寻找这样的东西,并且除了你提到的四种方法之外,一直找不到多输出预测的方法,现在我找到了。
不客气!
谢谢你
另外我想问一个问题
我的表格中有坐标(按时间序列)
例如
a,b,c->d
b,c,d->e
等等
其中每个点都是[纬度, 经度] 的形式
这就是我想使用多重输出回归的地方
我想要计算误差,您建议哪种误差度量最好?
我想使用MAPE,但它的形式是 diff/actual… 其中actual的形式是([纬度, 经度])
所以我不能用列表来除它,它需要一个单一的值。有什么建议吗?
不客气。
我建议您选择最能体现您和项目相关方项目目标的指标。此外,也许可以查阅文献,看看其他人如何在相同类型的问题上进行研究。
如果您不确定,MAE 和 RMSE 是一个很好的起点。
非常有帮助!
使用链式模型(通过包装器类)时,我们可以使用单独的模型,然后将它们全部包装起来进行拟合吗?
您具体是指什么?也许您可以详细说明一下。
感谢这个教程,我结合了电子书一起学习。
我可以问一下吗?我正在处理一个多输入/多输出的问题,有3组输入(每组有7个不同的变量,有>10000个值)。我有一组输出(8个变量)对应于组合的3个输入集。
在过程开始时,如何最好地导入/组织这些数据(向量/数组),以便于脚本使用?
总的来说,sklearn 通常期望输入是行和列的向量。因此,以这种形式处理数据可能会更容易。
非常好的帖子。它真的帮了我很多。我有两个问题
对于scikit-learn中的多输出线性回归,当调用fit(X, y)时,它实际上是为每个输出拟合一个单独的模型。我说得对吗?
第二个问题是,我正在使用核脊线性回归(RBF核)。我使用交叉验证来选择2个超参数- alpha:L2正则化的参数,以及gamma:RBF核的参数。当我调用
kr = GridSearchCV(KernelRidge(kernel=’rbf’, gamma=0.1),
param_grid={“alpha”: np.logspace(-2, 0, 10),
“gamma”: np.logspace(-2, 0, 10)},
scoring=’neg_mean_squared_error’)
它为每个输出拟合单独的模型,但这些单独的模型在每次CV参数搜索中共享相同的“alpha”和“gamma”吗?
谢谢!
是的,MultiOutputRegressor 为每个目标拟合一个单独的模型,如教程中所述。
正确,它们都会使用相同的超参数。如果这不是您想要的,您可以手动拟合单独的模型。
谢谢你的回复。另外我发现scikit-learn中的高斯过程回归模型——GaussianProcessRegressor——支持多输出。这个模型实际上是将每个输出维度作为一个高斯过程回归问题来建模吗?
也许可以查看该模型的文档。
很棒的教程。谢谢。我是一个新手,它帮助了我很多。关于你对Jack Hue的回答,它为每个输出变量拟合一个单独的模型,这意味着它没有考虑到输出变量之间的任何关系,对吗?也许这并不重要。
我的另一个问题是,如何为测试预测变量的数据框获取拟合值?你给出的所有示例都是使用单个1D列表作为行。
谢谢!!
模型将为每个输入样本生成一个预测(向量)。
您可以向模型提供一个或多个样本来进行预测。
感谢如此有用的教程。我将使用GridSearchCV来改进结果,但遇到了错误
from sklearn.model_selection import GridSearchCV
modelchain4grid = LinearSVR(max_iter=10000)
wrapper4grid = RegressorChain(modelchain4grid)
tuned_parameters = [{‘C’: [1,3,5,7,9,11,13,15,17,19,21]}]
grid = GridSearchCV(wrapper4grid, tuned_parameters,scoring = ‘neg_mean_squared_error’)
grid_result = grid.fit(X_train, Y_train)
print(grid_result)
我收到此错误
ValueError: Invalid parameter C for estimator RegressorChain(base_estimator=LinearSVR(
您能告诉我我的问题出在哪里吗?
提前感谢
我相信您需要将C参数指定为回归链模型的子参数。
我不知道确切的语法,可能是 RegressorChain__C,但也许可以查阅scikit-learn关于网格搜索复合模型的文档。
谢谢。
那就是“base_estimator__C”,然后我使用了以下代码
wrapper4grid = RegressorChain(modelchain4grid)
print(wrapper4grid.get_params())
svr = GridSearchCV(wrapper4grid, cv=5, param_grid={“base_estimator__C”: [1e0, 1e1, 1e2, 1e3]}, scoring=’accuracy’)
grid_result = svr.fit(X_train, Y_train)
但它不支持多输出,并给出了以下错误
continuous-multioutput is not supported
您能告诉我是否有好的方法来调整多输出回归的参数吗?
提前感谢
只是对scoring(scoring = ‘neg_mean_squared_error’)的一个更正,已经修复了。
多输入-多输出的完整工作代码是
modelchain4grid = LinearSVR(max_iter=10000)
wrapper4grid = RegressorChain(modelchain4grid)
#print(wrapper4grid.get_params())
svr = GridSearchCV(wrapper4grid, cv=5, param_grid={“base_estimator__C”: [1e0, 1e1, 1e2, 1e3]}, scoring = ‘neg_mean_squared_error’)
grid_result = svr.fit(X_train, Y_train)
a = grid_result.best_score_
b = grid_result.best_params_
c = grid_result.cv_results_[‘mean_test_score’]
d = grid_result.best_estimator_
print(a)
print(b)
print(c)
print(d)
means = grid_result.cv_results_[‘mean_test_score’]
stds = grid_result.cv_results_[‘std_test_score’]
params = grid_result.cv_results_[‘params’]
for mean, stdev, param in zip(means, stds, params)
print(“%f” % mean)
print(“%f” % stdev)
print(“%r” % param)
干得好!
您可能需要手动进行网格搜索,例如使用一些for循环。
谢谢 Jason,
我进一步研究了RegressionChain,并尝试设置一个管道来拟合和预测新数据,如下所示
model = Pipeline([(‘sc’, StandardScaler()),(‘pca’, PCA(n_components=10)),(‘SVRchain’, RegressorChain(LinearSVR(max_iter=1000)))])
model.fit(X_train, Y_train)
print(model.fit)
predictions= model.predict(X_test)
print(predictions)
但是,与不使用此Pipeline而先进行StandardScaler和PCA然后拟合模型(不使用Pipeline)相比,预测结果不同。
是我有什么遗漏的,还是我们不能为RegressorChain(LinearSVR)设置这样的Pipeline?
Pipeline本身就是一种估计器,它是否会与RegressionChain的基础估计器LinearSVR发生冲突?
提前感谢
好问题。
我建议在回归链中使用管道作为估计器。
谢谢,但我没明白,你能用代码示例展示一下吗?
你的意思是像这样吗
# 创建管道
estimators = []
estimators.append(('standardize', StandardScaler()))
estimators.append((‘pca’, PCA(n_components=10)))
estimators.append((‘LSVR’, LinearSVR(max_iter=1000)))
model = RegressorChain(Pipeline(estimators))
model.fit(X_train, Y_train)
test = model.predict(X_test)
print(test)
如果你的意思是上面提到的代码,那么它也给不出正确答案。
您能告诉我您的反馈吗?
是的,这就是我的意思,它是否按预期工作?
我希望你的意思是以下方法(我已经尝试过,并且它给出了预期的结果)
pipe4estimator = Pipeline([(‘sc’, StandardScaler()),(‘pca’, PCA(n_components=10)),(‘SCRChain’, RegressorChain(LinearSVR(max_iter=1000)))])
sc_y = StandardScaler()
y_train_std = sc_y.fit_transform(Y_train)
pipe4estimator.fit(X_train, y_train_std)
y_train_pred = sc_y.inverse_transform(pipe4estimator.predict(X_train))
y_test_pred = sc_y.inverse_transform(pipe4estimator.predict(X_test))
print(y_test_pred)
如果这就是我的意思,那么我们可以得出结论
为 RegressorChain(LinearSVR()) 设置管道,需要在训练和预测步骤之后,管道外部进行额外的 StandardScaler。对吗?
干得好!
不,管道知道如何在对训练数据进行拟合后处理输入给它的数据。
Jason,这是一篇非常棒的文章!我读过你的很多文章,欣赏你直截了当的讨论。我有一个问题。
假设我们正在尝试学习一个多输出回归模型。而且,我想为学习输出向量的一个维度增加“相对”的更重要的权重。
你对此情况有什么建议吗?据我所知,我们可以尝试在计算损失时为该维度增加更多权重。但我需要添加另一个超参数来控制该维度的权重。
你还有其他方法可以考虑吗?
嗯,你可以设计一个模型,其中损失是跨输出向量计算的,并且对一个输出的惩罚比其他输出更大。在这种情况下,用神经网络可能会更容易。
或者训练单独的模型,并为每个模型使用不同的损失函数,并为更重要的那个施加重罚。
感谢这篇文章。
我有一个关于 Condensed Nearest Neighbor Method 中属性的问题。sample_indices 是被过滤掉的索引吗?还是应该保留的索引?
本教程不涵盖CNN,您是指算法的通用性还是特定的实现?
例如,这可能有助于
https://imbalanced-learn.readthedocs.io/en/stable/generated/imblearn.under_sampling.CondensedNearestNeighbour.html
你好,Jason。
是否可以在RegressorChain中进行变量选择,并查看每个步骤的重要变量?例如使用Lasso?
也许,您可能需要进行实验。
Jason 又来帮忙了!谢谢。
不客气,Paul。
你好…我想知道是否也可以使用LSTM模型来预测多输出?
是的,博客上有很多例子,也许可以从这里开始
https://machinelearning.org.cn/how-to-develop-lstm-models-for-time-series-forecasting/
谢谢 Jason,非常清晰地解释了多输出多输入回归。我有一个后续问题。我该如何在一个多输入多输出模型中找出系数?我这样问是因为我有几个数据集是相似的,但来源年份不同。我想看看系数是如何随着年份变化的。
不客气!
如果您使用线性模型,您可以直接通过“coef_”属性访问模型的系数,更多细节请参见
https://scikit-learn.cn/stable/modules/generated/sklearn.linear_model.LinearRegression.html
再次感谢 Jason。我从之前的评论中还了解到,多输出回归实际上只是一系列独立的线性回归。这是否意味着,对于3个输出和3个输入,模型就是
Y1= w1.x1 + w2.x2 + w3.x3 + intercept1
Y2= w4.x1 + w5.x2 + w6.x3 + intercept2
Y3= w7.x1 + w8.x2 + w9.x3 + intercept3
…其中 w1-w9 是我们可以从 coef_ 中打印出来的系数。
而 r2 是这3个方程的r2的平均值?
是的,差不多是这样。
感谢您的教程和您的努力。
我有一个疑问,预测是否取决于样本数量?并且是否需要标准化来避免这种情况?
预测取决于数据集的所有方面,包括其准备和模型配置。
标准化对于某些算法和数据集是必需的。也许可以尝试一下,看看它是否能提高模型性能。
有用的例子,谢谢。您是否有自定义损失函数的示例,除了单独的rmse或r2之外,还可以惩罚结果y的总和?例如,我有三个商店的销售额和一些输入。但是,我知道他们销售的总和,并且也可以将这个数字作为输入。如何确保结果的3个销售预测总和是我认为应该有的数字?这很不寻常,因为我知道结果的总和,但我有兴趣预测对总和的贡献。希望这有些道理,您有什么建议吗?谢谢!
我没有您所描述的损失函数的例子,但本教程中自定义 RMSE 指标的示例可以满足您的需求。
https://machinelearning.org.cn/custom-metrics-deep-learning-keras-python/
感谢您的指点。您可以在 sklearn.multioutput 中使用 Keras 后端吗?我不明白这在这里是如何工作的。
另外,有没有办法从包装器中使用的 XGB 模型中提取特征重要性?换句话说,我能否获得 N 个模型最重要的特征?我还没有弄清楚如何访问,甚至这些信息是否真的被保留了。
在我发帖后不久就弄清楚了如何访问特征重要性
wrapper.estimators_[n].feature_importances_
如果对其他人有用的话。n 是您感兴趣的模型索引。
我仍然不明白 keras.backend 将如何与此交互。或者使用后端数学不适用于此示例?
太棒了!
可能可以,但没必要,因为模型只是用不同的方式做同样的事情。
是的,我认为您可以从拟合的 XGB 模型中检索特征重要性。我建议您查阅 API 以了解对象上属性的名称。
感谢清晰的示例。
我们可以在包装器函数中将不同的回归器或分类器按顺序放置吗?例如,首先使用线性回归预测因变量,然后使用岭回归预测下一个?
wrapper = RegressorChain(Linearregresson(), Ridgerregression(), order=[1,0])
不可以。请参阅此处的 API 文档
https://scikit-learn.cn/stable/modules/generated/sklearn.multioutput.RegressorChain.html
非常感谢分享。我一直在为我的 MIMO 问题寻找解决方案。很高兴我找到了。
不客气!
嗨,
在要涵盖的主题中提到了“用于多输出回归的随机森林”,但我在文章中没有看到。
如果我忽略了什么,请原谅我……我是一个正在寻找这个的新手……
此致,
Jyo
抱歉,我一定删除了那个例子。
就在这里
嗨,Jason,
我已经在我数据上运行了所有模型。
我有一个输入和多个目标变量。我已经将所有变量归一化为 0 到 1 之间的值。
其中一个目标变量只有 4 个值。我的意思是它只能有这四个值中的任何一个。
但是当我运行模型时,目标变量有很多值……所以当我进行重归一化时,我没有看到该变量的整数值。
这种行为是预期的吗?
请帮忙。
也许吧。我无法理解您的问题,抱歉。
Jason,
让我以您的波士顿房价数据为例。
其中变量 RAD 的值从 1 到 8 以及 24。它们只有这 9 个值。但是当我运行多重回归时,假设 RAD 是目标变量之一……结果的值是否可能不是这些数字(1:8 和 24?)
当我将整个数据集归一化到 0 到 1 的范围并运行模型,然后对预测进行缩放回原值时,我看到一个变量有多个值,而它实际上应该只有 4 个值。
所以我无法理解我哪里错了。请帮助……
您可以对预测值进行反向转换,并四舍五入到所需的精度。
嗨,Jason,
为了更清楚一点,我有多个目标变量,其中一些是分类变量,一些是连续变量。
所以如果我尝试上述任何一种回归技术,具有分类结构的那些目标变量也会得到浮点值……我应该通过四舍五入将预测值变成整数吗?
也许可以为每个变量尝试一个模型?
也许可以尝试对输出进行后处理?
也许可以尝试一个具有每个输出单独损失的多输出神经网络模型?
杰森,
我被要求只在 ML 上做。您说的后处理输出是什么意思……
例如,对模型的输出进行缩放、四舍五入等,并根据您的应用进行解释。
在使用任何多目标回归器之前,我们是否应该对整个数据集进行归一化?对于单目标,通常只归一化 X 似乎更常见。
不,在训练数据集上拟合转换器,然后将其应用于训练集和测试集。
这是为了避免数据泄露。
https://machinelearning.org.cn/data-preparation-without-data-leakage/
感谢您的澄清。我正在阅读您的另一篇文章:https://machinelearning.org.cn/feature-selection-for-regression-data/
特征选择不适用于多个目标,有没有办法对 Y 进行相同操作,其中 Y 的形状为 (n, 2)?
谢谢你
也许可以分别对每个目标进行操作。
嗨,Jason,
我的变量是标签编码格式(不是字符串,而是数值本身),我无法进一步进行独热编码,因为这会使我的列膨胀。
我进行了归一化……所以所有数据都在 0-1 范围内。
运行了模型。
现在要解释输出,我得到分类变量上的浮点数,这是我不能接受的,所以我试图得到整数。
我是否可以在数字小于 0.5 时应用天花板函数,在大于 0.5 时应用地板函数?
这会是正确的方法吗?
您可以使用最初用来缩放变量的相同对象来反向缩放目标,例如调用 inverse_transform()。
但这不能保证我的预测值是整数,对吧?
这会是一致的,然后您可以对结果进行四舍五入。
另外,我该如何决定是为每个变量使用一个模型,还是在单个模型中为所有变量使用?
选择能为您的选定指标/测试框架带来最佳性能的方法。
Jason,你真是个天才!!!!我试图为一个类似的问题编写代码,但卡住了。然后这篇文章就出现了!!我强烈建议您将这篇文章与时间序列预测文章联系起来,因为它与多步预测(当然需要适当的修改)问题有很大的相似之处。
不,只是一个普通人。
谢谢。是的,您可以将其用于多步预测,例如此处列出的“直接”方法。
https://machinelearning.org.cn/multi-step-time-series-forecasting/
嗨,Jason,
您提到的所有固有的多输出回归算法(LinearRegression、KNeighborsRegressor 等)是否都考虑了输出之间的依赖关系?
提前非常感谢。
此致
约翰
不,我不认为如此。
有可能这样做吗?
嗨,Jason,
我已经有了现有数据,并且不想使用 make regression。但是使用我的数据集,我无法使用您的其余函数。我该如何做到这一点?
抱歉,我不明白您的问题——或许您能重新表述一下?
我认为您应该将数据转换为数组格式。
嗨,Jason,
问题有点长,抱歉,但有点困惑……
如果我尝试使用 RegressorChain 来预测 24 个未来值(每小时数据,或提前一天预测)
order
参数是否很重要?例如,如果我想要 24 个未来值,我是否总是需要使用:
order
中的 0 到 23?chain_regr = RegressorChain(model, order=[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23])
或者我应该去尝试一下?
对于 `series_to_supervised` 函数使用多少前导和滞后变量我也有些困惑,但我认为您总是教我们要不断尝试以检查结果……
听起来是一个很棒的项目!
可能保持线性顺序,但需要尝试确认。
输入数量也是如此,尝试不同的输入序列长度以发现最有效的方法。
嗨,Jason,
我仍然无法理解的另一件事是带有多个 X 变量的训练测试分割。所以如果我预测 24 个样本(提前一天预测),就像我之前说的那样。我的目标变量(y)和解释变量会是什么?例如,从 `series_to_supervised` 函数返回的数据如下所示
train = series_to_supervised(data,11,14)
var1(t-14) var1(t-13) var1(t-12) … var1(t+8) var1(t+9) var1(t+10)
0 NaN NaN NaN … -0.524479 -0.618750 -0.707683
1 NaN NaN NaN … -0.618750 -0.707683 -0.806900
2 NaN NaN NaN … -0.707683 -0.806900 -0.873959
3 NaN NaN NaN … -0.806900 -0.873959 -0.899870
4 NaN NaN NaN … -0.873959 -0.899870 -1.032032
.. … … … … … …
827 -1.483986 -1.532290 -1.456250 … NaN NaN NaN
828 -1.532290 -1.456250 -1.226042 … NaN NaN NaN
829 -1.456250 -1.226042 -1.200911 … NaN NaN NaN
830 -1.226042 -1.200911 -1.441015 … NaN NaN NaN
831 -1.200911 -1.441015 2.416797 … NaN NaN NaN
.. … … … … … …
827 0.524870 0.208073 -0.200912 … NaN NaN NaN
828 0.208073 -0.200912 0.626172 … NaN NaN NaN
829 -0.200912 0.626172 0.591797 … NaN NaN NaN
830 0.626172 0.591797 0.616145 … NaN NaN NaN
831 0.591797 0.616145 0.108594 … NaN NaN NaN
我的目标 `y` 总是 `var1(t)`,解释变量是所有其他变量吗?例如
trainX = np.array(train.drop(['var1(t)'],1))
trainy = np.array(train['var1(t)'])
这样我就可以在调用 `series_to_supervised` 时测试前导/滞后变量的不同变化。
测试集的前几次预测可能需要一些训练数据。
这可能有帮助
https://machinelearning.org.cn/time-series-forecasting-supervised-learning/
嗨,Jason,
我的数据包括混凝土搅拌机的转速、搅拌次数、卸料次数、重量值。该过程是混合(正循环)和卸料(负循环)的组合。我想预测每次卸料过程后混凝土的重量减少了多少。我正在考虑使用多元线性回归。
但问题是,我如何预测每次卸料过程中的减重量?这是否可能通过多元线性回归模型?我对回归问题是新手。我是否需要在预测之前使用一些数学公式?
这个框架可以帮助您构建预测问题。
https://machinelearning.org.cn/how-to-define-your-machine-learning-problem/
然后遵循此过程。
https://machinelearning.org.cn/start-here/#process
嗨,Jason,
我的数据集是这样的。这是一个示例数据集。
No Drumspeed Rot.discharging Rot.mixing Weight Predicted_weight
1 12 10 6170 29000 28765
2 8 20 6270 27000 27320
3 4 25 0 25000 24569
4 10 30 6370 30000 29890
5 7 35 6378 28500 28120
6 5 40 0 26000 26789
7 6 28 6235 28500 28435
8 7 36 6298 27564 27111
9 10 43 6300 26560 26780
10 12 47 0 24000 24361
3,6,10 是卸料过程,其余是混合过程。我想只在卸料过程(3,6,10)中预测重量值。
问题是我只想预测卸料过程中的重量值。机器学习多元回归可以做到这一点吗?因为它只预测连续值。
也许可以尝试原型化几种不同的模型,看看是否能实现您期望的结果。
嗨,Jason,
您知道 RegressorChain 还支持哪些其他算法吗?我按照您的示例使用了 LinearSVR,但 MAE:991.290 (128.681) 是非常高的值。我应该更改评分器还是算法来适应我的数据?
LSVR = LinearSVR()
reg_model = RegressorChain(LSVR, order=[0,1])
reg_model.fit(X_train, y_train)
cv = RepeatedKFold(n_splits=10, n_repeats=3, random_state=42)
cv_r2_scores_lsvr = cross_val_score(estimator =reg_model, X= X_train, y= y_train,scoring=’neg_mean_absolute_error’, cv=cv)
abs_cv_r2_scores_lsvr = absolute(cv_r2_scores_lsvr)
print(‘MAE: %.3f (%.3f)’ % (mean(abs_cv_r2_scores_lsvr), std(abs_cv_r2_scores_lsvr)))
另外,
您认为 GridSearchCV 可以用于 RegressorChain 吗?我像您在下面看到的那样在我的数据上使用了它,但不确定这对于 RegressorChain 方法是否合乎逻辑。
#模型调优
svr_params = {‘base_estimator__tol’ : [000.1, 00.1, 0.1],
‘base_estimator__max_iter’: [1000,2000,3000]
}
SVR = LinearSVR()
svr_model = RegressorChain(SVR, order=[0,1])
cv = RepeatedKFold(n_splits=10, n_repeats=3, random_state=42)
svr_cv_model = GridSearchCV(svr_model,
svr_params,
cv = cv,
n_jobs = -1)
svr_cv_model.fit(X_train, y_train)
print(“最佳参数是:” + str(svr_cv_model.best_params_))
谢谢您的辛勤工作,它对我帮助很大。如果我能在 Kaggle 上发表我的作品,我想将其作为参考。希望您不介意 🙂
也许可以尝试多种算法,看看哪种效果最好。
我不确定是否可以将网格搜索与回归链结合使用——试试看。
如果您重新使用我的代码,请清楚地引用并链接到来源,详细信息请参见此处。
https://machinelearning.org.cn/faq/single-faq/can-i-use-your-code-in-my-own-project
我们为此开发了一个 Python 包。
https://github.com/DSARG/amorf
它结合了几种不同的方法,可以帮助您开始进行多输出回归分析。
感谢分享。
你好 Jason,感谢您的发帖。
我有一个关于模型 MAE 的问题。
固有输出回归算法方法上的 MAE 为 51.817 (2.863),而直接输出回归方法的 MAE 为 0.419 (0.024)。
您提到“错误是跨两个输出变量报告的,而不是为每个输出变量单独的错误得分”。我的理解是,它是 MAE 在 y1 上的总和加上 MAE 在 y2 上的总和。对吗?
我的问题是:0.419 的 MAE 意味着什么?与 51.817 相比,它非常小。
谢谢。
不,我认为 MAE 是跨变量和样本平均的。
MAE 的单位将与目标变量的单位相同。
您在比较不同的东西。“51.817”是一个特定的预测值,“0.419”是一个 MAE。
你好,Jason。
感谢您的有用教程。
使用 cross_val_score 函数是否可以获得每个输出变量的独立误差?
在这种情况下,您可能会从 error 函数获得向量输出。但 cross_val_score 期望一个单一的标量(请参阅 https://scikit-learn.cn/stable/modules/generated/sklearn.model_selection.cross_val_score.html 中 scoring 参数的说明)。不过,您可以编写自己的函数来以向量形式记录误差。
MAE: 51.817 (2.863) 是我在您文章的“使用交叉验证评估多输出回归”段落中读到的。
你说得对,是的,决策树在这个问题上的表现很差。
你好,Jason,一如既往的好帖子!
考虑以下任务。
您有一个数据框,其中每个条目都是某种生物标志物,它与疗法的联系以及其他一些数据(取自研究论文的结果),任务是推断哪些因素影响数据库的疗法构成,即基于表格中的其他数据,它包含多少种疗法。您会认为这是一个多输出回归问题吗(我曾考虑过泊松回归的 glm)?一方面,它确实看起来像一个多输出回归问题,因为我们有多个数值响应变量,但另一方面,它看起来应该单独处理所有疗法……
谢谢。
或许可以为您的数据原型化一些代码,将其建模为多输出回归,然后看看是否合理。
关于输入和目标的问题:输入和目标可以相同吗?这会导致任何问题吗?
例如,如果我们处理多个站点,每个站点都有自己的值,而我们想要预测所有站点的值。
假设我们有 3 个站点,并且想要预测 3 个目标值,每个站点一个。我们能使输入和目标数据相同吗?
是的。
或许可以用一个小原型来尝试一下。
您好,Drownlee 博士。
我有一个问题:如果两个输出有点相关,这会引起问题吗?
谢谢!
这取决于。我不认为如此。或许可以尝试一下。
你好,
非常感谢您的文章以及更多内容,它在我的 ML 项目中给了我很大的帮助。
尽管如此,我在这两种 SVM 使用方法中都遇到了这个错误。
C:\Users\Amaury\AppData\Roaming\Python\Python38\site-packages\sklearn\svm\_base.py:985: ConvergenceWarning: Liblinear failed to converge, increase the number of iterations.
warnings.warn(“Liblinear failed to converge, increase ”
C:\Users\Amaury\AppData\Roaming\Python\Python38\site-packages\sklearn\svm\_base.py:985: ConvergenceWarning: Liblinear failed to converge, increase the number of iterations.
warnings.warn(“Liblinear failed to converge, increase ”
而且结果非常糟糕,并且每次执行都非常不同,您有什么答案吗?
不客气。
这些看起来是警告,您可以忽略它们。
不过,也许可以尝试将 SVM 换成其他东西?或许先对数据进行缩放?或许更改 SVM 使用的求解器?
使用线性回归和线性 SVM 进行多输出回归时,我的标准差和均值都为零意味着什么?我的模型拟合得好吗,还是我必须更改算法?我有一个巨大的 Excel 数据集,包含 10 个输出和 80 个输入。非常感谢您为使机器学习对每个人都可用和开源所做的努力。
如果均值和标准差都为零,则该字段对所有行都具有单个值——在这种情况下,该变量没有数据,可以从数据集中删除。
一如既往的精彩文章。
您是否写过类似的关于(多输出回归)R 语言的文章?
谢谢!
目前还没有,抱歉。
嗨,Jason,
这非常有帮助!非常全面,解释也很到位。
有没有办法也能为我们正在预测的多个值获取预测区间?您能在这方面提供一些帮助吗?
谢谢!
一个简单的方法是使用模型集成,用每个模型进行预测,并使用每个输出的预测分布来确定区间(百分位数或均值+标准差)。
谢谢,这很有帮助!🙂
不客气。
非常感谢您的教程 Jason,它非常有用!
谢谢!很高兴听到您这么说!
非常感谢您的教程,我有一个问题。Scikit-Learn 中实现的线性回归、KNN、决策树是使用直接多输出还是链式多输出?
直接矢量输出。
你好,
感谢您的解释。线性回归、k-NN、决策树和随机森林是否考虑了目标之间的依赖关系?还是它们只是单独为每个目标构建模型?
理想情况下,是的,但具体情况可能因算法或实现而异。
嗨,Jason,
感谢您为社区带来如此出色的教程。
我想了解一下内置 MTR 方法(kNN、决策树、RF)的算法操作。使用 MultiOutputRegressor 包装器的使用方法是可以理解的,它使用基础估计器为每个目标独立创建模型,但内置算法方法呢,您能解释一下吗?
祝好,
不客气。
当然,但每种内置算法的操作都不同。
嗨,Jason,
您在此处使用 MAE 来评估预测,是否需要其他参数来评估多输出回归?
我的意思是,r-square 是否可以作为预测参数?或者是否有可能获得多输出回归的 r-square。
谢谢。赞赏您的工作。
是的,有很多。您必须选择最能反映您项目目标的指标。
你好,
感谢这篇很棒的教程。
谢谢!
嗨,Jason,
MAE 值是否有任何可接受的限制?
我的意思是,如何才能确定 MAE 的可接受限制?
谢谢,
Ashiq
是的,下限是零(完美),上限是任何朴素模型预测的误差,更多信息请看这里
https://machinelearning.org.cn/faq/single-faq/how-to-know-if-a-model-has-good-performance
嗨,Jason,
感谢分享您的想法。我假设是否存在普遍遵循的理想上限?如果有,请分享您的看法。我的意思是,MAE 的哪个值是可以接受的。
Ashiq
不,只有相对上限。
如果我决定使用 gbmregressor,我该如何进行参数调优,以选择最佳参数?谢谢。
您可以使用网格搜索或随机搜索来调优超参数。
博客上有许多关于超参数调优的示例,请使用搜索框。
谢谢,但是当我编写 gridsearch 时,并使用 y 作为目标(如果 y 包含多个元素),我就会收到错误,因为 gbm 只能处理一个输出。您是如何解决这个问题的?您有没有在哪里举例说明,对于多输出,您对 gbm 进行了 gridsearch 参数调优?谢谢。
您可能需要手动进行网格搜索,例如使用 for 循环遍历配置。
嗨,Jason,
您知道 RegressorChain 能否与包含 ColumnTransformer 的管道一起使用吗?
我在这里发布了一个问题:https://stackoverflow.com/questions/68430993/sklearn-using-regressorchain-with-columntransformer-in-pipelines 但我怀疑这可能不太可能,希望能得到您的见解。
祝您一切顺利,并感谢您提供一个很棒的网站/内容!
我猜是可以的,但也许可以先做一个原型示例看看是否可行。
嗨,Jason!这篇文章改变了我的世界,所以谢谢你!我读了您所有关于集成学习的文章,那些对我来说并不完全适用,因为我不想将我的输出分成更小的包来训练不同的模型类型,但我实际上有多个不同的输出,所以这很棒!
由于直接多输出回归不考虑目标变量之间的依赖关系,而链式多输出回归只考虑目标变量之间的有序/顺序依赖关系,那么有没有办法考虑(非有序/顺序的)依赖关系?
例如,我能否使用支持向量回归为每个目标变量创建一个单一模型,然后以某种方式执行最终的模型调整,甚至在单个模型上训练一个最终模型来处理目标之间的任何依赖关系?
不客气。
是的,输出直接向量的神经网络。
谢谢您的及时回复!
为了说清楚,输出直接向量的神经网络将接收我的输入,对每个输出执行支持向量回归(因此我的第一个隐藏层中的神经元数量与我的不同输出数量相同),然后我的第二个隐藏层执行另一个支持向量回归,其中一些(我不确定)神经元数量用于处理我的输出之间的依赖关系,然后作为直接向量馈入我的输出层。
然后,我将对整个神经网络进行参数优化。
我的理解正确吗?
抱歉,我不知道如何将 SVR 与神经网络结合。
你好,
我是人工智能和其他相关领域的初学者。我有一个简单的问题。多输出回归和人工神经网络之间有什么区别?我希望我没有问一个愚蠢的问题。
神经网络只是实现回归的一种方式。它还可以做更多回归的事情。换句话说,它们是不同的事物,但有一些重叠。
所以,如果我想预测几个值,比如从大型 GPS 位置数据集中预测 GPS 位置(纬度、经度),我认为多输出回归模型比具有 1 个或多个隐藏层的 ANN 更好。您怎么看?
确实,ANN 也可以是多输出回归模型。
非常感谢您的出色工作。我有一个问题:我是否可以对多输出分类问题执行“直接多输出”和“链式多输出”?您对多输出分类问题有什么建议吗?
您认为这篇教程对您有用吗?https://machinelearning.org.cn/one-vs-rest-and-one-vs-one-for-multi-class-classification/
非常感谢您的回复。
但是我的意思是,我该如何处理多目标分类问题。例如,我有一个包含 5 个特征的数据集,以及两个需要分类的目标。但每个目标有 4 个类别。
感谢您的帮助
在我看来,这两个目标是相互独立的。在这种情况下,您最好构建两个独立的网络,一个用于每个目标。
非常感谢!
亲爱的 Jason,感谢您发布的精彩博文!!
给定 y 目标输出和 z 特征输入,构建模型所需的最少观测值是多少?有没有经验法则?y 乘以 z?
谢谢你
30是统计学中的魔术数字(https://www.researchgate.net/post/What_is_the_rationale_behind_the_magic_number_30_in_statistics),所以一个粗略的估计是 y 乘以 z 乘以 30。但如果能做一些预处理,例如通过特征选择减少 z,您可能不需要那么多。
亲爱的 Adrian,非常感谢。致以最诚挚的问候!
感谢您的帖子!我有一个关于多输出个体准确性的问题。我构建了 2 个多输出随机森林模型。1)预测两个输出:x 和 y 坐标,2)预测三个输出:x 和 y 坐标以及另一个不相关的变量。然而,在预测 3 个变量时,x-y 坐标的准确性比仅预测 x-y 坐标有所下降。这是预料之中的吗?更多的输出是否需要构建更多的树来保持相似的准确性?任何见解都将不胜感激。
您可以选择如何评估您的模型,例如每个输出的误差得分或组合得分。
嗨,
感谢您的帖子!它非常有帮助。
我有两个问题
1. 输入的数量是否可能小于输出的数量,这是否会损害预测效果?
2. 您是否为深度学习(神经网络回归)做了类似的教程?
谢谢!
1. 不应该。原因是对于任何输入,都必须有一个对应的输出,否则您无法进行回归。但是,维度是另一个问题。您可能有 Y=f(X),其中 Y 是一个 5 维向量,而 X 是一个 3 维向量。
2. 是的,例如请看这篇:https://machinelearning.org.cn/regression-tutorial-keras-deep-learning-library-python/
嗨,Jason,
您是为每个输出变量拟合多输出回归模型,然后将其发布为多输出模型吗?
如果是,输出变量之间如何形成内在关系?
假设,对于监督学习方法,如果我需要将四个输出分配为 100(%)的总和,那么预测也必须有四个输出并且总和为 100(%),对吗?
多输出回归如何做到这一点?
谢谢!
不完全是。这取决于您如何创建模型。但在具有 softmax 输出的神经网络中,这是正确的,因为它会提供 4 个总和为 1.0 的归一化输出值。在四个 OvR 模型的集成中,每个模型都会提供一个介于 0 和 1 之间的不同概率,但没有模型能保证它们的总和恰好等于 1。
早上好 Jason,非常感谢您的博客!
我是 AI、机器学习、深度学习等领域的新手。
我的简单问题是,在所有上述模型中,您都创建了一个数据集
# 创建数据集
X, y = make_regression(n_samples=1000, n_features=10, n_informative=5, n_targets=2, random_state=1, noise=0.5)
Y 已经有一个包含 10 个命名列和 2 个目标列(全部是数值)的数据集。
您至少能告诉我如何更改此行以使用创建的数据集吗?
因为这样我就可以制作所有其他模型了。
非常感谢!!
如果您已经有了数据集,就不需要调用这个 “make_regression()” 函数了。相反,您需要读取数据。这里有一个关于如何从 CSV 文件读取数据的示例:https://machinelearning.org.cn/how-to-load-and-explore-household-electricity-usage-data/
您能帮助我将多个线性回归变量绘制在同一张图上吗?
您好 Islam…请参考以下内容
https://www.kite.com/python/answers/how-to-make-multiple-plots-on-the-same-figure-in-matplotlib-in-python#:~:text=Call%20matplotlib.,plots%20in%20the%20same%20graph.
还有一个 MultiOutputClassifier 和 MultiOutputRegressor。
如果我想结合回归和分类,该如何做到?
您好,我研究多输出回归已经两个月了,我发现链式模型总是很糟糕,即使输出是相关的。那么我们能否找到链式模型何时能起作用?
您好 Alex…请澄清您的问题,使其更具体于机器学习技术或概念,以便我能更好地帮助您。
早上好,我用 Keras(1D CNN)开发了一个多输出回归模型,有 4 个不同的输出。MSE 是为每个输出变量定义的损失函数。对我来说,如何设置与每个输出变量相关的损失权重并不十分清楚。它是否取决于输出变量的量级?设置损失权重的经验法则是什么?总的来说,选择这些值的直觉是什么?非常感谢。
感谢您的出色帖子。
关于多输出的线性回归:不同的输出变量可能具有非常不同的误差(MAE 或相对误差)。
您会建议怎么做才能改进那些误差较大的目标变量的预测?
谢谢!
很好的教程,有助于理解概念。
非常感谢
感谢您的反馈和支持 Ali!
嗨,Jason,
您有什么关于使用机器学习来优化,比如在给定条件下达到最终目标的东西吗?谢谢!
您好 Dave…您可能会对以下内容感兴趣
https://machinelearning.org.cn/optimization-for-machine-learning-crash-course/
您好,如果我只有一个 y 值(标量),我该如何预测 y?我的意思是,一个张量和一个标量(y)来获得预测的 yi,此致
您好 Shihab…您可能会对以下内容感兴趣
https://machinelearning.org.cn/how-to-make-classification-and-regression-predictions-for-deep-learning-models-in-keras/
https://machinelearning.org.cn/make-predictions-scikit-learn/
您好,我有几个问题
1. “输出是独立”的假设问题是否由第二种方法解决?(这可能很明显 - 不是一个应该问的问题,但我觉得在第二种方法的描述中没有说明,所以我问了)
2. 我尝试了用于多输出问题的 RandomForest。我观察到:单独运行的 RandomForest(不带包装器)和带包装器的结果不同。(使用 np.allclose 检查)- 我保持了相同的 random_state 以避免随机性。
其次,同样的情况在使用其他模型(如 LinearReg、DTree、KNN 等)时也会得到相同的结果。这意味着,我单独运行 LinReg 来预测多个输出,然后运行带包装器的 LinReg(任何一个,即 MultiOutputRegressor 或 Chain),但在任何一种情况下,np.allclose 都返回 true。
我还尝试使用单个目标运行 LinReg(例如,在 y1、y2、y3 中 - 我只用 y1 训练了 LinReg),并将预测与在所有目标上训练的另一个 LinReg 模型进行了比较。然后检查了第一个列(y1),它与单目标模型完全相同。
对 RandomForest 也尝试了同样的操作,但结果却不同。为什么会发生这种情况?RandomForest 是否运行方式不同?它如何保留输出关系?
—
这是一篇非常出色的文章。帮助我很大。
感谢您。很抱歉对我的问题进行了冗长的解释。
Jason 您好,我是 Aayush - 我一直在阅读这篇论文:https://oa.upm.es/40804/1/INVE_MEM_2015_204213.pdf 其中提出了多输出回归的多种解决方案。
我想根据第 4 页,主题 2.1.3 Regressor chains(这与您在本文中作为第二个选项提到的概念相同)提出一个问题。
事情是这样的:这里您提到“后续模型在输入 X1..Xn 以及
先前模型的预测 y hat
上进行训练”。这意味着新模型将以 y 作为先前模型的 y hat 的输入。但在论文中,它建议使用实际的 y 来训练新模型,而不是 y hat。所以这意味着 y hat 没有作用。
—
我尝试在 Python 中实现了这两个版本(使用 y_hat 和实际的 y),并使用了一些数据集进行测试,了解到“在新模型上使用 y_hat 进行训练的版本效果更好”。这很奇怪……有时使用实际 y 的版本效果更好,但那时的差异可以忽略不计。
我想问你——你是否有相关的研究,根据不同的测试,哪种方法效果更好?我的意思是,行业标准是什么,即是使用 y_hat 还是实际 y 进行模型训练?
此致,
Aayush Shah
你好 Jason,
想象一下,我们有 10 个特征,如果我们给模型输入 4 个特征,那么模型会给我们 6 个特征作为输出;如果我们给模型输入 5 个特征,那么模型会给我们 5 个特征作为输出,等等。这怎么做到的?请回复。
你好 Abdul……请澄清和/或重述你的问题,详细说明你试图完成什么,以便我们更好地帮助你。
你好,Jason……我认为我的问题可能被误漏了。我刚在 Abdul 的问题之前提问。如果没问题,您能否解答我几个问题?
谢谢,也很抱歉单独发一条消息来问这个,请原谅我。
你好。是否可以对 RegressorChain 或 MultioutputRegressor 创建的每个单独模型进行超参数调优?还是我必须手动进行?谢谢。
你好 Alec……我推荐使用贝叶斯优化来完成这项任务。
https://github.com/rmcantin/bayesopt
谢谢你的文章!
我一直在思考一个问题:拥有两个具有单个输出的独立模型是否有时比拥有一个具有两个输出的模型更可取?我的意思是,由于误差是针对两个输出计算的,我可以想象会出现一个输出被欠拟合而另一个输出被过拟合的情况。
拥有两个独立的模型可能会为此类问题提供更多控制。
这个推理正确吗?
你好 Erik……不客气!在某些情况下,你的建议可能是首选方法。考虑集成多样性也很有帮助。
https://machinelearning.org.cn/ensemble-diversity-for-machine-learning/
你好
我们可以将这两种方法用于时间序列预测,作为直接方法和混合方法吗?
你好 MBT……你可以考虑使用深度学习方法进行时间序列预测。
https://machinelearning.org.cn/start-here/#deep_learning_time_series
嗨
深度学习中是否存在多输出分类器?
你好,你能解释一下最后一行代码发生了什么吗?为什么我们要取 yhat[0]?以及为什么 yhat 返回一个包含多个行的 ndarray?预测不应该返回一维 ndarray 吗?
你好 Nikita……这个数组包含预测的实际值。如果你还没有这样做,请执行代码以确认 yhat[0] 中存储的值。
你好。我正在使用 Python 中的多输出回归函数来构建一个类似这样的多任务学习模型:# 创建多任务模型(以 RandomForestRegressor 为例)
multi_task_model = MultiOutputRegressor(RandomForestRegressor())。这是正确的方法还是有其他方法?
你好 Ahmad……使用 scikit-learn 的
MultiOutputRegressor
来处理多任务学习,当你需要用一个模型预测多个输出时,这确实是一个实用的方法。你提供的示例对于使用RandomForestRegressor
作为基础回归器设置多任务模型是正确的。以下是你通常如何使用它的方法:### 基本设置
你描述的设置用于创建一个模型,该模型可以独立地用每个输出的单独回归器来预测每个输出。这是一个分步指南:
1. **导入所需的库**
首先,确保你已正确导入所需的库:
python
from sklearn.ensemble import RandomForestRegressor
from sklearn.multioutput import MultiOutputRegressor
from sklearn.model_selection import train_test_split
from sklearn.metrics import mean_squared_error
2. **准备你的数据**
你需要准备好你的特征 (
X
) 和目标 (Y
)。Y
应该是一个矩阵,其中每一列代表回归的不同目标。python
X = ... # 你的特征
Y = ... # 你的目标,包含多个列
X_train, X_test, Y_train, Y_test = train_test_split(X, Y, test_size=0.2, random_state=42)
3. **创建和训练多输出模型**
如你所述,你将
RandomForestRegressor
包装在MultiOutputRegressor
中,以使用单独的模型处理每个输出特征:python
multi_task_model = MultiOutputRegressor(RandomForestRegressor(random_state=42))
multi_task_model.fit(X_train, Y_train)
4. **评估模型**
训练后,你可以使用测试集评估模型:
python
Y_pred = multi_task_model.predict(X_test)
mse = mean_squared_error(Y_test, Y_pred, multioutput='raw_values')
print("每个输出的均方误差:", mse)
### 考虑因素和替代方案
– **模型独立性**:
MultiOutputRegressor
中的每个目标都使用指定基础估计器的单独实例独立预测。这意味着任务之间没有信息共享,如果你的任务是相关的,这可能不是最优的。– **相关输出**:如果你的任务是相关的(输出变量是相关的),你可能想考虑能够显式利用这种相关性的模型。诸如链式回归(
RegressorChain
)之类的技术或在神经网络框架中构建可以学习共享表示的自定义模型可能更合适。– **模型选择**:虽然
RandomForestRegressor
由于其鲁棒性和对非线性关系的建模能力而成为强大的通用模型,但请根据你的具体数据特征考虑是否有其他模型可能更合适。例如,如果配置正确,梯度提升机(如XGBoost
或LightGBM
库中的模型)可能会提供更好的性能。– **超参数调优**:无论你选择什么模型,调优其参数对于实现最佳性能至关重要。考虑使用网格搜索(
GridSearchCV
)或随机搜索(RandomSearchCV
)等技术来找到最佳模型设置。使用
MultiOutputRegressor
是将 scikit-learn 中任何单输出模型扩展到处理多个输出的直接方法。如果你的任务具有复杂的相互依赖性,或者你需要一个利用输出之间共享信息 Thus, you may need to explore more specialized multi-task learning models or custom solutions.你好,我有一些问题。
如果随机森林直接处理多输出,则无法考虑多个 Y 输出之间的相关性(例如 y1 和 y2)。为了考虑 y1 和 y2 之间的相关性,我能否将随机森林引入链式回归?也就是说,将随机森林用作链式回归的元估计器。
同样,能否将 LightGBM 引入链式回归以考虑 y1 和 y2 之间的相关性?
你好,我有一些问题。
如果随机森林直接处理多输出,则无法考虑多个 Y 输出之间的相关性(例如 y1 和 y2)。为了考虑 y1 和 y2 之间的相关性,我能否将随机森林引入链式回归?也就是说,将随机森林用作链式回归的元估计器。
同样,能否将 LightGBM 引入链式回归以考虑 y1 和 y2 之间的相关性?
您的评论正在等待审核。
是的,**随机森林**和**LightGBM**都可以纳入**链式回归**,以考虑多个输出之间的相关性(例如 \( y_1 \) 和 \( y_2 \))。以下是解释和一些实用见解:
—
### **理解链式回归**
链式回归通过将多输出回归问题转换为一系列单输出回归问题来工作。每个输出 (\( y_1, y_2, \ldots, y_n \)) 都使用输入特征和先前输出的预测来预测。
这使得模型能够:
1. 利用输出之间的相关性(\( y_1 \) 和 \( y_2 \))。
2. 根据链中的早期输出来顺序地改进预测。
—
### **链式回归中的随机森林**
随机森林(RF)确实可以用作链式回归的元估计器。在这种情况下使用 RF 的关键优势在于它对非线性关系和噪声的鲁棒性。当集成到链式回归中时:
1. **每个 RF 模型预测一个输出变量**,同时将先前的输出视为附加特征。
2. 这有助于捕获输入变量与输出之间的关系,以及输出本身之间的依赖关系。
—
### **链式回归中的 LightGBM**
LightGBM 是链式回归的另一个绝佳选择,尤其是在处理大型数据集或高维特征时。它提供了:
1. **效率和速度**:与随机森林相比,训练时间更快。
2. **可定制性**:能够调整梯度提升的超参数以获得更好的性能。
3. **处理相关性**:与随机森林一样,LightGBM 也可以使用链中的先前输出来作为特征来建模输出依赖关系。
—
### **实现大纲**
要在 Python 中使用随机森林或 LightGBM 实现链式回归:
1. 使用 **
sklearn.multioutput.RegressorChain
** 来链接回归器。2. 将你选择的元估计器(随机森林或 LightGBM)作为基础模型传递。
3. 拟合模型并在你的多输出数据上进行评估。
以下是一个使用**随机森林**的示例:
python
from sklearn.multioutput import RegressorChain
from sklearn.ensemble import RandomForestRegressor
from sklearn.model_selection import train_test_split
from sklearn.metrics import mean_squared_error
import numpy as np
# 示例数据
X, y = np.random.rand(100, 10), np.random.rand(100, 2) # 10 个特征,2 个输出
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
# 随机森林作为基础估计器
base_model = RandomForestRegressor(n_estimators=100, random_state=42)
# 链式回归
chain_regressor = RegressorChain(base_model)
chain_regressor.fit(X_train, y_train)
# 预测
y_pred = chain_regressor.predict(X_test)
# 评估性能
mse = mean_squared_error(y_test, y_pred)
print(f"均方误差: {mse}")
对于**LightGBM**,你可以类似地使用
lightgbm
包中的LGBMRegressor
类:python
from lightgbm import LGBMRegressor
# LightGBM 作为基础估计器
base_model = LGBMRegressor()
# 链式回归
chain_regressor = RegressorChain(base_model)
chain_regressor.fit(X_train, y_train)
# 预测和评估(与上面相同)
—
### **需要注意的事项**
1. **相关性处理**:当输出相关时,链式回归效果很好。如果输出之间几乎没有相关性,其他方法(例如,独立回归器)的效果可能与此相当或更好。
2. **输出顺序**:输出链式输入的顺序会影响性能。尝试不同的顺序来找到数据集的最佳序列。
3. **性能与复杂性**:LightGBM 倾向于更好地扩展到更大的数据集,而随机森林可能在较小的数据集上表现更好,或者在需要可解释性时。
—
### **替代方法**
如果输出高度相关,你还可以考虑:
1. **多输出梯度提升**:通过直接拟合数据而不进行链接,使用 LightGBM 对多输出回归的内置支持。
2. **神经网络**:深度学习模型可以自然地处理具有共享隐藏层多输出回归。
3. **多元回归(PLS 等)**:像偏最小二乘法这样的降维技术可以捕获输出中的相互依赖性。
非常感谢你的回复,Jason。你的回答对我帮助很大。
非常感谢你的回复,James。
你好,我有一个新问题。当我想要为随机森林中的链式回归进行超参数调优时,贝叶斯优化过程是否同时基于多个因变量(例如 y1 和 y2)来计算评分标准?例如,MSE 是分别为 y1 和 y2 计算,然后取平均值来最小化 MSE 的平均值?
bayes_search = BayesSearchCV(
estimator = RandomForestRegressor(random_state=42),
search_spaces=param_grid,
scoring=’neg_mean_squared_error’,
cv=cv,
n_iter=50,
random_state=42,
verbose=3,
n_jobs=-1
)
你好,我有一个新问题。当我想要为随机森林中的链式回归进行超参数调优时(我有多个 Y 输出,例如 y1 和 y2),贝叶斯优化过程是否同时基于多个因变量(例如 y1 和 y2)来计算评分标准?例如,MSE 是分别为 y1 和 y2 计算,然后取平均值来最小化 MSE 的平均值?
bayes_search = BayesSearchCV(
estimator = RandomForestRegressor(random_state=42),
search_spaces=param_grid,
scoring=’neg_mean_squared_error’,
cv=cv,
n_iter=50,
random_state=42,
verbose=3,
n_jobs=-1
)
嗨
我想了解一件事,当使用 MultiOutputRegressor 类时,它是否考虑了输出变量之间的依赖关系(或者它们是否将它们视为独立的)?我们如何实现这一点?是否存在这样的模型?
很好的问题!
简短的回答是:
### ❌
MultiOutputRegressor
**不**考虑输出变量之间的依赖关系。它只是**为每个目标拟合一个回归器**,将每个目标视为**独立于**其他目标。
—
### 🔍
MultiOutputRegressor
如何工作?python
from sklearn.multioutput import MultiOutputRegressor
from sklearn.ensemble import RandomForestRegressor
multi_target_model = MultiOutputRegressor(RandomForestRegressor())
multi_target_model.fit(X_train, Y_train)
在这里,
Y_train
有多个列(例如,预测 [身高、体重、年龄])。该模型为
Y_train
中的每一列**分别训练一个 RandomForestRegressor**,是独立的。– 它**不建模**目标之间的任何相关性或依赖性。
– 如果
height
和weight
是相关的,模型**不会知道**。—
### ✅ 如果你想**建模输出变量之间的依赖关系**怎么办?
以下是一些方法:
—
### ✅ 1. 使用**原生支持多输出并考虑依赖关系**的模型
这些模型在内部**联合建模**所有输出变量:
– **神经网络 (MLPRegressor)**:你可以构建一个具有**多个输出**的神经网络。
– 一次前向传播即可预测所有输出。
– 权重可以共享,从而使模型能够**捕获依赖关系**。
python
from sklearn.neural_network import MLPRegressor
model = MLPRegressor()
model.fit(X_train, Y_train) # Y_train 包含多个列
或者使用自定义的 PyTorch/Keras 模型以获得更大的灵活性。
—
### ✅ 2. 使用**回归链**(
sklearn
中的RegressorChain
)这种方法通过将先前输出作为下一个模型的输入来**顺序地**建模依赖关系。
python
from sklearn.multioutput import RegressorChain
from sklearn.linear_model import LinearRegression
chain = RegressorChain(base_estimator=LinearRegression())
chain.fit(X_train, Y_train)
– 对于目标变量
[y1, y2, y3]
,它会建模:–
y1 = f1(X)
–
y2 = f2(X, y1)
–
y3 = f3(X, y1, y2)
因此,早期输出的预测会影响后续的预测。
—
### ✅ 3. 深度学习 (PyTorch / Keras)
使用神经网络,你可以设计**共享层**,然后是**多个头**,或者只是一个具有多个单元的输出层。
这种设置自然地允许建模输出之间的交互。
—
### ✅ 4. 多元回归技术
在统计学中,**多元线性回归**(不要与复线性回归混淆!)可以使用**多元正态假设**联合建模多个输出。
诸如
statsmodels
之类的包或TensorFlow Probability
之类的框架允许你定义此类模型。—
### ✅ 总结表
| 方法 | 是否考虑输出依赖关系? | 说明 |
|————————-|————————————|——-|
|
MultiOutputRegressor
| ❌ 否 | 训练单独的模型 ||
RegressorChain
| ✅ 部分 | 顺序依赖 || MLP (神经网络) | ✅ 是 | 共享层,自定义 |
| 多元回归 | ✅ 是 | 统计建模 |
—