【Python机器学习】算法链与管道——用预处理进行参数选择的注意项

对于许多机器学习算法,提供的特定数据表示非常重要。比如,首先对数据进行缩放,然后手动合并特征,再利用无监督机器学习来学习特征。因此,大多数机器学习应用不仅需要应用多个算法,而且还需要将许多不同的处理步骤和机器学习模型链接在一起。

使用Pipeline类可以简化构建变换和模型链的过程。

我们知道可以通过MinMaxScaler进行预处理来打打提高核SVM在cancer数据集上的性能,下面代码实现了数据划分、计算最小值最大值、缩放数据和训练SVM:

python 复制代码
import mglearn.plots
from sklearn.svm import SVC
from sklearn.datasets import load_breast_cancer
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import MinMaxScaler

cancer=load_breast_cancer()
#加载并划分数据
X_train,X_test,y_train,y_test=train_test_split(cancer.data,cancer.target,random_state=0)
#计算训练数据的最大最小值
scaler=MinMaxScaler().fit(X_train)

#对训练数据进行缩放
X_train_scaler=scaler.transform(X_train)
svm=SVC()
#在缩放后的训练数据上学习SVM
svm.fit(X_train_scaler,y_train)
X_test_scaler=scaler.transform(X_test)
print('测试集精度:{}'.format(svm.score(X_test_scaler,y_test)))

现在,如果我们希望利用GridSearchCV知道更好的SVC参数,有一种简单的方法可能如下所示:

python 复制代码
from sklearn.model_selection import GridSearchCV

param_grid={'C':[0.001,0.01,0.1,1,10,100],
            'gamma':[0.001,0.01,0.1,1,10,100]}
grid=GridSearchCV(SVC(),param_grid=param_grid,cv=5)
grid.fit(X_train_scaler,y_train)
print('最高精度:{}'.format(grid.best_score_))
print('最高测试集精度:{}'.format(grid.score(X_test_scaler,y_test)))
print('最佳参数:{}'.format(grid.best_params_))

其实实践中是不能这样使用的

这里我们利用缩放后的数据对SVC参数进行网格搜索。但是,上面的代码有个不易察觉的陷阱:

在缩放数据时,我们使用了训练集中的所有数据 来找到训练的方法,然后我们使用缩放后的训练数据来运行带交叉验证的网格搜索;对于交叉验证的每次划分,原始数据集的一部分被划分为训练部分,另一部分被划分为测试部分,测试部分用于度量在训练部分上所训练的模型在新数据上的表现。但是,我们在缩放数据时就已经试用过测试部分中所包含的信息。要知道,交叉验证每次划分的测试部分都是训练集的一部分,我们使用整个训练集的信息来找到数据的正确缩放。

对于模型来说,这些数据与新数据看起来截然不同。如果我们观察新数据集,那么这些数据并没有用于对训练数据进行缩放,其最大最小值也可能与训练数据不同。

下面这个例子显示了交叉验证与最终评估这两个过程中数据处理的不同之处:

python 复制代码
import matplotlib.pyplot as plt
mglearn.plots.plot_improper_processing()
plt.show()

因此,对于建模过程,交叉验证中的划分无法正确地反映新数据的特征。我们已经将这部分数据的信息"泄露"给建模过程。这将导致在交叉验证过程中得到过于乐观的结果。

为了解决这个问题,在交叉验证的过程中,应该在进行任何预处理之前就完成数据集的划分。任何从数据集中提取信息的过程都应该仅应用于数据集的训练部分,因此,任何交叉验证都应该位于处理过程的"最外层循环"。

在scikit-learn中,要想使用cross_val_score函数和GridSearchCV函数实现这一点,可以使用Pipeline类。Pipeline类可以将多个处理步骤合并为单个scikit-learn估计器。Pipeline类本身具有fit、predict、score方法,其行为与scikit-learn中的其他模型相同。

Pipeline类最常见的用例是将预处理步骤(比如数据缩放)与一个监督模型(比如分类器)链接在一起。

相关推荐
SmartBrain14 分钟前
DeerFlow 实践:华为IPD流程的评审智能体设计
人工智能·语言模型·架构
l1t1 小时前
利用DeepSeek实现服务器客户端模式的DuckDB原型
服务器·c语言·数据库·人工智能·postgresql·协议·duckdb
寒月霜华2 小时前
机器学习-数据标注
人工智能·机器学习
九章云极AladdinEdu3 小时前
超参数自动化调优指南:Optuna vs. Ray Tune 对比评测
运维·人工智能·深度学习·ai·自动化·gpu算力
Hello_Embed4 小时前
STM32HAL 快速入门(二十):UART 中断改进 —— 环形缓冲区解决数据丢失
笔记·stm32·单片机·学习·嵌入式软件
咸甜适中4 小时前
rust语言 (1.88) 学习笔记:客户端和服务器端同在一个项目中
笔记·学习·rust
人工智能训练师4 小时前
Ubuntu22.04如何安装新版本的Node.js和npm
linux·运维·前端·人工智能·ubuntu·npm·node.js
酷飞飞5 小时前
Python网络与多任务编程:TCP/UDP实战指南
网络·python·tcp/ip
Magnetic_h5 小时前
【iOS】设计模式复习
笔记·学习·ios·设计模式·objective-c·cocoa
cxr8286 小时前
SPARC方法论在Claude Code基于规则驱动开发中的应用
人工智能·驱动开发·claude·智能体