首席数据分析师教你怎么一步步提升Kaggle竞赛模型的精确度
作者:Werner Chao
翻译:白静
术语校对:黄凯波
本文长度为2800字,建议阅读8分钟
线上心理健康公司KaJin Health首席数据分析师教你怎么一步步提升Kaggle竞赛模型的精确度。
最近,Kaggle竞赛非常受欢迎,很多人都试图获得好成绩。但是,这些竞赛竞争十分激烈,获胜者通常不会透露其方法。通常情况下,获胜者只会写一个他们所做的事情的简单概述,而不会透露很多,所以用何种方法可用的提高模型精确度仍是一个谜。
这篇博文介绍了如何在Kaggle竞赛中提高模型精确度。我将分享一些如何获得较高分数且排名相对靠前(达到前10%)的步骤。这篇博文结构如下:
1. 数据探索(Data Exploratory)
1.1 数值数据(Numerical Data)
1.2 分类数据(Categorical Data)
2. 模型建立(Model Building)
2.1 线性回归(Linear Regression)
2.2 LASSO回归(Lasso Regression)
2.3岭回归(Ridge Regression)
2.3.1 数据转换(Data Transformation)
2.4 随机森林(Random Forest)
2.5 梯度推进器1(Gradient Boosting Machine)
2.6 神经网络(Neural Network)
2.7 叠加模型(Stacking Models)
1. 数据探索(Data Exploratory)
1.1 数值数据(Numerical Data)
首先,我们迅速浏览一下数据。这里有14组连续(数值)特征。令人感到意外的是,这些数据相当整齐。看以下两个图表,如果我们注意到平均数和标准差,会发现平均数在0.5左右,标准差在0.2上下。这意味着这些数据已经被转换过了。
接下来,我们将为这14组连续特征绘制直方图,这里我们要注意的是特征“cont7”和“cont9”左偏。
损失(Loss)变量的绘制情况并不好,因此我们为其绘制一个单独的直方图,发现损失变量也是左偏。
为了查明这些变量的偏斜程度,我们计算了偏斜度。“cont7”“cont9”和“损失”这三个变量的偏斜程度最高。
如果进一步绘制一个箱线图,我们会再次发现“cont7”和“cont9”有很多离群值。如果我们尝试修正偏斜度,可能会减少离群值的数量。
在此,我们将尝试三种转换类型,对它们进行比较,找出效果最好的一种,这三种转换类型分别是:对数(log)、开平方根(sqrt)和Boxcox转换。
我们能够清楚地发现Boxcox变换对这三种情况都起作用。但是我们不能将Boxcox变换用在“损失”(Loss)变量上,因为目前在Python里,没有撤销Boxcox的功能。因此,我们无法做到:在预测之后将“损失” (Loss)转换回去,再计算平均绝对误差(mean absolute error)。随后,我们将使用对数(log)来转换“损失”(Loss)变量。
1.2 分类特征(Categorical Features)
对于分类特征,我们可以绘制频率图。关于分类特征的几个要点如下:
类别标签A、B只与分类特征1到分类特征72有关;
73-78特征描述了两个以上的类别;
109-116特征表达了多种类别。
这里有几幅采样频率图来证明以上三点:
2. 模型建立(Model Building)
2.1 线性回归(Linear Regression)
分析完连续特征和分类特征之后,我们就可以开始建立模型了。要注意的是这个数据集非常完整,没有任何缺失数据。这里我们将要做的是建立一个工作流程,首先输入原始数据,然后随着我们对数据进行不同转换,可以将新模型与基准模型(原始数据案例)进行比较。原始数据案例是未经转换的连续特征和虚拟编码特征。至少,我们必须对分类数据做虚拟编码,这是因为sklearn模型不允许观察数据中有字符串。
我们可以拟合一个如下所示的线性回归:
如上所示,测试得分远大于训练得分。这意味着训练集过拟合。关于这个估计需要说明的一点是:我们正在使用平均绝对误差,这里这个值是负数是因为sklearn使其成为负值。所以当我们降低这个误差时(调整模型使误差更接近零),看起来却像是在提高分数(即:-1﹣(-2)=1,因此新成绩比以前的成绩高了1分)
2.2 LASSO回归(Lasso Regression)
很明显我们需要一个正则化,因此将使用Lasso回归。记住,Lasso回归只是线性回归加一个正则化项。我们可以在下面看到一个5折的交叉验证。我们得到的交叉验证分数大约为1300,接近之前线性回归1288的分数。这意味着我们处在正确的轨道上!虽然三种不同的情况产生的结果非常接近,但注意下面的网格搜索告诉我们最好的alpha是0.1.
2.3 岭回归(Ridge Regression)
另一个易于使用的正则化是岭回归。由于我们已经知道Lasso回归的效果很好,所以这个数据集很有可能是一个线性问题,我们将使用岭回归来解决这个问题。
2.3.1 数据转换(Data Transformation)
现在有了工作流程设置,我们将使用岭回归来检测不同的数据转换,探究哪种转换能得出最好的结果。记得之前我们已经对特征“cont7”和“cont9”进行了boxcox转换,但是并未真正实行(直到现在我们使用的一直是原始连续特征和独热编码分类特征)。现在我们将实行这个转换。
我们将实施并比较这些转换:
原始(数值/连续特征)+虚拟编码(分类特征)
Raw (numerical/continuous features) + Dummy Encode (categorical features)
归一化(数值)+虚拟(分类)
Normalized (num) + Dum (cat)
Boxcox转换&归一化(数值)+虚拟(分类)
Boxcox Transformed & Normalized (Num) + Dum (cat)
Box&范数(数值)+虚拟(分类)+log1(损失变量)
Box & Norm (num) + Dum (cat) + Log1 (Loss variable)
下表并列比较了交叉验证的误差,我们发现使用损失(目标)变量的对数得到了最好的结果。
2.4 随机森林(Random Forest)
现在我们已经进行了转换,并且知道这个问题是一个线性案例,我们可以转向更复杂的模型,比如,随机森林。
我们马上发现交叉验证得分从1251(来自岭回归)改进到1197。
2.5 梯度推进器(Gradient Boosting Machine)
我们将进一步采用更加高级的模型——梯度推进器(Gradient Boosting Machine)。这个程序库被称为极端梯度提升2(Xgboost),因为它优化了梯度推进算法。在此,我将分享优化过的超参数。调整极端梯度提升(Xgboost)是一门耗时的艺术,因此我们不在这里谈论。这篇博文论述的是一种循序渐进的方法,我将简要介绍这里采取的一般步骤:
1. 推测学习率和n_estimator
Guess learning_rate & n_estimator
2. 交叉验证调整min_child_weight和max_depth
Cross validate to tune for min_child_weight & max_depth
3. 交叉验证调整colsample_bytree和subsample
Cross validate to tune for colsample_bytree & subsample
4. 交叉验证调整gamma
Cross validate to tune for gamma
5. 降低学习率并调整n_estimator
Decrease learning_rate & tune for n_estimator
通过使用这些参数,我们能够得到的交叉验证分数为1150——再次改进了误差!
2.6 神经网络(Neural Network)
我们也将使用神经网络来拟合这个数据集。如今,不使用神经网络几乎不可能赢得竞赛。
神经网络的主要问题是它很难调整、也很难知道有多少层次、要使用多少隐藏节点。我的做法是先从单层开始,并且我使用的隐藏节点的数量是特征数量的两倍,然后慢慢增加更多的层次,最后我得到了如下结构。我用Keras作为前端,Tensorflow作为后端。在这个模型中,我得到的交叉验证分数是1115。
因此,可比较不同的模型:
2.7 叠加模型(Stacking Models)
还记得我们的初始平均绝对误差是1300吗?我们已经将这一误差改进了14%,数值降至1115。然而单一模型并不能让你在Kaggle竞赛中取得好名次,我们需要叠加模型。
叠加模型的概念是每个模型在什么情况下运行良好,就采用其最好部分。这篇博文一个扩展的指南和解释。
简化版本如下:
将训练集分割成几份(在我的案例中分成了5份);
在不同份数下训练每个模型,并对分割的训练数据进行预测;
设置一个简单的机器学习算法,如线性回归;
使用每个模型训练的权重作为线性回归的特征;
使用原始数据训练集目标作为线性回归的目标。
为了更容易理解上述步骤,我创建了下表:
我的叠加代码在Github存储库中。我叠加了两个最好的模型: 极端梯度提升(Xgboost)和神经网络。
提交我的叠加模型之后,我的测试得分为1115.75.
通过排行榜可以得知,如果我在竞赛结束之前提交模型,1115.75在3055个团队中大概排名326,你可以通过Kaggle排行榜链接进行查证,大概排在前10%到11%。
1.译者注:又译“梯度提升机”。
2.译者注:XGBoost是“极端梯度提升”(eXtreme Gradient Boosting)的简称,XGBoost源于梯度提升框架,但是更加高效。XGBoost已屡屡斩获Kaggle各项竞赛的冠军宝座。