使用GridSearch+FeatureUnion Pipeline时passthrough导致行维度不兼容
问题根源
你遇到的错误核心在于:FeatureUnion中使用"passthrough"时,它的作用是直接传递该分支的原始输入X,而非忽略这个分支。你的ngrams分支输出的是形状为(n_samples, n_features)的稀疏特征矩阵,但"passthrough"会直接返回原始的文本列表(比如GridSearch划分后的8个样本文本),这两个输出无法被hstack拼接,导致维度不兼容错误。
解决方案
以下是两种可行的解决方法:
方法一:用空特征Transformer替代"passthrough"
定义一个返回空特征矩阵的Transformer,当需要忽略lengths分支时,用它替换TextLengthExtractor,保证输出维度和ngrams分支匹配:
from sklearn.preprocessing import FunctionTransformer import numpy as np # 定义返回空特征的函数 def empty_feature(X): return np.zeros((len(X), 0)) # 返回(n_samples, 0)的空矩阵 # 包装成可用于Pipeline的Transformer empty_transformer = FunctionTransformer(empty_feature, validate=False) # 修改GridSearch参数 params = { "features__lengths": [TextLengthExtractor(), empty_transformer], "features__ngrams__vectorizer__ngram_range": [(1,3), (2,6)], }
当使用empty_transformer时,lengths分支会返回和样本数匹配的空特征矩阵,与ngrams分支的输出拼接后不会出现维度冲突。
方法二:直接调整FeatureUnion的transformer_list
通过GridSearch直接修改FeatureUnion的transformer_list参数,动态添加或移除lengths分支,这是更直接的"忽略分支"方式:
# 定义包含两种分支组合的参数列表 params = [ # 包含lengths分支的参数组合 { "features__transformer_list": [("ngrams", ngram_vectorizer), ("lengths", TextLengthExtractor())], "features__ngrams__vectorizer__ngram_range": [(1,3), (2,6)] }, # 不包含lengths分支的参数组合 { "features__transformer_list": [("ngrams", ngram_vectorizer)], "features__ngrams__vectorizer__ngram_range": [(1,3), (2,6)] } ]
这种方式直接控制FeatureUnion的分支列表,完全移除不需要的分支,从根源避免维度不匹配问题。
验证执行
修改参数后,重新运行GridSearch即可正常执行:
from sklearn.model_selection import GridSearchCV grid_search = GridSearchCV(pipe_full, params, cv=5, error_score='raise') grid_search.fit(X_train_dummy, y_train_dummy)
内容的提问来源于stack exchange,提问作者MichaelU
相关产品推荐
相关产品推荐

