1. 项目概述与核心价值最近在数据科学和机器学习社区里一个名为>import pandas as pd from data_prep_kit import DataLoader, AutoInspector from data_prep_kit.pipeline import PreprocessingPipeline from data_prep_kit.transformers import * # 1. 加载数据 loader DataLoader(source_typecsv, file_pathhouse_prices.csv) df loader.load() # 2. 自动探查 inspector AutoInspector() report inspector.inspect(df) print(report.summary()) # 输出可能包含 # - 总行数1460 # - 总列数81 # - 数值型特征37列 # - 分类型特征43列 # - 日期型特征1列YearBuilt # - 缺失值最严重的列PoolQC (99.5%缺失)MiscFeature (96%缺失)这份报告立刻告诉我们数据中有大量缺失的列有些甚至缺失率超过99%。在实际项目中对于缺失率超过某个阈值比如95%的特征通常的做法是直接删除因为它们提供的信息量极少且可能引入噪声。3.2 定义清洗与转换策略基于探查报告我们开始配置处理步骤。我们将使用ColumnTransformer来对不同类型的列应用不同的转换。# 定义预处理步骤 numeric_features report.get_numeric_columns() categorical_features report.get_categorical_columns() date_features report.get_date_columns() # 高缺失率特征列表根据报告手动列出 high_missing_cols [PoolQC, MiscFeature, Alley, Fence, FireplaceQu] # 创建列转换器 preprocessor ColumnTransformer( transformers[ # 数值型特征填充中位数并做标准化 (num, Pipeline(steps[ (imputer, SimpleImputer(strategymedian)), (scaler, StandardScaler()) ]), [col for col in numeric_features if col not in high_missing_cols]), # 分类型特征填充‘Unknown’做目标编码需要目标变量y (cat, Pipeline(steps[ (imputer, SimpleImputer(strategyconstant, fill_valueUnknown)), (encoder, TargetEncoder()) # 注意需要在fit时传入y ]), [col for col in categorical_features if col not in high_missing_cols]), # 日期特征转换为年份、月份等 (date, DateExtractor(features[year, month]), date_features), ], remainderdrop # 丢弃我们未明确处理的其他列包括高缺失率列 )这里有几个关键点针对性处理我们对数值型和分类型特征分别建立了子流水线Pipeline。目标编码的集成TargetEncoder需要在fit方法中传入目标变量y># 假设目标变量列名是 SalePrice target_col SalePrice X df.drop(columns[target_col]) y df[target_col] # 构建完整流水线 full_pipeline PreprocessingPipeline( steps[ (high_missing_dropper, ColumnDropper(columnshigh_missing_cols)), (preprocessor, preprocessor), (feature_engineering, PolynomialFeatures(degree2, interaction_onlyTrue)), # 添加交互特征 ] ) # 在训练集上拟合流水线学习所有转换参数 X_train_processed full_pipeline.fit_transform(X, y) # 注意这里fit_transform传入了y供TargetEncoder使用 # 查看处理后的数据形状和样例 print(f原始特征数{X.shape[1]}) print(f处理后特征数{X_train_processed.shape[1]}) print(X_train_processed[:5])流水线的fit_transform方法会依次执行删除高缺失列 - 按列类型进行填充、编码、转换 - 生成交互特征。最终输出的X_train_processed是一个干净的、数值型的 NumPy 数组或 DataFrame可以直接输入到机器学习模型中。3.4 流水线持久化与新数据转换模型训练完成后我们必须保存这个流水线以便在未来对测试集或新的房屋数据进行相同的处理。import joblib # 保存流水线 pipeline_path house_price_preprocessing_pipeline.joblib joblib.dump(full_pipeline, pipeline_path) # 在另一个环境如模型服务中加载流水线 loaded_pipeline joblib.load(pipeline_path) # 对新数据例如测试集进行转换 # 注意这里调用的是 transform不是 fit_transform确保使用训练时学到的参数如中位数、编码映射 new_data pd.read_csv(new_houses.csv) new_data_processed loaded_pipeline.transform(new_data)这个过程完美解决了数据预处理的一致性问题。无论何时何地loaded_pipeline都会以完全相同的方式处理数据。4. 高级特性与定制化开发一个优秀的数据准备工具包不仅要提供常用功能还要留有足够的扩展性。>from sklearn.base import BaseEstimator, TransformerMixin class CustomFeatureEngineer(BaseEstimator, TransformerMixin): 一个自定义的特征工程器计算房屋的‘总建筑面积’特征。 def __init__(self): pass def fit(self, X, yNone): # 这个转换器不需要从数据中学习任何参数 return self def transform(self, X): # 确保X是DataFrame并且有需要的列 X X.copy() # 假设‘1stFlrSF’是一楼面积‘2ndFlrSF’是二楼面积 if 1stFlrSF in X.columns and 2ndFlrSF in X.columns: X[TotalSF] X[1stFlrSF] X[2ndFlrSF] return X # 将这个自定义转换器加入到流水线中 full_pipeline.steps.insert(2, (custom_feature, CustomFeatureEngineer()))4.2 超参数调优集成更高级的用法是将预处理流水线本身作为机器学习超参数调优的一部分。例如你可以使用scikit-learn的GridSearchCV或RandomizedSearchCV来同时搜索“缺失值填充策略用均值还是中位数”以及“分类编码用独热编码还是目标编码”等预处理参数和模型参数的最佳组合。>from sklearn.model_selection import GridSearchCV from sklearn.ensemble import RandomForestRegressor # 创建一个包含预处理和模型的完整流水线 from sklearn.pipeline import Pipeline model_pipeline Pipeline([ (preprocessing, full_pipeline), # 使用我们之前定义的预处理流水线 (model, RandomForestRegressor()) ]) # 定义参数网格包括预处理参数 param_grid { preprocessing__preprocessor__num__imputer__strategy: [mean, median], # 数值填充策略 preprocessing__preprocessor__cat__encoder__strategy: [onehot, target], # 分类编码策略 model__n_estimators: [100, 200], model__max_depth: [10, 20, None] } grid_search GridSearchCV(model_pipeline, param_grid, cv5, scoringneg_mean_squared_error, verbose2) grid_search.fit(X, y)这种方式实现了真正的端到端自动化机器学习AutoML中的预处理环节优化。5. 常见陷阱、排查技巧与最佳实践即使有了强大的工具在实际使用中仍然会遇到各种问题。以下是我在多个项目中使用类似工具包积累的一些经验。5.1 数据泄露Data Leakage这是预处理中最隐蔽也最致命的错误。绝对不要在拟合fit预处理转换器之前在整个数据集训练集测试集上进行任何需要从数据中学习参数的操作例如计算填充缺失值的均值/中位数。拟合标准化器StandardScaler的均值和标准差。拟合目标编码器TargetEncoder的类别-目标值映射。基于整个数据集进行特征选择。正确做法始终先进行训练集-测试集分割然后在训练集上fit_transform预处理流水线在测试集上只使用transform。from sklearn.model_selection import train_test_split X_train, X_test, y_train, y_test train_test_split(X, y, test_size0.2, random_state42) # 只在训练集上拟合流水线 full_pipeline.fit(X_train, y_train) X_train_processed full_pipeline.transform(X_train) # 等价于上面的fit_transform但概念更清晰 # 在测试集上应用已拟合的转换 X_test_processed full_pipeline.transform(X_test) # 注意这里没有y_test但TargetEncoder会使用训练时学到的映射5.2 类别特征处理的一致性当测试集中出现了训练集中从未见过的类别“未知类别”时很多编码器会出错。># 方法1逐步执行 step1_output full_pipeline.named_steps[high_missing_dropper].fit_transform(X) print(“第一步删除列后形状”, step1_output.shape) # 方法2使用Pipeline的 set_output 方法如果支持 # 这可以让中间步骤的输出也保持为DataFrame方便查看列名 full_pipeline.set_output(transform”pandas”) X_train_df full_pipeline.fit_transform(X_train, y_train) # 现在X_train_df是一个DataFrame列名清晰可见5.4 性能与内存考量对于超大规模数据集一些操作如独热编码高基数特征可能导致内存爆炸。此时需要考虑使用稀疏矩阵确保编码器支持输出稀疏矩阵sparseTrue。增量学习/在线学习对于流式数据需要寻找支持partial_fit方法的转换器。降维在特征工程后如果特征维度爆炸考虑使用 PCA、特征选择等方法进行降维这本身也可以作为流水线的一个步骤。5.5 版本控制与文档化保存的.joblib或.pkl文件是二进制文件无法直接查看其内容。务必为每个保存的流水线建立详细的文档记录使用的>
data-prep-kit:Python数据预处理工具包,自动化清洗、特征工程与流水线构建
发布时间:2026/5/16 3:59:51
1. 项目概述与核心价值最近在数据科学和机器学习社区里一个名为>import pandas as pd from data_prep_kit import DataLoader, AutoInspector from data_prep_kit.pipeline import PreprocessingPipeline from data_prep_kit.transformers import * # 1. 加载数据 loader DataLoader(source_typecsv, file_pathhouse_prices.csv) df loader.load() # 2. 自动探查 inspector AutoInspector() report inspector.inspect(df) print(report.summary()) # 输出可能包含 # - 总行数1460 # - 总列数81 # - 数值型特征37列 # - 分类型特征43列 # - 日期型特征1列YearBuilt # - 缺失值最严重的列PoolQC (99.5%缺失)MiscFeature (96%缺失)这份报告立刻告诉我们数据中有大量缺失的列有些甚至缺失率超过99%。在实际项目中对于缺失率超过某个阈值比如95%的特征通常的做法是直接删除因为它们提供的信息量极少且可能引入噪声。3.2 定义清洗与转换策略基于探查报告我们开始配置处理步骤。我们将使用ColumnTransformer来对不同类型的列应用不同的转换。# 定义预处理步骤 numeric_features report.get_numeric_columns() categorical_features report.get_categorical_columns() date_features report.get_date_columns() # 高缺失率特征列表根据报告手动列出 high_missing_cols [PoolQC, MiscFeature, Alley, Fence, FireplaceQu] # 创建列转换器 preprocessor ColumnTransformer( transformers[ # 数值型特征填充中位数并做标准化 (num, Pipeline(steps[ (imputer, SimpleImputer(strategymedian)), (scaler, StandardScaler()) ]), [col for col in numeric_features if col not in high_missing_cols]), # 分类型特征填充‘Unknown’做目标编码需要目标变量y (cat, Pipeline(steps[ (imputer, SimpleImputer(strategyconstant, fill_valueUnknown)), (encoder, TargetEncoder()) # 注意需要在fit时传入y ]), [col for col in categorical_features if col not in high_missing_cols]), # 日期特征转换为年份、月份等 (date, DateExtractor(features[year, month]), date_features), ], remainderdrop # 丢弃我们未明确处理的其他列包括高缺失率列 )这里有几个关键点针对性处理我们对数值型和分类型特征分别建立了子流水线Pipeline。目标编码的集成TargetEncoder需要在fit方法中传入目标变量y># 假设目标变量列名是 SalePrice target_col SalePrice X df.drop(columns[target_col]) y df[target_col] # 构建完整流水线 full_pipeline PreprocessingPipeline( steps[ (high_missing_dropper, ColumnDropper(columnshigh_missing_cols)), (preprocessor, preprocessor), (feature_engineering, PolynomialFeatures(degree2, interaction_onlyTrue)), # 添加交互特征 ] ) # 在训练集上拟合流水线学习所有转换参数 X_train_processed full_pipeline.fit_transform(X, y) # 注意这里fit_transform传入了y供TargetEncoder使用 # 查看处理后的数据形状和样例 print(f原始特征数{X.shape[1]}) print(f处理后特征数{X_train_processed.shape[1]}) print(X_train_processed[:5])流水线的fit_transform方法会依次执行删除高缺失列 - 按列类型进行填充、编码、转换 - 生成交互特征。最终输出的X_train_processed是一个干净的、数值型的 NumPy 数组或 DataFrame可以直接输入到机器学习模型中。3.4 流水线持久化与新数据转换模型训练完成后我们必须保存这个流水线以便在未来对测试集或新的房屋数据进行相同的处理。import joblib # 保存流水线 pipeline_path house_price_preprocessing_pipeline.joblib joblib.dump(full_pipeline, pipeline_path) # 在另一个环境如模型服务中加载流水线 loaded_pipeline joblib.load(pipeline_path) # 对新数据例如测试集进行转换 # 注意这里调用的是 transform不是 fit_transform确保使用训练时学到的参数如中位数、编码映射 new_data pd.read_csv(new_houses.csv) new_data_processed loaded_pipeline.transform(new_data)这个过程完美解决了数据预处理的一致性问题。无论何时何地loaded_pipeline都会以完全相同的方式处理数据。4. 高级特性与定制化开发一个优秀的数据准备工具包不仅要提供常用功能还要留有足够的扩展性。>from sklearn.base import BaseEstimator, TransformerMixin class CustomFeatureEngineer(BaseEstimator, TransformerMixin): 一个自定义的特征工程器计算房屋的‘总建筑面积’特征。 def __init__(self): pass def fit(self, X, yNone): # 这个转换器不需要从数据中学习任何参数 return self def transform(self, X): # 确保X是DataFrame并且有需要的列 X X.copy() # 假设‘1stFlrSF’是一楼面积‘2ndFlrSF’是二楼面积 if 1stFlrSF in X.columns and 2ndFlrSF in X.columns: X[TotalSF] X[1stFlrSF] X[2ndFlrSF] return X # 将这个自定义转换器加入到流水线中 full_pipeline.steps.insert(2, (custom_feature, CustomFeatureEngineer()))4.2 超参数调优集成更高级的用法是将预处理流水线本身作为机器学习超参数调优的一部分。例如你可以使用scikit-learn的GridSearchCV或RandomizedSearchCV来同时搜索“缺失值填充策略用均值还是中位数”以及“分类编码用独热编码还是目标编码”等预处理参数和模型参数的最佳组合。>from sklearn.model_selection import GridSearchCV from sklearn.ensemble import RandomForestRegressor # 创建一个包含预处理和模型的完整流水线 from sklearn.pipeline import Pipeline model_pipeline Pipeline([ (preprocessing, full_pipeline), # 使用我们之前定义的预处理流水线 (model, RandomForestRegressor()) ]) # 定义参数网格包括预处理参数 param_grid { preprocessing__preprocessor__num__imputer__strategy: [mean, median], # 数值填充策略 preprocessing__preprocessor__cat__encoder__strategy: [onehot, target], # 分类编码策略 model__n_estimators: [100, 200], model__max_depth: [10, 20, None] } grid_search GridSearchCV(model_pipeline, param_grid, cv5, scoringneg_mean_squared_error, verbose2) grid_search.fit(X, y)这种方式实现了真正的端到端自动化机器学习AutoML中的预处理环节优化。5. 常见陷阱、排查技巧与最佳实践即使有了强大的工具在实际使用中仍然会遇到各种问题。以下是我在多个项目中使用类似工具包积累的一些经验。5.1 数据泄露Data Leakage这是预处理中最隐蔽也最致命的错误。绝对不要在拟合fit预处理转换器之前在整个数据集训练集测试集上进行任何需要从数据中学习参数的操作例如计算填充缺失值的均值/中位数。拟合标准化器StandardScaler的均值和标准差。拟合目标编码器TargetEncoder的类别-目标值映射。基于整个数据集进行特征选择。正确做法始终先进行训练集-测试集分割然后在训练集上fit_transform预处理流水线在测试集上只使用transform。from sklearn.model_selection import train_test_split X_train, X_test, y_train, y_test train_test_split(X, y, test_size0.2, random_state42) # 只在训练集上拟合流水线 full_pipeline.fit(X_train, y_train) X_train_processed full_pipeline.transform(X_train) # 等价于上面的fit_transform但概念更清晰 # 在测试集上应用已拟合的转换 X_test_processed full_pipeline.transform(X_test) # 注意这里没有y_test但TargetEncoder会使用训练时学到的映射5.2 类别特征处理的一致性当测试集中出现了训练集中从未见过的类别“未知类别”时很多编码器会出错。># 方法1逐步执行 step1_output full_pipeline.named_steps[high_missing_dropper].fit_transform(X) print(“第一步删除列后形状”, step1_output.shape) # 方法2使用Pipeline的 set_output 方法如果支持 # 这可以让中间步骤的输出也保持为DataFrame方便查看列名 full_pipeline.set_output(transform”pandas”) X_train_df full_pipeline.fit_transform(X_train, y_train) # 现在X_train_df是一个DataFrame列名清晰可见5.4 性能与内存考量对于超大规模数据集一些操作如独热编码高基数特征可能导致内存爆炸。此时需要考虑使用稀疏矩阵确保编码器支持输出稀疏矩阵sparseTrue。增量学习/在线学习对于流式数据需要寻找支持partial_fit方法的转换器。降维在特征工程后如果特征维度爆炸考虑使用 PCA、特征选择等方法进行降维这本身也可以作为流水线的一个步骤。5.5 版本控制与文档化保存的.joblib或.pkl文件是二进制文件无法直接查看其内容。务必为每个保存的流水线建立详细的文档记录使用的>