一个机器学习任务的步骤应该是什么?
来源:10-7 ROC曲线
蛋包饭吃球球
2022-11-05
bobo老师好!打扰您宝贵的时间了!我最近在通过机器学习最简单的竞赛任务练手,结果发现理论学习和动手敲代码差距太大了,导致课程整体知识点上有些混乱,想再请教您几个基础问题,为我指点迷津!
1.我想请问一下机器学习任务的步骤,已经晕了(模型选择、调参、交叉验证、集成学习、评价结果并得出结论——主要是这几个步骤)。以分类问题为例,数据处理好后,我是应该先试一下不同的分类模型(例如knn,决策树等),根据它们在测试集的得分如何(期间不断调参得到最高精度再比较),然后留下精度最高的几个模型(例如留下3个),最后用不同方法集成这3个模型,选择精度最高的集成方法,得出结论吗? 那什么时候用到交叉验证呢,精度比较时到底是比较在验证集上还是测试集上的精度呢(已晕)?还有ROC曲线又是在哪个阶段画呢?
2.有些模型需要将数据标准化处理,例如kNN,有的模型则对数据在什么范围并不敏感,这时候是不是标准化反而会降低模型精度?那我们难道需要将数据集不断标准化、还原、标准化。。。来测试不同的模型精度吗?还有就是对于类别型特征,将它们编码后,训练模型前也需要将它们标准化吗?(假如有10个类别编号为0-9,标准化压缩到0-1之间后岂不是没有了意义?)
bobo老师听了您的课真的受益匪浅:) :),我有在努力跟上,也给小伙伴推荐过!我的问题可能有点多了,希望您能给别嫌弃我555,最好能给小白详细解答(特别是问题1),期待您在闲暇之余为我指点迷津!!!
1回答
-
这个问题有一些大,我一直想找一块儿完整的时间回复,回复得较晚,见谅。
整体而言,你的问题看似只有一个:一个相对完整的机器学习任务的步骤是什么。但是,你的具体描述里的问题其实是琐碎的,有一些问题是“框架”性的问题,而有一些问题是具体操作性的,细节上的问题。
如果只是简单回答:一个相对完整的机器学习任务的步骤是什么?其实是简单的。基本而言,就是:
1)采集数据;
2)特征工程,整理好数据;
3)选择一个机器学习算法,如果这个机器学习算法有超参数,也需要选择相应的超参数;
4)把数据扔给机器学习算法,得到结果;
5)如果结果不够好,在 2)或者3)进行改进(甚至可能需要重新做1)),之后再进行 4)直到觉得结果 ok 了.
这个课程的重点在 3),4),5),不涉及1)。这里先岔开一句,实际上,如果你真的做机器学习在某一个具体领域的研究的话,就会意识到,1)是非常非常重要,且非常非常值钱的。也就是对于很多问题,最大的问题其实是没有数据。
比如医疗领域的很多问题都是如此,我们其实没有足够多的患者数据;
还有一些情况,是获得数据的成本太高了,物理或者天文领域就是如此,我们必须发射太空检测器才能采集到数据;
就算研究我们身边的事物,要想获得足够好的数据,也有可能是成本高昂的,比如研究人的大脑发展,需要采集相当数量的人,在几十年的时间里每一个时间点的数据,这其实非常难做到,所以这样的数据集是非常少的。
当然,还有很多问题,数据不成问题,但没有突破的关键是算法。自然语言处理或者无人驾驶都属于这类问题。
扯远了,只是因为很多同学在实际的科研工作中,非常忽视 1),所以提及一下。如果你是做 kaggle 竞赛,1)不是你需要关心的重点。
==========
对于2)3)4)5),这门课程关注的是 3),4),5),但是很不幸的,对于很多实际工作或者 kaggle 竞赛,2)是最重要的。3),4),5)你一旦掌握了,能够产生的变化并不多(在应用层面,当然在算法研究层面还有很多新的东西可以尝试。)但是2)是非常灵活的,可以结合领域知识,有无数种方式做特征工程。
对此,可以参考我的这个问答:https://coding.imooc.com/learn/questiondetail/ZEgyveP0ABBYBk7V.html
再给你举一个例子,kaggle 上最著名的泰坦尼克号预测,其中排名最高的 notebook 是这个,你可以研究一下:https://www.kaggle.com/code/startupsci/titanic-data-science-solutions
其中有 52 个单元格,前 39 个单元格都是在做数据预处理,最后 13 个单元格才真的开始使用机器学习算法。如果学完了这个课程,应该从 In[40] 开始,觉得非常熟悉亲切就对了。前面的 39 个单元格的内容,是在学习完这个课程以后,真正应用机器学习的时候,你需要补的内容。大体包含:
a) 工具类,比如 pandas,matplot 或者一些数学库的使用;
b) 统计学;
c) 机器学习算法中的一些和特征工程相关的算法,主要集中在非监督学习领域;
d) 领域知识
所以说,这个课程是机器学习的入门课程,远达不到真正应用机器学习的程度。我对于学习完这个课程,进一步使用机器学习的建议,可以参考这里:https://coding.imooc.com/lesson/169.html#mid=15180
另外,如果你比较集中在想搞诸如 kaggle 这类比赛的话,一定不要仅仅把 kaggle 当做一个竞赛网站。实际上,kaggle 是一个非常好的学习网站。就算你不参与到互动中,和其他人做交流学习,仅仅是被动地接受知识,也有很多很好的资源,这几个页面的内容你都可以做学习用:
https://www.kaggle.com/competitions?hostSegmentIdFilter=5
==========
最后,我结合你的具体描述中的一些问题,再做一下回答。我会选择一个更“合理”的顺序来回答你的这些疑问。
a) 精度比较时到底是比较在验证集上还是测试集上的精度呢(已晕)?
答:这其实是一个非常重要的问题。我可以毫不客气的说,看到的很多论文,在具体使用机器学习的方法的时候,在这一步都是错误的。对于这个问题,我建议再回顾一遍课程的 8-4,8-5,8-6 三个小节。
简单的回答,就是:在对一个学习算法调参的时候,应该比较的是验证数据集的精度。测试数据集在模拟“你完全不知道的数据”,所以不能参与到训练过程中;
最终调好参数以后,使用训练集+验证集一起,用调好的参数训练模型,报告在测试集上的精度。也就是测试集的作用只是报告你的模型的结果而已,而不能参与到训练中,否则就是 data leakage。
但是,如果你是做类似 kaggle 这样的比赛,没有这个问题。这是因为 kaggle 比赛已经为你准备好了你完全不知道 label 的测试集,你想“不小心 data leakage”都很难,因为测试集没有 label,你自然无法拿他做训练。所以最终,你在 kaggle 的一个比赛中,提交的对测试集的预测结果,kaggle 最终给你的评分,就是你的算法的最终结果。
-----
b)那什么时候用到交叉验证呢
答:从现在开始,我们的讨论就不牵扯测试集了。因为上面说过了,测试集本质是模拟你根本不知道的数据。但是比较麻烦的是,你会看到很多网上的讨论中,会把扔掉“真正”测试集以后的数据,再做“训练-测试数据集”的划分,但其实,严谨的说,此时应该叫“训练-验证数据集的划分”了。这里其实对于这个术语的使用是不是需要那么严谨,我倒觉得没有那么大的关系,只要你能 get 到对方的意思就好。但是,核心是,训练,验证,测试,这三个数据集到底在做什么事情,一定要清楚。依然是,请回顾这个课程的 8-4,8-5,8-6 三个小节。
现在,如果你能理解什么叫“训练-验证数据集的划分”,已经这样划分以后,如何使用他们。那么,“交叉验证”就是替换“训练-验证数据集划分的一种方法”。
训练验证数据集是在训练集上训练,看验证集的得分;
交叉验证是先把整个数据分成 k 份,用 k - 1 份做训练,剩下的一份做验证,这样能得到 k 个得分,这 k 个得分取均值;
他们是在做同样一件事:看在某组超参数下模型的得分,只是方法不同。说白了,他们是上面我说的步骤 4)中的两种方法。(把数据扔给机器学习模型,也是有不同的“扔”法的。)
------
c)还有ROC曲线又是在哪个阶段画呢?
答:ROC 曲线是得分的一种,是一个指标。和准确率或者 r^2 一样。是来帮你判断你训练出来的模型好不好的。换句话说,是我上面说的步骤 4) 中,“得到结果”的部分。(一个模型的结果是多维度的。)
这个课程整个第十章,都在说一件事儿:如果我们只看准确率,是不够的。在机器学习领域,还有非常多的指标可以帮助我们判断我们的模型到底好不好。如果有需要,请回顾这个课程的第十章。关于机器学习指标的讨论,可以参考这里:https://coding.imooc.com/learn/questiondetail/G4daeR64dbG6nWEp.html
-----
d)以分类问题为例,数据处理好后,我是应该先试一下不同的分类模型(例如knn,决策树等),根据它们在测试集的得分如何(期间不断调参得到最高精度再比较),然后留下精度最高的几个模型(例如留下3个),最后用不同方法集成这3个模型,选择精度最高的集成方法,得出结论吗?
答:不一定。你相当于再说,分类问题一定要集成学习,但实际上不是这样的。集成学习可以尝试,但在很多时候,单一的算法就是足够好的。如果集成的算法不如某个单一算法,可能还会效果更差。可以参考这个问答下我对追问问题的回复:https://coding.imooc.com/learn/questiondetail/Ene1kYr2783YBD5q.html
-----
e)对于类别型特征,将它们编码后,训练模型前也需要将它们标准化吗?(假如有10个类别编号为0-9,标准化压缩到0-1之间后岂不是没有了意义?)
答:这就是一个典型的数据预处理的问题。
整体而言,对于类别型特征,不需要做标准化。但是,对类别型特征,有自己的处理方式。一个典型的处理方式就是 one-hot encoding,你可以在网上搜索了解一下。很好理解的。
但不管怎样,这就是我说的:特征工程其实还有很多东西需要学习的一个例子:)
----------
f)那我们难道需要将数据集不断标准化、还原、标准化。。。来测试不同的模型精度吗?
答:我不很确定你说的“还原”是什么意思。如果你说的是,在“这 A 模型中测试需要标准化”,在 B 模型中“不需要标准化”,所以你是先标准化,然后跑 A,跑完 A 以后,在把数据还原回去,喂给 B,那么你的实验过程是不优的。
简单来说,这就是 pipeline 的意义。正确的做法(或者是更好的做法)是,建立两个 pipeline,在 A pipeline 中,包含标准化这个步骤;在 B pipeline 中,不包含标准化的步骤。我们是同样的原始数据喂给两个 pipeline。我们要调整的是 pipeline,调整 pipeline 以后,每个 pipeline 自然会按照他们自己的逻辑调整数据,而不是你在外面手动不断地调整数据。
这其实是一个软件工程上的问题,而非算法问题。但在实践中,pipeline 的概念确实是非常重要的,所以我在这个课程中做了介绍:)
----------
g)这时候是不是标准化反而会降低模型精度?
答:这是一个非常非常重要的问题。在你学了这个课程的“过拟合”这一小节以后,就应该建立这样一个概念:机器学习追求的并非“精度最高”,因为只要你愿意,你总是可以在你的数据上,做出一个精度 100% 的模型,但是,这个模型并没有用,因为他过拟合了,无法泛化。
所以,做机器学习,首先是要做一个“可信”的模型。你的模型的精度可能并不高,但是,这个精度本身是可信的,是可以真实的反应这个模型面对未知数据时的准确度的。这一点至关重要。因为我们需要在“可信”的基础上做调整才有意义。举个不恰当的例子,在学习过程中,用作弊的方式拿到 100 分是没有意义;但是不作弊,就算拿到 40 分,没有及格,也是有意义的。因为我们就可以通过这个 40 分,分析出你到底有哪些知识点没有掌握,问题出在哪里。
所以,如果采取了某个“合理”的步骤,模型的精度反而降低了,这既正常,也并不可怕。关键是,这个步骤是否合理?你更相信有这个步骤的结果?还是没有这个步骤的结果?如果精度差异非常大,进一步找到为什么这个步骤会导致这么大的差异,也对之后进一步优化模型是非常有帮助的。
在大多数时候,标准化都是非常合理的一步。虽然有些算法不需要做标准化,但是做了标准化也不应该构成问题。对于连续性特征,我个人是倾向于建议对数据库做标准化的。非常巧,我最近还遇到了一个实际的研究案例,对数据做标准化和不做标准化的统计结果有显著的不同,我们的分析一直认为:我们应该相信对数据做标准化后的结论。
----------
似乎上面涵盖了你的所有问题了:)
继续加油!:)
412022-11-10
相似问题
回答 1
回答 2