You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

FunctionTransformer与Pipeline/ColumnTransformer使用报错及原理咨询

Sklearn Pipeline/ColumnTransformer报错修复及技术疑问解答

报错原因与修复

核心问题分析

  1. 函数依赖全局变量:drop_cols直接操作全局的data而非传入的参数,导致Pipeline运行时返回的是原始数据集(含已被删除的f列),与后续X_train的列不匹配。
  2. 列定义不一致:num_clmns/cat_clmns基于原始data定义,但X_train已删除f列,导致ColumnTransformer找不到对应列。
  3. 组件位置错误:全局列删除操作不应放在ColumnTransformer内部,它是针对全量数据的处理,需放在ColumnTransformer之前。

修复后的代码

import pandas as pd
from sklearn.pipeline import Pipeline
from sklearn.compose import ColumnTransformer
from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestClassifier
from sklearn.preprocessing import OneHotEncoder
from sklearn.preprocessing import StandardScaler
from sklearn.preprocessing import FunctionTransformer

# 生成测试数据
a = range(1, 10)
b = range(10, 100, 10)
c = range(11, 110, 11)
d = range(12, 120, 12)
e = ['aa','bb','cc','dd','ee','ff','gg','hh','ii']
f_list = ['ф','и','с','в','у','а','п','р','ш']
g = ['!','@','#','$','%','^','&','*','(']

test={'a': a, 'b': b, 'c': c, 'd': d, 'e': e, 'f': f_list, 'g': g}
data = pd.DataFrame(test, columns=['a', 'b', 'c', 'd', 'e', 'f', 'g'])

# 修复删除列函数:使用传入的参数而非全局变量
def drop_cols(X):
    cols = ['g']
    return X.drop(cols, axis=1)

# 拆分数据集
x = data.drop('f', axis=1)
y = data['f']

# 基于拆分后的x定义列,保证列匹配
num_clmns = x.select_dtypes(include='int').columns
cat_clmns = x.select_dtypes(include='object').columns

X_train, X_test, y_train, y_test = train_test_split(x, y, train_size=0.3, random_state=42)

# 列转换组件:仅处理x中存在的列
trans = ColumnTransformer([
    ('num_trans1', StandardScaler(), num_clmns),
    ('cat_trans1', OneHotEncoder(sparse_output=False, handle_unknown='ignore'), cat_clmns)
], remainder='passthrough')

# 正确的Pipeline顺序:全局处理→列转换→建模
pipe = Pipeline([
    ('drop_g', FunctionTransformer(drop_cols)),
    ('trans', trans),
    ('rtc', RandomForestClassifier())
])

pipe.fit(X_train, y_train)
print("Pipeline训练成功")

技术疑问解答

1. 三者的数据流转机制

  • FunctionTransformer:把普通Python函数包装成sklearn兼容组件,全量接收输入数据,全量输出转换结果,不针对特定列,仅做全局数据处理。
  • ColumnTransformer:对数据集的不同列子集并行应用不同转换器,流程为:拆分指定列子集→各子集单独执行fit_transform/transform→拼接所有结果输出。
  • Pipeline:将组件按顺序串联,前一个组件的输出作为后一个组件的输入,训练时依次执行fit_transform(最后一个模型组件执行fit),预测时依次执行transform后调用模型predict,数据单向流转。

2. ColumnTransformer.fit_transform与Pipeline.fit的差异

  • ColumnTransformer.fit_transform:针对多列子集做并行训练+转换,同时记录每个转换器的训练状态(如标准化的均值方差),最终返回拼接后的特征矩阵,属于同一层级的多分支处理。
  • Pipeline.fit:按顺序执行串行全流程训练,每个组件的训练依赖前序输出,负责保存整个链的训练状态,后续可直接处理新数据,属于线性的连续处理。

3. Pipeline构建的列与DataFrame规则

  • 列定义必须匹配当前数据:所有基于列名的操作(如ColumnTransformer指定列),必须基于当前流转到该组件的DataFrame列,不能复用原始数据的列定义。
  • 数据修改在前,列定义在后:若有删/加列操作,需在操作完成后再定义后续组件的列列表,避免列不存在的错误。
  • 组件顺序符合逻辑:全局数据处理(如删列、全局标准化)放前面,特定列处理(如ColumnTransformer)放中间,模型放最后。
  • 禁止依赖全局变量:转换器逻辑必须依赖传入参数,不能用全局DataFrame,否则会导致训练/预测时数据不匹配。

内容的提问来源于stack exchange,提问作者InfinityVaL

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 00:54:59