ColumnTransformer内Pipeline中拟合后Transformer属性缺失问题排查
问题原因与解决方案
核心问题
你错误访问了未拟合的原始Transformer对象,而非拟合后生成的实例。在Scikit-learn里有个明确规则:
transformer.transformers:存的是定义ColumnTransformer时传入的初始未拟合转换器列表transformer.transformers_:带下划线的属性才是拟合完成后实际生成的转换器实例集合
你的代码用了transformer.transformers[0][1],拿到的是定义时的原始pipe对象——它内部的PCA根本没被真正拟合(真正的拟合过程发生在ColumnTransformer的fit方法里,拟合后的实例会存在transformers_中),自然没有explained_variance_ratio_这类拟合专属属性。
修正后的代码
把访问属性从transformers改成transformers_,同时推荐用命名属性替代硬编码索引,后续修改步骤顺序也不用调整代码:
from sklearn.preprocessing import OneHotEncoder, StandardScaler from sklearn.compose import ColumnTransformer from sklearn.pipeline import Pipeline from sklearn.decomposition import PCA import pandas as pd def transform(df: pd.DataFrame, cat_cols, log_cols, passthrough_cols): oh_enc = OneHotEncoder(handle_unknown='ignore') transformer_oh = ColumnTransformer([('cat_cols', oh_enc, cat_cols)], remainder='passthrough') scaler = StandardScaler() pca = PCA(n_components=5) pipe = Pipeline([("preprocessing", transformer_oh), ("scaling", scaler), ("pca", pca) ]) to_transform = list(set(df.columns) - set(passthrough_cols)) transformer = ColumnTransformer([("pipe", pipe, to_transform)], remainder='passthrough') transformer = transformer.fit(df) # 方式1:用transformers_ + steps索引(不推荐硬编码索引) pca2 = transformer.transformers_[0][1].steps[2][1] print(pca2.explained_variance_ratio_) # 方式2:用命名属性更清晰(推荐) fitted_pipe = transformer.named_transformers_['pipe'] fitted_pca = fitted_pipe.named_steps['pca'] print(fitted_pca.explained_variance_ratio_)
额外注意事项
- Scikit-learn里所有拟合后生成的属性都带下划线后缀(比如
explained_variance_ratio_、mean_),未拟合的实例不会有这些属性 - 用
named_transformers_和named_steps访问嵌套组件比索引可靠,后续调整Pipeline步骤顺序时不用改索引值 - 你的代码里
log_cols没用到,记得补充对应处理逻辑,避免功能遗漏
内容的提问来源于stack exchange,提问作者HrkBrkkl
相关产品推荐
相关产品推荐

