前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >如何通过交叉验证改善你的训练数据集?

如何通过交叉验证改善你的训练数据集?

作者头像
AI研习社
发布2019-10-08 17:18:53
4.2K0
发布2019-10-08 17:18:53
举报
文章被收录于专栏:AI研习社AI研习社
原标题 | Cross Validation — Why & How

作 者 | Amitrajit Bose

翻 译 | 天字一号(郑州大学)、stone豪

假设这样一种情况,你对一个样本不均匀的数据集做了一段时间的处理,在这期间你用其中一部分数据做试验,测试了n种机器学习方法,然后喜闻乐见的发现每次的准确率都高达95%。你觉得这95%的准确率真的是实至名归吗?

评估的需求

现在我假设你对数据集的预处理做的十分完美,去除了缺失值、处理了类别数据、消除了噪声。无论您使用什么先进的算法来构建假设函数并训练机器学习模型,都必须在继续进行之前评估其性能。

现在,评估模型最简单、最快的方法当然就是直接把你的数据集拆成训练集和测试集两个部分,使用训练集数据训练模型,在测试集上对数据进行准确率的计算。当然在进行测试集验证集的划分前,要记得打乱数据的顺序。但是仅仅这样做并不是那么的保险,简而言之,你不能用这样得到的准确率作为这个模型最终的评判标准。这个时候问题就来了,你可能想知道——为什么?

