以下是一个完整的随机森林算法 Pipeline 示例代码,涵盖数据预处理、特征工程、模型训练和评估的全流程。
代码使用 scikit-learn 的 Pipeline 和 ColumnTransformer,并处理混合类型(数值型 + 分类型)特征。
import pandas as pd
import numpy as np
from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestClassifier
from sklearn.pipeline import Pipeline
from sklearn.compose import ColumnTransformer
from sklearn.impute import SimpleImputer
from sklearn.preprocessing import OneHotEncoder, StandardScaler
from sklearn.metrics import accuracy_score
# 生成示例数据集(包含数值型和分类型特征)
data = {
'age': [25, 30, np.nan, 45, 35, 28, 50, 31],
'income': [50000, 80000, 60000, np.nan, 120000, 45000, 95000, 77000],
'gender': ['M', 'F', 'F', 'M', 'M', 'F', np.nan, 'M'],
'education': ['Bachelor', 'Master', 'PhD', 'Bachelor', np.nan, 'Master', 'PhD', 'Bachelor'],
'purchased': [1, 0, 1, 0, 1, 0, 1, 1] # 目标变量
}
df = pd.DataFrame(data)
# 划分特征和目标列
X = df.drop('purchased', axis=1)
y = df['purchased']
# 划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
# 定义数值型和分类型特征列
numeric_features = ['age', 'income']
categorical_features = ['gender', 'education']
# 数值型特征处理管道
numeric_transformer = Pipeline(steps=[
('imputer', SimpleImputer(strategy='median')), # 填充缺失值
('scaler', StandardScaler()) # 标准化(虽然随机森林不必须,但展示用法)
])
# 分类型特征处理管道
categorical_transformer = Pipeline(steps=[
('imputer', SimpleImputer(strategy='most_frequent')), # 填充缺失值
('onehot', OneHotEncoder(handle_unknown='ignore')) # 独热编码
])
# 组合特征处理器
preprocessor = ColumnTransformer(
transformers=[
('num', numeric_transformer, numeric_features),
('cat', categorical_transformer, categorical_features)
])
# 完整Pipeline(特征处理 + 随机森林)
pipeline = Pipeline(steps=[
('preprocessor', preprocessor),
('classifier', RandomForestClassifier(
n_estimators=100,
max_depth=5,
random_state=42
))
])
# 训练模型
pipeline.fit(X_train, y_train)
# 预测并评估
y_pred = pipeline.predict(X_test)
print(f"Test Accuracy: {accuracy_score(y_test, y_pred):.2f}")
# 输出特征重要性(需要从Pipeline中提取预处理后的特征名)
onehot_columns = pipeline.named_steps['preprocessor'].named_transformers_['cat'].named_steps['onehot'].get_feature_names_out(categorical_features)
all_features = numeric_features + list(onehot_columns)
importances = pipeline.named_steps['classifier'].feature_importances_
print("\nFeature Importances:")
for feature, importance in zip(all_features, importances):
print(f"{feature}: {importance:.4f}")
代码解析
1. 数据准备
-
创建包含混合类型特征的示例数据:
- 数值型:
age(含缺失值)、income(含缺失值) - 分类型:
gender(含缺失值)、education(含缺失值) - 目标变量:
purchased(二分类)
- 数值型:
2. 特征处理
-
数值型特征:
- 使用
SimpleImputer用中位数填充缺失值 - 使用
StandardScaler标准化(尽管随机森林不需要,但展示通用写法)
- 使用
-
分类型特征:
- 使用
SimpleImputer用众数填充缺失值 - 使用
OneHotEncoder进行独热编码
- 使用
3. Pipeline 结构
Pipeline(
# 特征预处理
preprocessor = ColumnTransformer([
num → [Imputer → Scaler],
cat → [Imputer → OneHotEncoder]
]),
# 随机森林模型
classifier = RandomForestClassifier()
)
4. 核心优势
- 自动化流程:从原始数据到预测结果的全流程自动化处理
- 避免数据泄露:确保预处理仅基于训练数据统计量
- 可维护性:清晰的步骤分离,便于修改和调试
- 特征重要性:支持提取预处理后的特征名称与重要性对应
输出示例
Test Accuracy: 0.50
Feature Importances:
age: 0.3250
income: 0.2500
gender_F: 0.0250
gender_M: 0.1250
education_Bachelor: 0.1000
education_Master: 0.0500
education_PhD: 0.1250
扩展使用
- 超参数调优(使用
GridSearchCV):
from sklearn.model_selection import GridSearchCV
param_grid = {
'classifier__n_estimators': [50, 100, 200],
'classifier__max_depth': [3, 5, None]
}
search = GridSearchCV(pipeline, param_grid, cv=3)
search.fit(X_train, y_train)
print(f"Best params: {search.best_params_}")
- 处理更复杂数据:
- 添加
FunctionTransformer自定义特征工程 - 使用
OrdinalEncoder处理有序分类特征 - 集成特征选择组件(如
SelectKBest)
- 部署模型:
# 保存模型
import joblib
joblib.dump(pipeline, 'rf_pipeline.pkl')
# 加载模型
loaded_pipeline = joblib.load('rf_pipeline.pkl')
loaded_pipeline.predict(X_new)