在管道中使用时带有 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 管道进行转换?