当前位置: 首页 > news >正文

DAY 23 pipeline管道

@浙大疏锦行https://blog.csdn.net/weixin_45655710 知识回顾:

  1. 转化器和估计器的概念
  2. 管道工程
  3. ColumnTransformer和Pipeline类

作业:整理下全部逻辑的先后顺序,看看能不能制作出适合所有机器学习的通用pipeline

以心脏病数据集为例

没有pipline的代码

# 导入必要的库
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
import warnings# 忽略警告信息,使输出更整洁
warnings.filterwarnings("ignore")# 设置中文字体,确保图表中的中文能够正常显示
plt.rcParams['font.sans-serif'] = ['SimHei']  # SimHei是Windows下常用的黑体
plt.rcParams['axes.unicode_minus'] = False  # 正常显示图表中的负号data = pd.read_csv('heart.csv')# --- 步骤 2: 数据探索与预处理 ---
# 心脏病数据集的特征通常是数值型的,或者已经是编码好的类别型数值。
# 我们将检查是否有明显的字符串类型需要编码,并处理缺失值。# 2.1 检查是否有字符串类型的特征需要处理
# (根据常见的心脏病数据集,大部分特征应该是数值型)
object_columns = data.select_dtypes(include=['object']).columns
if not object_columns.empty:print(f"发现字符串类型的列: {object_columns.tolist()}")print("请根据具体列的含义决定如何编码(例如标签编码或独热编码)。")# 示例:如果需要,可以在此处添加对特定对象列的编码逻辑# 例如: data['某个对象列'] = data['某个对象列'].astype('category').cat.codes
else:print("✅ 数据集中没有发现需要特殊编码的字符串类型列。")# 2.2 检查并处理缺失值
# 对于心脏病数据集,通常用中位数或均值填充数值型特征的缺失值
print("\n检查各列的缺失值数量:")
print(data.isnull().sum())# 筛选出数值类型的列(包括整数和浮点数)
numerical_features = data.select_dtypes(include=[np.number]).columns.tolist()if data.isnull().sum().sum() > 0: # 如果存在任何缺失值print("\n正在使用中位数填充数值型特征的缺失值...")for feature in numerical_features:if data[feature].isnull().any(): # 如果该列存在缺失值median_value = data[feature].median() # 计算中位数data[feature].fillna(median_value, inplace=True) # 用中位数填充from sklearn.model_selection import train_test_split
X = data.drop(['target'], axis=1)  # 特征,axis=1表示按列删除
y = data['target'] # 标签
# 按照8:2划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)  # 80%训练集,20%测试集from sklearn.ensemble import RandomForestClassifier #随机森林分类器from sklearn.metrics import accuracy_score, precision_score, recall_score, f1_score # 用于评估分类器性能的指标
from sklearn.metrics import classification_report, confusion_matrix #用于生成分类报告和混淆矩阵
import warnings #用于忽略警告信息
warnings.filterwarnings("ignore") # 忽略所有警告信息
# --- 1. 默认参数的随机森林 ---
# 评估基准模型,这里确实不需要验证集
print("--- 1. 默认参数随机森林 (训练集 -> 测试集) ---")
import time # 这里介绍一个新的库,time库,主要用于时间相关的操作,因为调参需要很长时间,记录下会帮助后人知道大概的时长
start_time = time.time() # 记录开始时间
rf_model = RandomForestClassifier(random_state=42)
rf_model.fit(X_train, y_train) # 在训练集上训练
rf_pred = rf_model.predict(X_test) # 在测试集上预测
end_time = time.time() # 记录结束时间print(f"训练与预测耗时: {end_time - start_time:.4f} 秒")
print("\n默认随机森林 在测试集上的分类报告:")
print(classification_report(y_test, rf_pred))
print("默认随机森林 在测试集上的混淆矩阵:")
print(confusion_matrix(y_test, rf_pred))

pipeline的代码教学
导入库和数据加载 

# 导入基础库
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
import time # 导入 time 库
import warnings# 忽略警告
warnings.filterwarnings("ignore")# 设置中文字体和负号正常显示
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False# 导入 Pipeline 和相关预处理工具
from sklearn.pipeline import Pipeline # 用于创建机器学习工作流
from sklearn.compose import ColumnTransformer # 用于将不同的预处理应用于不同的列
from sklearn.preprocessing import OrdinalEncoder, OneHotEncoder, StandardScaler # 用于数据预处理(有序编码、独热编码、标准化)
from sklearn.impute import SimpleImputer # 用于处理缺失值# 导入机器学习模型和评估工具
from sklearn.ensemble import RandomForestClassifier # 随机森林分类器
from sklearn.metrics import classification_report, confusion_matrix # 用于评估分类器性能
from sklearn.model_selection import train_test_split # 用于划分训练集和测试集# --- 加载原始数据 ---
# 我们加载原始数据,不对其进行任何手动预处理
data = pd.read_csv('heart.csv')print("原始数据加载完成,形状为:", data.shape)
print(data.head()) # 可以打印前几行看看原始数据

