FeatureUnion是scikit-learn 0.22前用于并行拼接多个Transformer输出的工具,但已在0.23+版本彻底移除,应改用ColumnTransformer或手动hstack/scipy.sparse.hstack。

FeatureUnion 是什么,现在还该用吗?
FeatureUnion 是 scikit-learn 0.22 之前提供的并行特征拼接工具,用于把多个 Transformer 的输出水平堆叠(hstack)成一个特征矩阵。但它在 0.22 版本已被标记为 deprecated,0.23+ 完全移除。官方明确推荐改用 ColumnTransformer 或手动组合 + numpy.hstack / scipy.sparse.hstack。
如果你维护旧代码或阅读老教程,遇到 FeatureUnion,得知道它已失效——直接运行会报 ImportError: cannot import name 'FeatureUnion' 或警告提示弃用。
替代方案:用 ColumnTransformer 拆分+合并更安全
ColumnTransformer 不仅能替代 FeatureUnion 的并行处理逻辑,还能天然支持列选择、类型区分(数值列 vs 文本列),避免手动切片出错。
- 只对部分列做变换?用
ColumnTransformer的remainder='passthrough'或remainder='drop' - 多个文本列各自 TF-IDF?每个配独立
TfidfVectorizer实例,传入不同列名列表 - 想保留原始列名?设
verbose_feature_names_out=True(v1.2+),否则输出列名会带前缀
示例:对数值列标准化 + 对文本列 TF-IDF
立即学习“Python免费学习笔记(深入)”;
图片提示词生成器?不止如此。 马甲系统 —— 把脑海中的画面,翻译成AI能理解的专业表达。 用得越多,它越懂你:首次需要多问几句确认方向,用久了几乎一说就懂。 用得越多,它越快:缓存机制让后续对话越来越省。 RAG进化:成功案例持续入库,越跑越聪明。 输入「新手指南」查看完整功能介绍
from sklearn.compose import ColumnTransformer
from sklearn.preprocessing import StandardScaler
from sklearn.feature_extraction.text import TfidfVectorizer
preprocessor = ColumnTransformer(
transformers=[
('num', StandardScaler(), ['age', 'income']),
('text', TfidfVectorizer(max_features=100), 'review')
],
remainder='drop'
)
如果必须拼接多个 Transformer 输出,怎么手动 hstack?
当你要组合的不是“按列分流”,而是多个模型/转换器都作用于同一组输入(比如同时提取 n-gram、词性统计、字符级特征),就得手动拼接。这时注意数据类型和稀疏性兼容问题:
- 全部是稠密数组?用
numpy.hstack - 含
scipy.sparse矩阵(如TfidfVectorizer输出)?必须用scipy.sparse.hstack,否则内存爆炸或报错ValueError: blocks must be 2-D - 混用稠密和稀疏?先统一转成稀疏(
scipy.sparse.csr_matrix),再拼接
示例:拼接两个 TF-IDF 结果(都是 sparse)
from sklearn.feature_extraction.text import TfidfVectorizer from scipy.sparse import hstack vec1 = TfidfVectorizer(ngram_range=(1,1)) vec2 = TfidfVectorizer(ngram_range=(2,2)) X1 = vec1.fit_transform(docs) X2 = vec2.fit_transform(docs) X_combined = hstack([X1, X2], format='csr')
常见坑:fit 和 transform 必须严格分离
并行分支里最容易忽略的是:每个 transformer 必须独立 fit,不能共用同一个实例——否则训练集信息会泄露到验证集,尤其在交叉验证中导致严重过拟合。
- 错误写法:
vec = TfidfVectorizer(); X1 = vec.fit_transform(a); X2 = vec.transform(b)—— 这里vec已 fit 过,transform(b)是合法的,但若b是验证集,就破坏了数据隔离 - 正确做法:每个分支用全新实例,或封装成 Pipeline 保证 fit-transform 链路封闭
- 用
ColumnTransformer时,它内部自动处理各分支的独立fit,不用手动管;但手拼时必须自己确保
真正麻烦的不是语法,是搞清每个 transformer 的 fit 范围是否跨了训练/验证边界——这个逻辑一旦错,模型评估结果就不可信。

















