要实现一个机器学习算法,那必然要经过很多步骤。现在有一个更高效的方法,可以将一些步骤链接起来,这就是“管道”。
管道有什么好处?最直观的就是可以减少我们所需的步骤,让算法更高效。它还有一个重要的优点,我们将在下面介绍。
一个不易觉察的小错误
在介绍管道之前,我们先来回顾一下构建算法模型时所需的一个大体流程。
假设我们使用SVM(支持向量机)来构建模型:
首先,我们将某一数据集分成训练集和测试集。
其次,由于SVM对数据敏感,也就是说需要对数据进行缩放。这里假设我们对训练集进行了0-1缩放。
然后,使用带交叉验证的网格搜索对训练集进行拟合,找出最佳的参数。
最后,评估在此参数下模型的精度。
上面的过程看似很完整,但却又一个不容易被发现的小缺陷,你发现了吗?
我们在对训练集进行数据预处理时,使用的是整个训练集的数据。而在进行交叉验证时,我们是将训练集的一部分作为验证集。因为我们先进行的数据缩放,也就是说验证集中的数据同样也进行了缩放。那么模型在拟合时,相当于已经知道了数据的一部分信息,而不是面对全新的数据。这样就会造成过拟合,模型的精度会被估计过高。如下图所示:
解决这个问题的方法也很简单,那就是把交叉验证放在数据预处理之前。换句话说,将带交叉验证的网格搜索放在外层循环,数据预处理放在内层循环。这样,就只会对交叉验证中的训练集进行缩放,而验证集不会受到影响。
在scikit-learn中,使用pipeline就可以实现上述过程。
创建一个管道
我们首先来看在不添加网格搜索时的管道创建,先加载必要的工具
然后创建管道
这样,我们就将数据预处理工具和SVC模型链接在了一起。其中,引号内的是对应工具的名称,我们可以自己定义。
同样,我们也可以用管道对数据进行拟合,然后观察其精度。这里使用之前的癌症数据集。
可以看到,最后的精度约为95.8%。
网格搜索中的管道
管道的另一个优点,就是可以在网格搜索中使用。这样,我们就解决了文章开始时所面对的问题。
在实际使用时,与之前并没有太大的不同。唯一需要注意的就是,在给GridSearchCV传入我们需要调节的参数时,要指定模型的名称。这个名称就是我们之前自己定义的那个。
比如SVC模型需要调节的参数是C和gamma,我们给SVC命名为“svc”,那么在传入参数时,需要写成“svc__C”和“svc__gamma”,注意中间是双下划线。
更高效的管道创建方法
除了我们上面提到的使用pipeline来创建管道之外,还有一种方法可以创建,那就是make_pipeline。
那这俩有啥区别呢?最大的区别就是make_pipeline不需要给对应的工具或模型命名,系统会自动给他们命名,名字就是工具或模型对应的英文小写。
我们来举个例子
可以看到,使用make_pipeline时,只需要直接传入数据预处理工具和模型即可,系统会自动命名。
当然,我们可以查看它们的名称
如果想查询其中具体的某一步骤或某一参数,可以使用named_steps属性
这就是今天的全部内容,喜欢就点个“在看”吧!
领取专属 10元无门槛券
私享最新 技术干货