因为是自己的学习笔记,方便自己理解,写得会比较细比较口语化,也有可能比较杂,不对的地方欢迎指正。
一,定义问题,确定任务类型,收集数据
具体的任务类型如分类或回归等不在此赘述。比较想提的一点是,如果是业务场景,该模型开发出来是给哪个部门提供支撑,一定要仔细商讨确定好,包括可用数据,最终目标等,在此基础上再去确定任务类型。
ps:对于非平稳问题,如建模对象随着时间推移而改变,利用最新数据重新训练是一般的做法,或者在更长的平稳时间段上收集数据,如一整年的(比如服装销量预测模型,在月维度上的数据的话就得不断利用最新数据重新训练,但若你能收集到以年维度的,就能维持模型一定的稳定性,不必每次重头训练)
二,确定衡量指标
要与业务目标一致,如最小风险损失还是最大精度?召回率还是准确率?在业务场景下,这同样应该是与支撑部门开会协商好。
三,确定验证方法
-
数据量大,用 留出验证法 。即留出一部分验证集,这种方法大部分情况下是足够应对的。
-
数据量小,精度要求不高,使用 k折交叉验证 。
-
数据量小,精度要求高,使用 重复的k折交叉验证 (比起第二种计算代价会激增。)
四,处理数据(特征工程)
特征工程,也就 是为数据寻找新的表示,让机器能够更加容易的 学习/识别 出模式。举个栗子,如果要根据时钟的图像让机器学习是几点钟,把整张图象的像素点直接输入模型虽然可以,但是如果你事先处理一下,用极坐标的方式来表达每个时针指向,再输入模型,学习效果无疑会好很多。一些常见特征工程流程包括数据清洗,处理,特征选择,特征构造和降维等,具体方法不在本篇讨论。
值得一提的是,对于神经网络,要做的数据预处理一般比较少,因为神经网络能够从数据中自动提取有用的特征(毕竟这就是权重更新的意义),但有的时候,我们仍需要进行特征工程,因为:
- 能够节省资源,比如上面提到的例子,把训练数据从整个图像的像素点,转换为只表示时钟指向的极坐标,这无疑会节省很多空间。
- 对数据量的要求会降低。还是上面的例子,如果你没转换,可能1000条数据作为样本输入模型训练,才能让模型达到你想要的精度,但如果你转换了,模式学习变得更容易了之后,可能200条就能达到同样的精度。(所以如果本身数据量就较少的情况,就一定要考虑进行特征工程。)
除此之外,神经网络的数据预处理一般就围绕3个方面:
- 把数据向量化(data vectorization),因为神经网络的所有输入和目标都是浮点数张量,所以这一步是必不可少的。如下所示:
为了形象展示我用excel列出来了,实际情况一般是这种形式:((A,B),(A,C,D))
通过向量化变为了2x4的向量(实际储存中下标当然不会存所以是2x4而不是2x5)。一般用one-hot实现。
2.数值标准化, 一般用 Standard Normalization 或者 Robust Normalization 就可以了。这么做是因为若把取值相对较大的数据或者异质数据(取值尺度不一样的数据,如一个特征取值范围0~1,一个0~100)输入神经网络,可能会导致较大的梯度更新,从而网络无法收敛。
3. 缺失值处理,一般把缺失值补0就可以了,神经网络会自动学习到为0的是缺失值。值得注意的是,如果测试数据中有缺失值,而训练数据里面没有,这个时候应该人为制造一些带缺失值的训练数据。
五,验证统计功效
以多分类任务为例,在这一步就是随便选择一个简单的模型,不做调参的直接用训练数据训练,然后用准确率与纯随机做对比,如果明显的表现出比纯随机好(即获得统计功效),那么就说我们的数据是和label相关的,可以用来训练,我们可以继续下一步了。反之则无关,可能需要获取一批新的数据或者直接获取新的特征了。
以10分类目标为例,随机的期望准确率应该是0.1,但如果你的训练出来一个准确率只有0.05的,恭喜你,重新准备数据吧,一切推倒重来。
ps:所以一些复杂的特征工程可以放在这一步之后,节省精力,但对于神经网络来说像向量化这种还是必须放在这一步之前,不然根本训练不了。
六,直奔过拟合
确定了具有统计功效之后,问题就变成了模型是否足够强大了。理想中的模型当然是在过拟合与欠拟合的边界上,而找这个边界的一般做法就是,先过拟合,再逐渐用正则化和调参,来慢慢回落到过拟合与欠拟合的边界。
普通的机器学习的话,这一步一般要根据 数据规模/特征数量/模型容量 等相关维度来综合考量选择哪一个模型(到底是随机森林还是lightGBM呢?),然后再调参到过拟合,再慢慢降。
深度学习的话,那就是尝试 更多层 / 每一层更多结点数 / 更多轮次 等方面来达到过拟合。
七,正则化与调超参数
- 这一步是最费时间的,要不停的调模型,训练,在验证集评估,直到模型的性能达到最佳。
有一点要注意,如果你采用留出验证法,那么仅仅调几次参还好,但如果你采用网格搜索等方式,尝试了很多次参数,那么你的模型会不可避免地被你带着往对验证集过拟合的方向走。毕竟你每一次调参,都是让模型在同一个验证集上的分数更高了,调次数多了难免会过拟合。这种时候就不要用留出验证法啦,用交叉k折验证比较好。
- 一旦调整好了,就可以用在全体数据(训练集+验证集)上训练,产生最终的模型。然后再用测试集来测试,如果测试集上的表现比验证集上相差很远,那么可能你的验证流程不靠谱(比如上面说的这种情况),就要要验证评估方法了。
ps:神经网络正则化常用的方式有,添加drop_out层,调整层数,添加L1或L2正则化,尝试不同的超参数(每层的结点个数或optimizer的学习率等)。