在管道中使用时带有 scikit-learn PLSRegression 的 ValueError

Posted

技术标签:

【中文标题】在管道中使用时带有 scikit-learn PLSRegression 的 ValueError【英文标题】:ValueError with scikit-learn PLSRegression when used in Pipeline 【发布时间】:2017-06-12 08:59:06 【问题描述】:

我正在尝试使用 scikit-learns PLSRegressor 类作为降维的中间步骤,但收到以下错误。

ValueError: could not broadcast input array from shape (100,2) into shape (100)

我从 scikit-learn 文档中了解到,管道中任何实现 fit 和 transform 的中间步骤都应该有效。 PLSRegression 类确实实现了这些方法。

sklearn.pipeline.Pipeline 类(步骤)

依次应用变换列表和最终估算器。 管道的中间步骤必须是“变换”,即它们必须实现拟合和变换方法。最终的估计器只需要实现fit即可。

以下是演示该行为的示例。我是做错了什么还是遗漏了一些明显的东西?

import numpy as np
import pandas as pd
from sklearn.pipeline import make_pipeline
from sklearn.linear_model import LinearRegression
from sklearn.cross_decomposition import PLSRegression

df = pd.DataFrame(np.random.randint(0,100,size=(100, 5)), columns=list('ABCDy'))

pipeline = make_pipeline(PLSRegression(n_components=2), LinearRegression())

X = df.ix[:, :-1]
y = df['y']

pipeline.fit(X, y)

这是完整的跟踪。

Traceback (most recent call last):
  File "pls.py", line 15, in <module>
    pipeline.fit(X, y)
  File "/usr/local/lib/python2.7/dist-packages/sklearn/pipeline.py", line 270, in fit
    self._final_estimator.fit(Xt, y, **fit_params)
  File "/usr/local/lib/python2.7/dist-packages/sklearn/linear_model/base.py", line 512, in fit
    y_numeric=True, multi_output=True)
  File "/usr/local/lib/python2.7/dist-packages/sklearn/utils/validation.py", line 521, in check_X_y
    ensure_min_features, warn_on_dtype, estimator)
  File "/usr/local/lib/python2.7/dist-packages/sklearn/utils/validation.py", line 382, in check_array
    array = np.array(array, dtype=dtype, order=order, copy=copy)
ValueError: could not broadcast input array from shape (100,2) into shape (100)

我理解错误,但由于这是管道的一部分,因此一旦数组进入管道,我就无法控制数组的形状。在拟合之前,我尝试了许多不同的重塑 X.values 的迭代,但到目前为止没有任何效果。

【问题讨论】:

这个模块好像在quite a bad shape. @sascha 感谢您指出这一点。甚至有人提到它在管道中不起作用。 【参考方案1】:

该错误是由于在大多数用于降维的 scikit 类中,transform 方法不将 Y 作为参数并返回转换后的 X。在 PLS 的情况下,如果未给出 Y,则返回“x_scores” , (x_scores, y_scores) 否则”(引用自文档)

为了使其与管道一起使用,您只需创建一个简单的包装器:

class PLSRegressionWrapper(PLSRegression):

    def transform(self, X):
        return super().transform(X)

    def fit_transform(self, X, Y):
        return self.fit(X,Y).transform(X)

用 Python3.6 测试

【讨论】:

以上是关于在管道中使用时带有 scikit-learn PLSRegression 的 ValueError的主要内容,如果未能解决你的问题,请参考以下文章

如何在 scikit-learn 的管道中对变换参数进行网格搜索

使用 scikit-learn 管道与手动操作时的不同分数

当最后一个估计器不是转换器时,如何使用 scikit-learn 管道进行转换?

PL/SQL 能否可靠地转换为 Pig Latin 或带有 Pig Latin 和 Hive 的 Oozie 管道

在 SciKit-Learn 中使用管道的排列重要性

为啥在 scikit-learn 中使用 make_pipeline 时出现“管道的最后一步”错误?