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

如何在Pipeline中实现特征工程方法?为何触发IndexError?

问题根源

你遇到的IndexError: Index dimension must be <=2本质是两个核心问题:

  1. Pipeline顺序逻辑错误:你把特征工程步骤add_features放在了预处理(编码、缩放)之后,但add_features依赖原始特征列(如Parch、SibSp、Name),而预处理后的输出是编码后的特征矩阵(稀疏矩阵/NumPy数组),不存在这些原始列名,且数据结构不支持DataFrame的列索引方式。
  2. 稀疏矩阵索引冲突:OneHotEncoder默认输出稀疏矩阵,当你用DataFrame的列索引方式(如df['Parch'])访问稀疏矩阵时,会触发SciPy稀疏矩阵的索引校验错误。
解决方案

调整Pipeline顺序,先完成缺失值填充,再执行特征工程,最后做编码、缩放等预处理——这样既避免了在含NA的数据集上运行特征工程报错,又保证add_features能访问到原始特征列。

步骤1:重新定义缺失值填充逻辑

先对原始数据集的缺失值进行填充,输出仍为DataFrame,方便后续特征工程:

import pandas as pd
from sklearn.preprocessing import FunctionTransformer

def fill_missing(df):
    # 替换成你实际定义的nominal/ordinal/numerical列名
    nominal_cols = ['Embarked', 'Sex']
    ordinal_cols = ['Pclass']
    numeric_cols = ['Age', 'Fare', 'SibSp', 'Parch']
    
    # 类别型特征用众数填充,数值型用均值填充
    df[nominal_cols] = df[nominal_cols].fillna(df[nominal_cols].mode().iloc[0])
    df[ordinal_cols] = df[ordinal_cols].fillna(df[ordinal_cols].mode().iloc[0])
    df[numeric_cols] = df[numeric_cols].fillna(df[numeric_cols].mean())
    return df

fill_missing_transformer = FunctionTransformer(fill_missing, validate=False)

步骤2:更新预处理Pipeline以适配特征工程后的列

特征工程后会新增Family_size、Alone、Title等列,需要重新定义预处理规则:

from sklearn.pipeline import Pipeline
from sklearn.impute import SimpleImputer
from sklearn.preprocessing import OneHotEncoder, OrdinalEncoder, StandardScaler
from sklearn.compose import ColumnTransformer

# 特征工程后的列划分
new_nominal = ['Sex', 'Embarked', 'Title']  # 新增Title到类别型列
new_ordinal = ['Pclass']
new_numeric = ['Age', 'SibSp', 'Parch', 'Family_size', 'Alone', 'Fare']

# 重新定义各类型列的预处理流程
nominal_pipeline = Pipeline([
    ('encoder', OneHotEncoder(drop='first', sparse_output=False))  # 输出密集数组,避免稀疏矩阵问题
])

ordinal_pipeline = Pipeline([
    ('encoder', OrdinalEncoder())
])

numeric_pipeline = Pipeline([
    ('scaler', StandardScaler())
])

preprocessing_pipeline = ColumnTransformer([
    ('nominal_preprocessor', nominal_pipeline, new_nominal),
    ('ordinal_preprocessor', ordinal_pipeline, new_ordinal),
    ('numeric_preprocessor', numeric_pipeline, new_numeric)
])

步骤3:构建正确顺序的完整Pipeline

from sklearn.neighbors import KNeighborsClassifier

# 你的特征工程函数保持不变
def add_features(df):
    df['Family_size'] = df['Parch'] + df['SibSp'] + 1
    df['Alone'] = 0
    df.loc[df.Family_size == 1, 'Alone'] = 1

    df.loc[df['Fare'] <= 130, 'Fare'] = 0
    df.loc[(df['Fare'] > 130) & (df['Fare'] <= 256), 'Fare'] = 1
    df.loc[(df['Fare'] > 256) & (df['Fare'] <= 384), 'Fare'] = 2
    df.loc[df['Fare'] > 384, 'Fare'] = 3
    df['Fare'] = df['Fare'].astype(int)

    df['Title'] = df.Name.str.extract(' ([A-Za-z]+)\.', expand=False)
    df['Title'] = df['Title'].replace(['Lady', 'Countess','Capt', 'Col',
                                       'Don', 'Dr', 'Major', 'Rev', 'Sir', 'Jonkheer', 'Dona'], 'Rare')
    df['Title'] = df['Title'].replace('Mlle', 'Miss')
    df['Title'] = df['Title'].replace('Ms', 'Miss')
    df['Title'] = df['Title'].replace('Mme', 'Mrs')

    title_mapping = {"Mr": 1, "Miss": 2, "Mrs": 3, "Master": 4, "Rare": 5}
    df['Title'] = df['Title'].map(title_mapping)
    df['Title'] = df['Title'].fillna(0)

    df.drop(columns=["Name"], inplace=True)
    return df

get_features = FunctionTransformer(add_features, validate=False)
knn = KNeighborsClassifier(n_neighbors=3)

# 正确顺序:填充缺失值 → 特征工程 → 编码缩放 → 模型
complete_pipeline_knn = Pipeline([
    ('fill_missing', fill_missing_transformer),
    ('feat_eng', get_features),
    ('preprocessing', preprocessing_pipeline),
    ('estimator', knn)
], verbose=True)

# 训练模型
complete_pipeline_knn.fit(X_train, y_train)

y_pred = complete_pipeline_knn.predict(X_train)
y_pred_test = complete_pipeline_knn.predict(test)
关键说明
  • 把缺失值填充放在最前面,确保add_features处理的是无NA的数据集,避免报错。
  • 特征工程后更新预处理的列划分,保证编码、缩放能覆盖所有新增特征。
  • 给OneHotEncoder加上sparse_output=False,输出密集数组,避免后续步骤的稀疏矩阵索引问题。

内容的提问来源于stack exchange,提问作者Emilio Cortés

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.23 14:03:23