分离特征和标签,划分数据集 

# --- 分离特征和标签 (使用原始数据) ---
y = data['target'] # 标签
X = data.drop(['target'], axis=1) # 特征 (axis=1 表示按列删除)print("\n特征和标签分离完成。")
print("特征 X 的形状:", X.shape)
print("标签 y 的形状:", y.shape)# --- 划分训练集和测试集 (在任何预处理之前划分) ---
# 按照8:2划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42) # 80%训练集,20%测试集print("\n数据集划分完成 (预处理之前)。")
print("X_train 形状:", X_train.shape)
print("X_test 形状:", X_test.shape)
print("y_train 形状:", y_train.shape)
print("y_test 形状:", y_test.shape)

 

代码汇总

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
import time # 导入 time 库
import warnings
warnings.filterwarnings("ignore")
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False # 防止负号显示问题# 导入 Pipeline 和相关预处理工具
from sklearn.pipeline import Pipeline #  用于创建机器学习工作流
from sklearn.compose import ColumnTransformer # 用于将不同的预处理应用于不同的列,之前是对datafame的某一列手动处理,如果在pipeline中直接用standardScaler等函数就会对所有列处理,所以要用到这个工具
from sklearn.preprocessing import OrdinalEncoder, OneHotEncoder, StandardScaler # 用于数据预处理
from sklearn.impute import SimpleImputer # 用于处理缺失值# 机器学习相关库
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import classification_report, confusion_matrix, accuracy_score, precision_score, recall_score, f1_score
from sklearn.model_selection import train_test_split # 只导入 train_test_split# --- 加载原始数据 ---
data = pd.read_csv('heart.csv')# --- 分离特征和标签 (使用原始数据) ---
X = data.drop(['target'], axis=1)  # 特征,axis=1表示按列删除
y = data['target'] # 标签# --- 划分训练集和测试集 (在任何预处理之前划分) ---
# X_train 和 X_test 现在是原始数据中划分出来的部分,不包含你之前的任何手动预处理结果
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)# --- 定义不同列的类型和它们对应的预处理步骤 (这些将被放入 Pipeline 的 ColumnTransformer 中) ---
# 这些定义是基于原始数据 X 的列类型来确定的# 识别原始的 object 列 (对应你原代码中的 discrete_features 在预处理前)
object_cols = X.select_dtypes(include=['object']).columns.tolist()# --- 2. 定义不同类型的特征列 ---
# 根据心脏病数据集的常见定义来划分特征# 数值型连续特征
# 这些特征的值是连续的,可以进行比较和度量
continuous_features = ['age', 'trestbps', 'chol', 'thalach', 'oldpeak']# 类别型特征 (虽然它们是数字,但代表类别,没有大小顺序关系)
# 我们将对这些特征进行独热编码
nominal_features = ['sex', 'cp', 'fbs', 'restecg', 'exang', 'slope', 'ca', 'thal']# --- 3. 构建特征处理的 Pipelines ---
# 在这个心脏病数据集中,我们主要有两类特征:连续型和类别型。# 构建处理连续特征的 Pipeline:
# 步骤1: 用中位数填充可能存在的缺失值 (更稳健的选择)
# 步骤2: 标准化数据,使其均值为0,方差为1
continuous_transformer = Pipeline(steps=[('imputer', SimpleImputer(strategy='median')),('scaler', StandardScaler())
])# 构建处理类别特征的 Pipeline:
# 步骤1: 用众数填充可能存在的缺失值
# 步骤2: 进行独热编码,将每个类别转换为一个新列
nominal_transformer = Pipeline(steps=[('imputer', SimpleImputer(strategy='most_frequent')),('onehot', OneHotEncoder(handle_unknown='ignore', sparse_output=False))
])# --- 4. 使用 ColumnTransformer 组合所有处理步骤 ---
# ColumnTransformer 可以将不同的处理 Pipeline 应用到不同的列上
preprocessor = ColumnTransformer(transformers=[('num', continuous_transformer, continuous_features),('cat', nominal_transformer, nominal_features)],remainder='passthrough' # 保留未被指定的列(如果有的话),默认为'drop'
)# --- 5. 应用预处理器到数据上 ---
# 现在,你可以将这个 preprocessor 应用到你的特征数据X上
# 这通常在机器学习模型的 Pipeline 中完成,或者直接转换数据
# 例如:
# X_processed = preprocessor.fit_transform(X)
# print(f"\n预处理后的数据形状: {X_processed.shape}")
# print("这个 X_processed 就可以用于训练模型了。")# 为了演示,我们可以直接在X上应用它
X_processed = preprocessor.fit_transform(X)# --- 构建完整的 Pipeline ---
# 将预处理器和模型串联起来
# 使用你原代码中 RandomForestClassifier 的默认参数和 random_state,这里的参数用到了元组这个数据结构
pipeline = Pipeline(steps=[('preprocessor', preprocessor), # 第一步:应用所有的预处理 (ColumnTransformer)('classifier', RandomForestClassifier(random_state=42)) # 第二步:随机森林分类器
])# --- 1. 使用 Pipeline 在划分好的训练集和测试集上评估 ---print("--- 1. 默认参数随机森林 (训练集 -> 测试集) ---") 
start_time = time.time() # 记录开始时间# 在原始的 X_train 上拟合整个Pipeline
# Pipeline会自动按顺序执行preprocessor的fit_transform(X_train),然后用处理后的数据拟合classifier
pipeline.fit(X_train, y_train)# 在原始的 X_test 上进行预测
# Pipeline会自动按顺序执行preprocessor的transform(X_test),然后用处理后的数据进行预测
pipeline_pred = pipeline.predict(X_test)end_time = time.time() # 记录结束时间print(f"训练与预测耗时: {end_time - start_time:.4f} 秒") # 使用你原代码的输出格式print("\n默认随机森林 在测试集上的分类报告:") # 使用你原代码的输出文本
print(classification_report(y_test, pipeline_pred))
print("默认随机森林 在测试集上的混淆矩阵:") # 使用你原代码的输出文本
print(confusion_matrix(y_test, pipeline_pred))

 

  • 特征分类的改变

    • 没有有序分类特征:在标准的心脏病数据集中,像cp (胸痛类型) 或 thal (地中海贫血) 这类虽然是用数字表示,但数字本身没有大小顺序关系(例如,类型3不一定比类型2“好”或“差”)。因此,我们没有使用 OrdinalEncoder
    • 连续特征与类别特征的重新定义:我们根据特征的医学含义,将age, trestbps, chol等定义为连续特征,将sex, cp, fbs等定义为类别特征。这是处理此数据集的关键一步。
  • Pipeline 的简化

    • 由于只有两种特征类型(连续型和类别型),我们将原有的三个transformer简化为两个:continuous_transformernominal_transformer
    • nominal_transformer 在此数据集中负责处理所有非连续的特征,对它们进行独热编码,因为这是处理无序类别特征最标准的方法。
  • 核心工具 ColumnTransformer

    • 代码的核心是使用 sklearn.compose.ColumnTransformer。这个工具非常强大,它可以接收一个列表,列表中每个元素都指定了 “要用哪个处理流程 (transformer) 来处理哪些列 (columns)”
    • ('num', continuous_transformer, continuous_features): 表示对 continuous_features 列表中的列应用 continuous_transformer
    • ('cat', nominal_transformer, nominal_features): 表示对 nominal_features 列表中的列应用 nominal_transformer
    • 这样,一个 preprocessor 对象就包含了对整个数据集所有特征的完整处理逻辑。

