如何在Scikit-Learn Pipeline中按特征分组执行PCA而非全量特征计算
解决方案
核心通过scikit-learn的ColumnTransformer实现按特征子集执行独立变换,具体修改步骤如下:
步骤1:按后缀筛选分组特征
首先根据特征名后缀拆分出三个分组的特征列列表,示例代码如下:
# 假设你的数据集是pandas DataFrame,替换为你实际的特征名列表即可 feature_names = df.columns.tolist() n1_cols = [col for col in feature_names if col.endswith('_n1')] n2_cols = [col for col in feature_names if col.endswith('_n2')] n3_cols = [col for col in feature_names if col.endswith('_n3')]
步骤2:修改预处理Pipeline为分组变换
使用ColumnTransformer为三个分组分别配置「标准化+独立PCA」的流水线,修改后的完整代码如下:
from sklearn.compose import ColumnTransformer # 每个分组独立的预处理+PCA流水线,可单独配置每个PCA的n_components group_prep = [ ("n1_prep", Pipeline([ ("scaler", StandardScaler()), ("pca", PCA(n_components=7, random_state=42)) # 可自定义分量数 ]), n1_cols), ("n2_prep", Pipeline([ ("scaler", StandardScaler()), ("pca", PCA(n_components=7, random_state=42)) ]), n2_cols), ("n3_prep", Pipeline([ ("scaler", StandardScaler()), ("pca", PCA(n_components=6, random_state=42)) ]), n3_cols) ] # 替换原prepData为分组变换器,默认自动拼接三个分组的PCA输出结果 prepData = ColumnTransformer(transformers=group_prep) # 下游KMeans流水线保持不变即可 kModel = Pipeline( [ ( "kmeans", KMeans( n_clusters=6, init="k-means++", n_init=20, max_iter=100, random_state=42, ), ), ] ) pipe = Pipeline( [ ("prepData", prepData), ("kModel", kModel) ] )
补充说明
- 每个分组PCA的
n_components可根据实际分组特征数量独立调整,不需要和原全局PCA的分量数保持一致 - 如果有未归入三个分组的特征需要保留,可在
ColumnTransformer中添加remainder='passthrough'参数,未指定的特征会原样保留参与后续聚类
内容的提问来源于stack exchange,提问作者Gustavomoty
相关产品推荐
相关产品推荐

