第一章:初见竞赛
Andrew Ng说:机器学习在大多数时候就只是数学统计,数据相关的特征工程直接决定了模型的上限,而算法只是不断地去逼近这个上限而已。
Kaggle的开源社区很好用!各种工具和代码。我们可以将各种建模方法进行融合。“只要开源融合得好,得一块银牌不是问题。”
竞赛流程:问题建模;数据探索;特征工程;模型训练;模型融合。
第二章:问题建模
线上提交结果验证的次数往往有限。因此合理切分训练集和验证集,以及构建可信的线下验证就很重要。
2.1 赛题理解
2.11 业务背景
也就是用经济理性去理解x y。收集能影响y的所有重要变量x
2.12 数据理解
数据基础层:重点关注每个数据字段的来源,生产过程,取数逻辑,计算逻辑
数据描述层:做一些基本的统计分析:均值,最值,分布,增幅,趋势等等
2.13 评价指标
1. 分类指标
准确率 vs 召回率:
准确率 = TP / (TP+FP) 真正为阳性的案例占检测结果为阳性案例的比例;代表有多少阳性是真的,准确度的概念。
召回率 = TP / (TP + FN) 真正为阳性的案例占样本中所有阳性案例的比例;代表检测出多少阳性案例,(1-召回率)就是漏检率。
两者不可兼得,准确率越高,漏检率也会更高。二者不可兼得。
F1-score
用于均衡准确率和召回率的权衡取舍。两者的调和平均数。
ROC曲线
绘制采用不同分类阈值时候的TP和FP的关系图
AUC
ROC曲线下方的面积,由于ROC曲线都在y=x这条线上方,因此AUC取值范围是[0.5, 1]。AUC的好处是作为一个数值,比ROC曲线更为直观。
但AUC其实和模型预测的概率绝对值无关。它只关注样本间的排序结果。比如随机挑选一个正样本和负样本,AUC就是将正样本排在负样本前面的概率。
比起准确率召回率这些依赖分类阈值的指标。AUC是评价相对排序的指标,不依赖分类阈值,省去我们试探分类阈值的时间。直接评价模型的排序能力。
对数损失函数
直接评价模型的预测是否足够准确。常见的损失函数。
2. 回归指标
平均绝对误差MAE (mean absolute error) 也称L1范数损失
不光滑导致不可导,一般不用。但在XGBoost里面可以用,不过一般我们会用Huber损失函数。(结合了MAE和MSE的优点)
均方误差MSE(mean sequared error) 也称L2范数损失
取二次方后可导。不过为了量纲一致,会再开方,产生均方根误差RMSE(root mean sequared error)。
不过MSE RMSE也有缺点,容易被极端值影响。
平均绝对百分比误差MAPE(mean absolute percentage error)
与MAE类似,不过将绝对误差除以yi,变成百分比的形式。
2.2 样本选择
2.2.1 主要问题
数据质量经常成为影响模型表现的因素。主要有以下四大问题:
1. 数据集过大影响模型性能
当计算资源有限的时候,需要考虑数据采样处理,在小数据集上建模分析
2. 噪声和异常数据导致模型准确度不高
x的噪声分为两类:一是x输入错误,这是大问题,会导致内生性,需要处理;二是x的自然波动。
错误输入的X必须先处理。剩下的白噪声其实会让模型更稳健,让模型的泛化性能更好。
3. 冗余和不相关的特征没有给模型带来收益
冗余和不相关的特征丢掉就好。加入没有收益,反而可能导致共线性或内生性等问题。
4. 正负样本分布不均衡导致数据存在倾斜
大部分竞赛,主办方都是从真实数据中提取一部分出来,并且保证数据分布的一致性。如果真不均衡,可以自行抽取一个训练集来近似总体分布。通过不断改变样本的分布来适应模型训练与学习。
2.2.2 解决方法
数据集过大问题
1. 简单的随机抽样:有放回和无放回
2. 分层采样:在每个类别里面,按照规定比例随机抽样。优点:样本代表性好,抽样误差小。
正负样本不均衡问题
应用场景:1.如果对召回率有要求。那意味着对阳性案例的预测的远比阴性案例更重要。那这时候就需要处理了,否则很难获得良好的建模结果。
2. 如果评价指标是AUC,那是否处理差别不大。3. 如果正样本和负样本同样重要,那是否处理也差别不大。
评分加权处理:直观理解就是阳性样本的价值大于阴性样本,因此希望模型能从阳性样本上学到更多关键信息,如果学得不好,就给更大惩罚。
欠采样:从数量较多的那一类样本中选择一部分删除。
过采样:对样本较少的类别重新组合,构建新样本。
2.3 线下评估策略
为了做线下验证,必须留一部分数据做测试数据。
强时序数据:用最后一个月的数据做验证集(20%左右)
弱时序数据:数据分5份。4份用来训练,1份用来test。训练出5个模型,然后合并。
Andrew的建议是 6 2 2 训练集,cross validation, test set
第三章:数据探索
3.1 数据初探
数据倾斜,异常值和过多缺失值可能导致一些不好的结果:1. 模型不准确 2. 生成基于错误数据的精确模型 3. 为模型选择错误的变量
数据探索阶段必须做的七件事情:
1. 数据基本情况:比如数据大小,各个字段信息
2. 处理重复值,缺失值,和异常值
3. 特征之间是否冗余(共线性)
4. 是否为时序。如果时序,需要进行相关性,趋势性,周期性和异常点的分析。还要小心未来信息。
5. 标签分布:对于分类问题,是否存在类别分布不均衡
6. 训练集和测试集的分布:是否分布一致,信息一致
7. 单变量/多变量分布:熟悉特征的分布
3.2 变量分析
单变量分析:查看基本信息,画直方图,看是否有极端值,是否符合正态分布等。除去极端值,正态分布的变量会更容易学习。
相关性分析:可以生成相似性矩阵。
一是移除共线性过强的变量(因为会让训练时间过长)
二是寻找xy之间相关性的强弱。对于与y相关性很弱的x,可以考虑去处,在竞赛中一般有很好的结果。
分类数据:类别变量可以考虑与其他变量生成交叉项,比如性别这个变量。
多变量分析
3.3 模型分析
3.3.1 学习曲线
学习曲线显示了模型在不同迭代次数下的性能表现。横轴表示迭代次数,纵轴表示模型的性能指标。
欠拟合 VS 过拟合
3.3.2 特征重要性分析
对于树模型,可以计算特征在模型中的重要性,可以起到选择特征的作用。反直觉的特征有可能是过拟合。
3.3.3 误差分析
可以做的很细致,看错误的案例的问题在哪里。Andrew讲了很多这部分。
第四章:特征工程
4.1 数据预处理
4.1.1 缺失值处理
XGBoost 和 LightGBM 这两个树算法可以直接处理缺失值,其他算法都要对缺失值做预处理。
找出缺失值:除了缺失标签外,还有些数据用-1 -999 来表示缺失值
处理方法:
1. 最基本的是均值填充,但对极端值比较敏感,中位数填充就对计算值不敏感。
2. 类别变量:可以用众数填充,也可以填一个新类别。
3. 时序变量:可以用这个观测值的前一期或者后一期填充。
4.1.2 异常值处理
异常值主要是极端值和不合常理的值。
找出异常值:可以画分布图,散点图,找出离群的异常值。也可以用基本的统计量来找出来,比如四分位间距,极差,均差,标准差等。
处理方法:
1. 直接删除异常值的观测点。缺点是会损失样本量。
2. 将异常值等同缺失值处理。缺点是可能影响数据的准确性。
4.1.3 优化内存
内存回收机制:用python的gc.collect()来释放内存
数值类型优化:浮点数常常内存占用太多,可以将其最小值最大值归一化,然后乘100 、1000后取整
4.2 特征变换
4.2.1 连续变量无量纲化
这是线性回归,神经网络和KNN的关键,但决策树模型没有影响。
标准化 和 区间缩放 两种方法
4.2.2 连续变量的转化
对数化:多数机器学习模型不能很好地处理非正态数据。取对数可以让数据更正态,压缩了尺寸,让数据更平稳,还削弱了共线性异方差等。
离散化:把连续数据做成分组数据,可以使数据平滑,降低噪声的影响。
无监督的离散化有 等频 等距 两种方式
有监督的离散化 使用树模型返回叶子节点来进行离散化
4.2.3 类别变量的转化
有顺序关系的类别特征可以用自然数编码
无顺序关系时,用独热编码
4.3 特征提取
机器学习模型很难识别到复杂的模式,特别是不同变量的交叉项的信息。所以我们可以根据经济理性创建一些特征来帮助模型学习。
4.3.1 类别变量的统计特征
对于每个类别,可以构造一些连续型的统计特征:最常用的是count, nunique, ratio
类别特征之间还能交叉组合,但要有经济理性
4.3.2 数值相关的统计特征
数值变量之间的交叉组合,可以加减乘除(要经济理性)
类别特征和数值特征之间的组合
按照行(观测点)统计相关特征
4.3.3 时间特征
除了基本的时间特征,还可以计算每一个观测样本在不同时间的数值不同(时间差特征)
4.3.4 多值特征
某些变量包含多个属性,就叫做多值特征。处理方法就是展开,把n个属性展开成n维稀疏矩阵。
4.4 特征选择
当我们需要添加新特征时,需要验证它是否能够提高模型预测的准确度。所以我们需要用特征选择算法删除不相关和冗余的特征。
4.4.1 先验的特征关联性
考虑自变量和应变量的相关性
皮尔森相关系数:除了衡量自变量和应变量的相关性;还可以删除共线性高的自变量。
卡方检验:检验自变量和应变量的相关性
相互信息法
4.4.2 后验的重要性分析
基于树模型的评估特征的重要性分数:gain计算方式 cover计算方式
4.4.3 使用封装好的方法
启发式方法:向前搜索和向后搜索,比较耗时,消耗资源,不推荐
递归消除特征法:使用一个基模型来进行多轮训练,每次训练都会先消除若干权值系数的特征,再基于新的特征集进行下一轮训练。
tips:使用这些封装好的方法选特征的时候,不要用全量数据,抽一个小数据集出来会更好。
null importance方法:将构建好的特征和y喂给模型,得到特征的重要性分数。再将y打乱,也会得到一个重要性分数。两者比较,如果前者没有超过后者,就是无用的特征。
第五章:模型训练
模型主要是线性模型,树模型,神经网络三种
5.1 线性模型
Lasso回归 VS 岭回归
两者唯一的区别在于正则项。前者是L1范数,后者是L2范数。
当存在强共线性变量时,Lasso回归只保留其中一个特征,其他特征设置为0。缺点是可能丢失信息。
而岭回归,并不会降低特征的数量,只是让系数变小。缺点是不利于特征的筛减。
5.2 树模型
可以分为随机森林和梯度提升树(XGBoost, LightGBM, CatBoost)
5.2.1 随机森林
我们可以把随机森林里面的树想象成一群聪明的小朋友,他们每个人都试着回答同一个问题,然后大家一起投票来决定最终的答案。这也是最简单的Bagging思想。
流程如下:
1. 数据抽样:从原始数据集中通过有放回的抽样(即bootstrap抽样)生成多个子集。每个子集的大小和原始数据集一样大,但其中的样本是随机选出的,可能包含重复的样本。
2. 特征选择:对于每棵决策树,从所有特征中随机选择一部分特征(sqrt(M))。
3. 生成决策树:根据这些随机抽样的数据和特征,生成一棵决策树。
重复上述步骤,生成很多棵不同的决策树。然后汇总所有决策树的预测。
优点:不容易过拟合。缺点:计算成本更高,不过天然的并行特征,在分布式环境下可以很快训练
5.2.2 梯度提升树
基本原理:每个新的决策树都试图纠正之前模型的错误,逐渐减少预测误差。
数学原理:可以推导出梯度提升树的最优化目标函数,只依赖每个数据点在误差函数上的一阶导和二阶导。
5.2.3 XGBoost
XGBoost的核心是基于梯度提升方法,即通过逐步添加新的树来修正前一步模型的误差。每一棵新树都基于之前所有树的误差梯度进行训练,从而逐步提升整体模型的精度。
具体步骤:
初始化模型:以一个简单的模型开始。
计算残差:根据当前模型预测的误差,计算残差。
训练新树:利用残差训练新的决策树。
更新模型:将新树的预测结果加到现有模型中。
重复步骤2-4,直到达到预定的树的数量或其他停止条件。
关键特点:
并行处理:支持并行计算,提高训练速度。
正则化:通过L1和L2正则化防止过拟合。
二次泰勒展开:使用二次泰勒展开对损失函数进行近似,提高优化效率。
缺失值处理:自动处理缺失值,能够对缺失值进行分支。
5.2.4 LightGBM
LightGBM,专注于提高训练速度和效率,特别适用于大规模数据集。Leaf-wise生长,算深度优先搜索;而XGBoost Level-wise生长,算广度优先搜索。
具体步骤
初始化模型:以一个简单模型开始。
计算残差:用当前模型计算每个样本的预测误差。
拟合新树:训练一个新的决策树来拟合这些残差,使用leaf-wise策略选择误差最大的叶子节点进行分裂。
更新模型:将新树的预测结果加到现有模型上。
重复步骤2-4,直到达到预设的树数量或误差收敛。
关键特点
Leaf-wise生长策略:能够更好地减少误差。
直方图算法:通过将连续特征值离散化为直方图,加速了计算。
GOSS(Gradient-based One-Side Sampling):对梯度较大的数据进行优先采样,提高训练效率。
EFB(Exclusive Feature Bundling):将互斥的特征捆绑在一起,减少特征维度,提高效率。
5.2.5 CatBoost
CatBoost(Categorical Boosting)特别优化了类别特征的处理,适用于包含大量类别特征的数据集。
一个强大的功能是:在树分裂选择节点的时候,能够将所有类别特征之间的组合考虑进来。
具体步骤
初始化模型:以一个简单模型开始。
计算残差:用当前模型计算每个样本的预测误差(残差)。
拟合新树:训练一个新的决策树来拟合这些残差,使用顺序Boosting,通过随机排列数据并使用每个样本的先验信息,减少过拟合。
更新模型:将新树的预测结果加到现有模型上。
重复步骤2-4,直到达到预设的树数量或误差收敛。
关键特点
高效处理类别特征:自动处理类别特征,无需预处理或编码。
顺序Boosting:通过随机排列数据并使用每个样本的先验信息,避免常见的过拟合问题。
对称树结构:提高训练和预测效率。
内部处理缺失值:自动处理缺失值,简化数据预处理。
5.2.6 三个模型的比较
相似点
Boosting框架:三者都是基于Boosting框架,通过多棵决策树的加权组合来提高预测性能。
高效处理:都强调训练速度和效率,通过各种优化技术(如并行处理、特征捆绑等)来加速计算。
内部处理缺失值:自动处理数据中的缺失值,简化数据预处理。
不同点
树的生长策略:
XGBoost:采用level-wise生长策略。(可以同时分裂同一层叶子,不容易过拟合。但很多叶节点的分裂增益低,影响性能)
LightGBM:采用leaf-wise生长策略,能够更好地减少误差。(可能会长出非常深的决策树,从而导致过拟合。用参数max_depth防止过拟合)
CatBoost:采用对称树结构,提高训练和预测效率。(这种结构起到了正则化的作用,不容易过拟合)
类别特征处理:
XGBoost:需要手动对类别特征进行编码处理。
LightGBM:对类别特征有一定的支持,不需要独热展开,但仍需要一些预处理。
CatBoost:专门针对类别特征进行了优化,能够自动处理。
优化技术:
XGBoost:使用二次泰勒展开和正则化。
LightGBM:使用直方图算法、GOSS、EFB等技术。
CatBoost:使用顺序Boosting和对称树结构。
优劣
XGBoost:
优点:成熟稳定,广泛使用,具有丰富的功能和参数调节选项。
缺点:对类别特征处理不如CatBoost方便,训练速度相对较慢。
LightGBM:
优点:训练速度快,特别适用于大数据集,leaf-wise策略能够更好地减少误差。
缺点:对类别特征的处理较为有限。
CatBoost:
优点:对类别特征处理非常友好,适合包含大量类别特征的数据集,顺序Boosting减少过拟合。
缺点:在某些情况下,训练速度可能不如LightGBM快。
总的来说,选择哪种模型取决于具体的数据和需求。对于包含大量类别特征的数据集,CatBoost可能是最佳选择;对于大数据集和需要高效训练的场景,LightGBM可能更合适;如果需要成熟稳定的解决方案,XGBoost是一个不错的选择。
重要参数输入
见p73
5.3 神经网络
神经网络是一种模拟人脑神经元互联的计算模型。它们由多个层级的节点(或称为“神经元”)组成,每个节点之间通过连接(权重)相互作用。
基本原理
输入层:接收输入数据,每个节点对应一个输入特征。
隐藏层:通过权重和激活函数对输入数据进行非线性变换,提取特征。可以有多个隐藏层,每层包含若干个节点。
输出层:根据前一层的输出,生成最终的预测结果或分类。
向前传播(Forward Propagation): 是指数据从输入层经过隐藏层到达输出层的过程。在这个过程中,数据通过层与层之间的权重(系数)进行传递,并应用激活函数进行非线性变换。最终在输出层,输出预测结果。
向后传播(Backward Propagation):是指通过计算预测输出与真实值之间的误差,反向调整系数,使得模型的预测误差最小化的过程。先计算输出层误差,利用输出层误差往回计算隐藏层误差,然后更新系数。
5.3.1 卷积神经网络
卷积神经网络(Convolutional Neural Networks,简称 CNN)是一种专门用于处理具有网格状拓扑结构数据(如图像)的深度学习模型。它们通过局部连接和共享权重的方式,能够有效地捕捉数据中的空间或时序依赖关系。CNN 在计算机视觉领域取得了显著成功,被广泛应用于图像分类、目标检测和语义分割等任务。
CNN 主要由以下几种层次组成:
卷积层(Convolutional Layer):
卷积操作:通过卷积核(filter 或 kernel)在实际图像上滑动,计算每个位置上的卷积和,从而提取局部特征。
输出特征图(Feature Map):每个卷积核生成一个特征图,多个卷积核生成多个特征图。
池化层(Pooling Layer):
最大池化(Max Pooling):取局部区域内的最大值,减少特征图的尺寸,同时保留重要信息。
平均池化(Average Pooling):取局部区域内的平均值,同样用于减少特征图的尺寸。
全连接层(Fully Connected Layer):
类似于传统神经网络的全连接层,将池化层或卷积层的输出展开成一个向量,并通过全连接层进行分类或回归任务。
归一化层(Normalization Layer):
批量归一化(Batch Normalization):对每个批次的数据进行归一化处理,加速训练过程并稳定模型训练。
卷积神经网络的工作原理
输入层:接收输入数据(如图像),通常是一个三维张量(宽度、高度、通道数)。
卷积层:通过多个卷积核对输入数据进行卷积操作,提取局部特征。
激活函数:对卷积层的输出应用激活函数,如 ReLU
池化层:对卷积层输出的特征图进行下采样,减小尺寸并保留重要特征。
全连接层:将卷积层或池化层的输出展开成一维向量,经过若干个全连接层进行分类或回归任务,这部分和传统的神经网络一样。
输出层:根据任务需求,输出分类概率或回归结果。
卷积神经网络的特点和优势
局部感受野(Local Receptive Field):卷积核只与局部区域连接政府,提高了特征提取的效率和模型的鲁棒性。
参数共享:同一卷积核在不同位置共享参数,减少了参数数量,降低了模型复杂度。
平移不变性(Translation Invariance):卷积操作能够捕捉平移不变的特征,使模型对输入图像的平移更加鲁棒。
5.3.1 循环神经网络
循环神经网络(Recurrent Neural Networks,简称 RNN)是一种用于处理序列数据的神经网络结构,广泛应用于自然语言处理、时间序列预测和语音识别等领域。RNN 能够捕捉数据的时序依赖关系,适合处理序列中的上下文信息。
RNN 的原理
RNN 与传统的前馈神经网络不同,其隐藏层的输出不仅依赖于当前的输入,还依赖于之前的隐藏状态。这种结构使得 RNN 能够在时间序列数据中捕捉到长期依赖关系。
在每个时间步 t (也称为帧),循环神经元接收输入 Xt,以及它自己在前一时间步的隐藏状态 Ht-1,输出Ht。
尽管 RNN 能够处理序列数据,但其在处理长序列时存在梯度消失和梯度爆炸问题,导致模型难以捕捉到长期依赖关系。