如果你还没有听说过数据科学,那一定是我疯了。各种培训、岗位、学校课程像雨后春笋一样遍地开花。每次我看到这些东西的样品时,我总是格外关注他们学习算法的细节。当然,了解回归、深度学习的工作原理是件很酷的事情,但是当你真正动手处理数据的时候你就会发现,可能有些其他的事情也同样重要,甚至更重要。
我真的不是在说这些课程的坏话。我在大学教了很多年的机器学习,教的东西始终都围绕着那些非常具体的算法模型。你可能非常了解支持向量机,高斯混合模型, K-均值聚类等等,但是只有当你开始准备硕士论文的时候,你才真的学会了如何正确的处理数据。
什么样的处理才算是正确的处理呢?为了目的不择手段?只要得到好的预测性能就万事大吉?事实确实如此,但是这么做的关键在于,你能确保未知数据也能有个不错的表现。就像我经常说的那样,你很容易就会受到它的蒙蔽,在分析训练结果的时候,轻易地就相信了你选择的方法。
因此,在这里我要分享我的三点经验,因为我发现书里很少会提到这些,但是他们真的很重要。
1.模型评价是关键
数据分析/机器学习/数据科学(或任何你能想到的领域)的主要目标,就是建立一个系统,要求它在预测未知数据上有良好的表现。区分监督学习(像分类)和无监督学习(如聚合)其实没有太大的意义,因为无论如何你总会找到办法来构建和设计你的数据集。方法行不行***还是得看它在未知数据上的表现,你得保证它能得出同你过去的训练集一样的结果。
初学者最常犯一个错误就是看到已知数据的表现,就想当然的认为未知数据也会一样。通常你会发现,现实是很骨感的。这里我们就只说监督学习,任务就是根据你的输入预测输出,例如把电子邮件分成垃圾邮件和非垃圾邮件。
如果你只考虑训练数据,通过让机器记住一切,很轻松的就能得到***的预测结果(除非这些数据自相矛盾)。这并不是什么新鲜事儿,人类自己就是这样的。还记得你学外语背单词的苦逼时光么,你必须检查单词字母的顺序,因为你的大脑需要按正确的顺序记住他们。
机器在存储和检索大量数据上的优势是人类拍马不及的。但这也带来了过拟合和泛化能力差的问题。
所以,一个好的评价方法是模拟未知数据的影响来分割数据,一部分用来训练,一部分用来检测效果。通常,用较大的训练集建模,然后用小的那部分进行预测,经过多次迭代来得到一个较稳定的模型。这个过程就是我们常说的交叉验证。
为了模拟未知数据的表现,把数据集分为两个部分,一部分用于训练,一部分用于预测。
就算我们这么做了,还是很有可能出问题,特别是在数据非平稳的时候,数据的潜在分布会随着时间变来变去。利用真实数据预测时经常会碰到这种情况,同样是销售数据,六月和七月的就可能差别巨大。
还有数据点间的相关性,如果你知道了一个数据点那么你肯定对另一个数据点也有了一些了解。好比股票价格,他们通常不会在两天之间任意的大幅波动,因此如果你胡乱的拆分训练/预测数据,就会破坏这种相关性。
每当出现这种情况,你得到的结果就会过于乐观,而你的模型似乎不打算在现实应用中也这么给你面子。最糟糕的情况就是,你千辛万苦终于说服人们认可你的方法,结果下水一试,它当掉了……
所以学习如何正确的进行模型评价是关键!
2.特征提取是天
学习一种新的算法感觉总是很棒,但现实是,最复杂的算法执行起来和那些老办法 几乎没什么两样,真正的区别在于原始数据的特征学习。
现在的模型功能看起来非常强大,随随便便就能处理成千上万的特征和数据点,其 实本质上并没聪明到哪里。特别是线性模型(像logistic回归或线性支持向量机),就是个傻乎乎的计算器。
这些模型确实很擅长在数据充足的情况下识别信息的特征,但是如果信息不充足,或者不能按线性组合的特征来表示,那基本就没什么可玩了。同样这些模型也不能通过“洞察”自行简化数据。
换句话说,你可以通过寻找合适的特征,来大量简化数据。坦白来讲,如果你能为想做预测的功能简化掉所有特征,那还有什么需要学习的呢?!这就是多么强大的特征提取啊!
这意味着两件事情:首先,你应该确保你确实掌握了这些几乎相同的方法中的一种,并且始终不抛弃它。你真的不需要同时掌握逻辑回归和线性支持向量机,你只要选择一个就够了。这些方法几乎都是相似的,关键的不同就在于底层模型。深度学习还有些特别的东西,但线性模型在表现能力上几乎都是相同的。虽然,训练时间、解决方案的稀疏度等可能会有些不同,但在大多数情况下你会得到相同的预测性能。
其次,你应该了解所有的特征工程。这是一门艺术,不幸的是,几乎所有的教科书都没有涵盖这一点,因为关于它的理论太少了。它的常规化就像我们的雾霾一样,还有很长的路要走。有时,特征需要取对数。每当降低一定的自由度,就是摆脱那些与预测任务不相关的数据,可以显著降低你所需的训练集数量。
有些情况下这种类型的转化会不可思议的简单。例如,如果你正在做手写字体识别,你就会发现有没有一个识别度高的颜色并不重要,你只要有一个背景和前景就OK了。
我知道,教科书往往将算法模型描述的异常强大,好像只要你把数据扔给模型,他们就会把一些都做了。从理论和***的数据源上看它可能是对的。但很遗憾,我们的时间和数据都是有限的,所以寻找包含信息大的特征是绝对有必要的。
3.最耗神的是模型选择,而不是数据集的大小
在大数据时代,很多你不想被人知道的事情都被你的主内存以数据集的方式***的记录下来。你的模型可能不需要花太多时间就能跑完这些数据,但是却要花费非常多的时间从原始数据中提取特征,利用交叉验证的方法来比较不同学习模型的渠道和参数。
为了选择合适的模型,你需要大量的组合参数,再利用备份数据来评估它的表现。
问题来了,组合参数的爆发式增长。如果你只有两个参数,可能只需要花费1分钟就能完成训练,并且得到性能的评估结果(用合适的评估像我上面说的那样)。但如果每个参数有5个候选值,那就需要执行5倍的交叉验证(把数据集分成5份,每个测试都跑5遍,在每一次迭代中用不同的数据测试),这意味着你需要把上面的步骤重复125次去找到一个好的模型,你要等待的就不是1分钟,而是两小时。
好消息是,在多参数的情况下你可以并行操作,因为每个部分都是独立运行的。这 种对每个独立数据集进行相同操作(分割,提取,转换等)的过程,被称为“密集并行”(没错,这是一个技术术语)。
这里的坏消息大多针对大数据,因为这些都意味着很少需要复杂模型的可扩展实现。在大多数情况下,仅仅通过对内存中的数据执行相同的非分布式算法,再把这种方法并行化就足够了。
当然,像用于TB级日志数据的广告优化和面向百万用户推荐的 learning global models这样的应用也是存在的,但是最常见的用例都是这里描述的类型。
***,拥有很多数据并不意味着你都需要他们。***的问题在于底层学习的复杂性。如果这个问题能被一个简单的模型解决,你就不需要用这么多的数据来检验模型,也许一个随机的数据子集就可以解决问题了。像我上面说的,一个好的特征表现能帮助你急剧的降低所需要数据点的量。
综上所述
总之,知道如何正确的评估,对降低你的模型在面对未知数据时的风险是非常有帮助的。掌握合适的特征提取方法,可能是帮助你取得一个好的结果的***方法,***,并没有那么多大数据,通过分布式计算可以降低训练时间。