在sklearn转换器管道上创建一个fork,以允许数据通过

时间:2020-10-10 00:53:22

标签: scikit-learn

我有一个看起来像这样的sklearn管道

enter image description here

您会注意到features_to_vectorize左侧和右侧的重复步骤FeatureUnionfeatures_to_vectorize是对熊猫DataFrame列应用DictVectorizer的结果。然后,我想使用features_to_vectorize并将其与自身的转换连接起来。我当前的设置重复了转换,因为我不确定如何在features_to_vectorize上创建派生,可以在其中为该数据创建传递,也可以在该数据上应用转换,然后在FeatureUnion上应用转换。有什么想法如何更好地进行设置以避免重复计算?谢谢

sum_along_columns = FunctionTransformer(np.sum, kw_args={"axis": 1})
col_trans = ColumnTransformer([("features_to_vectorize", DictVectorizer(), "col")])
out = FeatureUnion(
    [
        ("pipeline", Pipeline([("d_vec", col_trans), ("sum", sum_along_columns)])),
        ("column_transformer", col_trans),
    ]
)

理想情况下应该看起来像

enter image description here

解决方案

col_trans = ColumnTransformer([("features_to_vectorize", DictVectorizer(), "col")])
ident = FunctionTransformer()

fts = FeatureUnion([("sum", SumColumns()), ("ident", ident)])
out = Pipeline([("dv", col_trans), ("sum_and_pass", fts)])

其中SumColumns是一个简单的转换np.sum(axis=1).reshape(-1,1),以符合sklearn强制执行的2d输出

1 个答案:

答案 0 :(得分:1)

ColumnTransformer可以将同一列发送到多个转换器,所以应该这样做:

sum_along_columns = FunctionTransformer(np.sum, kw_args={"axis": 1})
col_trans = ColumnTransformer([("features_to_vectorize", DictVectorizer(), "col")])

split = ColumnTransformer([
    ('sum', sum_along_columns, [0]),
    ('ident', 'passthrough', [0]),
])

out = Pipeline([
    ('vectorize', col_trans),
    ('split', split),
])

一个问题是,在管道中的“向量化”步骤之后,您有了一个数组而不是一个框架,因此我们不能依靠split中的要素名称,因此也不能依靠[0]中的要素名称。 / p>

您还可以坚持使用FeatureUnion并实现自己的简单身份转换器,例如再次使用FunctionTransformer,而不是使用ColumnTransformer的{​​{1}}。