假设现在你正在做一个关于垃圾邮件分类的工作,数据集98%都是垃圾邮件,仅2%为有效邮件,在这种情况下,即便是不建立任何模型,直接把所有的邮件都认为是垃圾邮件,你都可以获得98%的准确率。这种情况我们称作是“准确率悖论”(https://en.wikipedia.org/wiki/Accuracy_paradox)。

想象一下,如果一个基于胸部x光线的肿瘤分类模型是用这样的方法让准确率上了98%,并且还将这项技术推向了市场。你将无法想象这将会让多少人从其中丧命。

不要着急,或许你可以稍微不那么严肃的去喝杯热水,在下面的文章中,我会向你介绍整个机器学习过程中如何对你的模型建立评价指标,你只需要有python基础就可以了。

模型评估

我们一开始将全部数据拆分为两组,一组用于训练模型,另一组则作为验证集保存,用于检查模型测试未知数据时的性能。下图总结了数据拆分的全部思路。

模型构建和评估管道的流程图概览

注意:训练集和测试集的比例可设置为80:20,75:25,90:10等等。这个比例是根据数据量的大小认为设置的。一个常用的比例是使用25%的数据进行测试。

对数据进行划分,你可以很容易使用Python或者开源工具Scikit Learn API。.

X表示全部数据集中最原始的特征,y表示与之对应的类别标签。上面的函数将训练集和测试集按照0.3的比例划分,其中30%的数据用于测试。参数shuffle设置为True时,数据集在拆分之前就会被随机打乱顺序。参数stratify是最进scikit learn从版本v0.17中新添加的,这个参数在处理不均衡数据时候比较重要,例如垃圾邮件分类。利用这一参数时,保证了生成的样本中的值比例与提供给参数的值比例相同。例如,如果变量 y 是具有值 0 和 1 的二进制分类变量,并且有 10% 的0和90%的1,则 stratify=y 将确保随机拆分时,保证子数据集中具有 10% 的 0 和 90% 的 1。

正如我们所讨论的,由于类不平衡等因素,仅检查测试集中有多少示例被正确分类并不是检查模型性能的有用指标。我们需要一个更加稳健和细致入微的衡量标准。

混淆矩阵

我们需要了解以下混淆矩阵。这是判断模型性能的一种简单且流行的方法。让我们通过垃圾邮件分类方案来理解这一点。混淆矩阵如下所示。

通过混淆矩阵可以得到以下几个指标:

精确度基本上就是你说的所有相关的东西,而召回率是所有真正相关的东西。换句话说,召回率也称为模型的灵敏度,而精确度称为正预测值。这里有一张表来总结了混淆矩阵:http://numerical.recipes/whp/ConfusionMatrixDefns.pdf。

当你理解了上面这些概念之后,利用scikit learn,只需要几行Python代码就可以得到混淆矩阵的结果。

代码语言:javascript
复制
from sklearn.metrics import confusion_matrix, classification_report
y_pred = model.predict (X_test)
print(confusion_matrix(y_test, y_pred))
print(classification_report(y_test, y_pred))

假设你已经使用 .fit()方法在训练集上训练了模型(关于这一问题我可能在其他时间详细地写出来),然后使用模型的 .predicted() 方法计算预测的标签集。y_test 为原始数据的标签,并将预测的标签集合y_test这两个数组传递到上述两个函数中。就可以获得一个2 x 2的混淆矩阵(因为垃圾邮件分类是二进制分类),并返回一个涵盖上述所有指标的分类报告。

注意: 真实值作为第一个参数传递,预测值是第二个参数。

你可以将目标名称作为额外的参数传递给分类报告(参考说明文档:https://scikit-learn.org/stable/modules/generated/sklearn.metrics.classification_report.html)

交叉验证

交叉验证是一种评估数据分析对独立数据集是否通用的技术。它是一种通过在可用输入数据的子集上训练几个模型并在数据的补充子集上对其进行评估来评估机器学习模型的技术。使用交叉验证,我们很容易发现模型是否过拟合。

有5种常用的交叉验证方法:

代码语言:javascript
复制
1. K-Fold Cross Validation
2. Leave P-out Cross Validation
3. Leave One-out Cross Validation
4. Repeated Random Sub-sampling Method
5. Holdout Method

在这篇文章中,我们将讨论最流行的K折交叉验证,其他虽然也非常有效,但不太常用。

我们简单了解一下为什么需要交叉验证 — 我们一直将数据集拆分为训练集和测试集(或保留集)。但是,准确性和衡量标准会因为数据集拆分方式的不同而存在很大偏差,这取决于数据集是否被随机排列、用于训练和测试的是哪一部分、拆分的比例是多少,等等。此外,它并不代表模型的归纳能力。因此我们需要进行交叉验证。

K折交叉验证

首先我需要向你介绍一条黄金准则:训练集和测试集不要混在一块。你的第一步应该是隔离测试数据集,并将其仅用于最终评估。这样才能在训练集上执行交叉验证。

5折交叉验证

最初,整个训练数据集被分成k个相等的部分。第一部分作为hold out(测试)集,其余k-1部分用于训练模型。然后将训练好的模型在holdout集上进行测试,上述过程重复k次,每次我们都在不断地改变hold out集,这样,每个数据点都有相等的机会被包含在测试集中。

通常,k设置为3或5。也可以设置的很大,比如10或者15,但是它在计算上非常庞大且耗时。 让我们看看如何使用几行Python代码和Sci-kit Learn API来实现这一点。

代码语言:javascript
复制
from sklearn.model_selection import cross_val_score
print(cross_val_score(model, X, y, cv=5))

我们将模型或者分类器、特征、标签和K折交叉验证的参数cv传入该函数,该函数就会返回每次迭代是的k个精度。通常来说,我们取这k个精度的平均值作为最终的结果。

代码语言:javascript
复制
import numpy as np
print(np.mean(cross_val_score(model, X, y, cv=5)))

虽然这么做计算量很大,但是交叉验证在评估模型的性能是是非常必要的。

你在文章的参考部分可以看看我提到过的其他交叉验证的方法。

结论

机器学习模型的精度要求因行业、领域、要求和问题的不同而异。但是,在没有评估所有基本指标的情况下,模型称不上是训练完成。

顺便说一下,一旦您完成了评估并最终确认您的机器学习模型,您应该重新训练最初被隔离的测试数据,使用完整的数据训练模型,能增加更好的预测。

谢谢您的阅读。这是一个高层次的专题概述,我试图尽我所能,以简单的方式解释所用到的概念。请随时对文章发表评论、批评和提出改进建议。此外,您的鼓励支持我写更多!敬请期待更多文章。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-09-30,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 AI研习社 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 评估的需求
  • 模型评估
    • 混淆矩阵
    • 交叉验证
      • K折交叉验证
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档