有没有办法在 sklearn 管道中链接 pd.cut FunctionTransformer?
Is there a way to chain a pd.cut FunctionTransformer in a sklearn Pipeline?
我正在使用 sklearn 制作 DataFrame 预处理管道并链接各种类型的预处理步骤。
我想链接一个 SimpleImputer
转换器和一个 FunctionTransformer
应用 pd.qcut
(或 pd.cut
),但我不断收到以下错误:
ValueError: Input array must be 1 dimensional
这是我的代码:
from sklearn.base import BaseEstimator, TransformerMixin
from sklearn.pipeline import Pipeline
from sklearn.impute import SimpleImputer
from sklearn.preprocessing import FunctionTransformer
class FeatureSelector(BaseEstimator, TransformerMixin):
def __init__(self, features):
self._features = features
def fit(self, X, y=None):
return self
def transform(self, X, y=None):
return X[self._features]
fare_transformer = Pipeline([
('fare_selector', FeatureSelector(['Fare'])),
('fare_imputer', SimpleImputer(strategy='median')),
('fare_bands', FunctionTransformer(func=pd.qcut, kw_args={'q': 5}))
])
如果我简单地将 FeatureSelector
转换器和 FunctionTransformer
与 pd.qcut
链接在一起并省略 SimpleImputer
:
,也会发生同样的情况
fare_transformer = Pipeline([
('fare_selector', FeatureSelector(['Fare'])),
('fare_bands', FunctionTransformer(func=pd.qcut, kw_args={'q': 5}))
])
我广泛搜索了 Whosebug 和 google,但找不到解决此问题的方法。如有任何帮助,我们将不胜感激!
sklearn 已经有了这样的转换器,KBinsDiscretizer
(匹配pd.qcut
,使用strategy='quantile'
)。它的主要区别在于它 transform
测试数据的方式:FunctionTransformer
版本将“重新调整”分位数,而内置 KBinsDiscretizer
将保存分位数统计数据以对测试数据进行分箱。正如 @m_power 在评论中指出的那样,它们在 bin 边缘附近也不同,以及转换数据的格式。
但要具体解决错误:这意味着您的函数 qcut
仅适用于一维数组,而 FunctionTransformer
发送整个数据帧。您可以在 qcut
周围定义一个薄包装器来完成这项工作,例如
def frame_qcut(X, y=None, q=10):
return X.apply(pd.qcut, axis=0, q=q)
(假设您将获得一个数据框。)
我正在使用 sklearn 制作 DataFrame 预处理管道并链接各种类型的预处理步骤。
我想链接一个 SimpleImputer
转换器和一个 FunctionTransformer
应用 pd.qcut
(或 pd.cut
),但我不断收到以下错误:
ValueError: Input array must be 1 dimensional
这是我的代码:
from sklearn.base import BaseEstimator, TransformerMixin
from sklearn.pipeline import Pipeline
from sklearn.impute import SimpleImputer
from sklearn.preprocessing import FunctionTransformer
class FeatureSelector(BaseEstimator, TransformerMixin):
def __init__(self, features):
self._features = features
def fit(self, X, y=None):
return self
def transform(self, X, y=None):
return X[self._features]
fare_transformer = Pipeline([
('fare_selector', FeatureSelector(['Fare'])),
('fare_imputer', SimpleImputer(strategy='median')),
('fare_bands', FunctionTransformer(func=pd.qcut, kw_args={'q': 5}))
])
如果我简单地将 FeatureSelector
转换器和 FunctionTransformer
与 pd.qcut
链接在一起并省略 SimpleImputer
:
fare_transformer = Pipeline([
('fare_selector', FeatureSelector(['Fare'])),
('fare_bands', FunctionTransformer(func=pd.qcut, kw_args={'q': 5}))
])
我广泛搜索了 Whosebug 和 google,但找不到解决此问题的方法。如有任何帮助,我们将不胜感激!
sklearn 已经有了这样的转换器,KBinsDiscretizer
(匹配pd.qcut
,使用strategy='quantile'
)。它的主要区别在于它 transform
测试数据的方式:FunctionTransformer
版本将“重新调整”分位数,而内置 KBinsDiscretizer
将保存分位数统计数据以对测试数据进行分箱。正如 @m_power 在评论中指出的那样,它们在 bin 边缘附近也不同,以及转换数据的格式。
但要具体解决错误:这意味着您的函数 qcut
仅适用于一维数组,而 FunctionTransformer
发送整个数据帧。您可以在 qcut
周围定义一个薄包装器来完成这项工作,例如
def frame_qcut(X, y=None, q=10):
return X.apply(pd.qcut, axis=0, q=q)
(假设您将获得一个数据框。)