相关文章:

  • C#使用MindFusion.Diagramming框架绘制流程图(1):基础类型
  • FART 脱壳某大厂 App + CodeItem 修复 dex + 反编译还原源码
  • maven私服
  • 基于KNN算法的入侵检测模型设计与实现【源码+文档】
  • C++.OpenGL (5/64)变换(Transformation)
  • day2 大模型学习 Qwen2.5微调入门
  • salesforce sandbox 不支持 data export
  • STM32外设问题总结
  • 传统业务对接AI-AI编程框架-Rasa的业务应用实战(5)--Rasa成型可用 rasa服务化部署及识别意图后的决策及行为
  • 如何解决 远程 合并冲突
  • 前端技能包
  • 【见合八方平面波导外腔激光器专题系列】用于干涉光纤传感的低噪声平面波导外腔激光器2
  • CSS 性能优化
  • Neo4j 集群管理:原理、技术与最佳实践深度解析
  • 【JMeter】后置处理器 - 提取器
  • 交易所系统攻坚:高并发撮合引擎与合规化金融架构设计
  • AGain DB和倍数增益的关系
  • 【Ragflow】26.RagflowPlus(v0.4.0):完善解析逻辑/文档撰写模式全新升级
  • Typeerror: cannot read properties of undefined (reading ‘XXX‘)
  • C++——红黑树
  • 青州网站建设/成全视频免费观看在线看
  • 有没有做租赁的网站/厦门网络关键词排名
  • 网站收录低的原因/推广普通话的意义50字
  • 客户跟进系统 免费/拼多多关键词优化是怎么弄的
  • 怎么做分销平台/优化防控举措
  • 遵义城乡建设网站/百度 个人中心首页