columntransformer是并行处理不同类型列的核心工具:先按列类型分流转换,再横向堆叠结果;必须用字符串列名指定列,避免错位;tfidfvectorizer仅接受一维文本序列,数值列需预处理缺失值;输出为无列名ndarray,调试时需调用get_feature_names_out拼接各转换器特征名。

用 ColumnTransformer 分开处理再拼接
不能直接把文本列和数值列丢进同一个 StandardScaler 或 TfidfVectorizer —— 它们数据类型和处理逻辑完全不同。必须先按列类型分流,各自转换,再横向合并。核心是 ColumnTransformer,它不是“加法器”,而是“并行处理器”:对指定列应用指定转换器,最后把结果 numpy.ndarray 按列堆叠(hstack)。
常见错误是试图用 FeatureUnion(已弃用)或手动拼接 pandas.concat,这会破坏 Pipeline 的 fit_transform / transform 一致性,导致预测时出错。
-
ColumnTransformer的transformers参数是列表,每个元素为(name, transformer, columns)元组 - 列名要用原始
pandas.DataFrame的列名,不是位置索引;若用位置,写成[0, 1]或slice(0, 2),但强烈建议用字符串列表(如["age", "income"])避免错位 - 未出现在任何
columns中的列默认被丢弃(remainder="drop"),如需保留,设remainder="passthrough",但注意它不参与训练,仅原样传递
TfidfVectorizer 只能接一维文本列,别喂 DataFrame
TfidfVectorizer 接收的是可迭代的字符串序列(如 Series 或 list),不是二维 DataFrame。如果传入 df[["text_col"]](返回 DataFrame),会报错 expected 1D array, got 2D array。
正确做法是用列名字符串(如 "text_col")而非列表,让 ColumnTransformer 自动提取为 Series;或者显式用 df["text_col"].values,但前者更安全、可复用。
- 若文本列含
NaN,TfidfVectorizer默认报错,需提前用fillna("")或在 Pipeline 前清洗 - 不要在
ColumnTransformer外单独调用fit—— 它必须和数值转换器一起被整体fit,否则词汇表不一致 - 如需对多文本列(如 title + desc)联合向量化,先用
df["title"] + " " + df["desc"]合并为新列,再传入
数值列用 StandardScaler 前务必确认无缺失值
StandardScaler 对 NaN 零容忍,遇到就直接抛 ValueError: Input contains NaN。而文本列常用 fillna 处理,容易让人忽略数值列也得清理。
推荐在 ColumnTransformer 内部用 SimpleImputer 衔接,而不是在 Pipeline 外预处理 —— 否则交叉验证时会泄露测试集统计量。
- 数值列插补优先选
strategy="median"(比均值抗异常值) - 不要用
strategy="most_frequent"处理数值列,它只适用于分类变量 - 若数值列本身是整型(如计数),
StandardScaler输出会变成浮点,不影响模型,但要注意下游是否依赖 dtype
合并后特征顺序固定,但列名丢失——调试时靠 get_feature_names_out
ColumnTransformer 输出是 numpy.ndarray,没有列名。虽然不影响模型训练,但调试、特征重要性分析、后续人工检查时极易混乱。
从 scikit-learn 1.0+ 开始,所有转换器都支持 get_feature_names_out 方法。必须在 fit 后调用,且需逐个子转换器获取,再拼起来:
ct = ColumnTransformer([
("num", StandardScaler(), ["age", "income"]),
("txt", TfidfVectorizer(max_features=100), "review")
])
ct.fit(X_train)
feature_names = (
ct.named_transformers_["num"].get_feature_names_out() +
ct.named_transformers_["txt"].get_feature_names_out()
)
注意:named_transformers_ 是 fit 后才有的属性;若某转换器为 None(如 remainder="passthrough"),对应键不存在;TfidfVectorizer 的输出名默认是 vocab_word 形式,不含原始列名前缀,这点常被忽略。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











