天天看点

Kaggle Animal Shelter Outcome整个流程

本文主要对Kaggle的一个比赛项目,进行了分析说明,希望能够查找到原因,提高数据分析的能力。

具体项目要求及数据请看[这里]

简而言之这是一个多分类的问题,并需要计算出属于各个类的概率,项目评判的标准是交叉熵(Cross Entropy)最小。

1、数据的加载与清洗

由于所给数据为csv格式,而且还有header选择使用了pandas中的read_csv函数作为加载数据的函数,具体代码如下:

animals = pd.read_csv('D://shelter/train.csv') p_animals = pd.read_csv('D://shelter/test.csv')

观察数据不难发现其中有不少数据缺失的情况,暂且先不考虑,提取特征的时候予以重点考虑。

2、特征提取

最开始时对这块儿不太重视,只想套用模型计算结果,后来发现特征提取(或称之为特征工程)可以说是最关键的一步。好的特征 + 简单的模型 >> 一般的特征 + 高级模型,这个方面会在后文详细介绍。

  • 分析AnimalID,每一个Animal有唯一的ID,因此这一特征可以删除,不用考虑;
  • 分析Name这一列特征,可以发现有很多缺失数据,也就是说有些动物可能没有名字,最开始的 时候我直接把这一行数据弃用了;后来发现这是一个很大的错误,因为有名字的动物可能以前已经被收养过,而没有名字的动物,可能以前没有被收养过(当然也可能存在漏统计等因素),但不管怎么说我们从实际出发, 这个特征可能会对流浪动物的去向有影响,这点需要注意的是我们再最初筛选特征时,宁可多加特征,也不要漏加特征,也就是说,只要我们觉得特征对预测结果有影响,我们就应该把该特征加入训练集(即便该特征并没有那么重要,我们也可以在全部特征构造完成后,通过查看特征的重要性去删除一些不必要的特征),说到这里,我们就在训练集加入了一列特征HasName;
  • 分析DateTime这一列特征,这列特征处理起来是比较让我头疼的,因为时间特征的处理可以变幻出很多的特征,很需要自己的imagination,考虑到实际情况,对于这列我的处理是把其拆成了year、month、weekday(即该天是周几),早上(7~11点钟),中午(11~14点钟),下午(14~19点钟),晚上(19~7)点钟,总之对于时间特征的处理还有很多地方需要深入的学习。
  • 对于流浪动物去向类型,有四类, Return_to_owner(返回主人,该种情况可能是动物丢失)、Euthanasia(安乐死)、Transfer(转移)、Adoption(收养)这4类,而这正是需要我们想要通过测试集的特征,预测的4种情况,相当于Target。然后还有一列特征是去向的子特征,比如对于Euthanasia,可能的子类型是Suffering(遭遇痛苦),这一列我个人觉得没有利用的价值(因为项目要求不需要预测子类型),所以没有用。
  • AnimalType有两种猫和狗,这列特征不用多说,处理起来很简单。
  • 对于SexuponOutcome这一列,由于之前对流浪动物不太了解,不太重视这个特征。后来发现,是很重要的这个特征分为Neutered Male(已阉割的雄性)、Sprayed Female(不能生育的雌性)、Intact Male(未阉割的雄性)和Intact Female(能够生育的雌性)、Unknown(未知)。比如收养的动物里边有很多可能是不能生育的雌性,因此这个特征对于预测来讲很重要,将这列特征划分为2个特征Sex(Male or Female or unKnown)、IsIntact(Yes or No or unknown);
  • AgeUponOutcome即出现该结果时动物的年龄,根据实际情况,人们可能更偏重于去收养一些年龄较小的动物,而一些年龄较大的动物可能会Euthanasia、一些年龄适中的动物可能会更偏向于重新返回主人身边。由于这些动物的年龄从days到10years不等考虑将特征用days表示;

    -Breed,我把他理解为出现结果前,流浪动物所在的流浪动物收容所或商店。这个特征对结果的影响可能在于,对于大型的流浪动物收容所,可能收养的概率会更高些;但该列特征处理起来相当麻烦,因为预测时会发现有一些流浪所或商店在训练集中根本没有出现过,而且流浪所或商店数目众多,这就造成特征的维度过高或者数据分支过细,都不利于模型的训练。最终我没有将流浪所和商店的名字作为一个特征,而是将该流浪动物是否曾在多个流浪所或商店转移过。构造出了IsMix这一列特征。

    -Color,即动物的颜色。虽说每个人都有自己喜欢的颜色,但毕竟有一个词语叫大众审美,说明我们人类对一些美丑还是有共识的通过查看数据我们一可以发现,那些白色、黑色、灰色的动物更容易被收养

    还有就是动物是纯色还是杂色的区别;由于训练集中的颜色众多,全部作为特征可能维度太高,我对于这些颜色的特征的处理是,选出大众颜色即这些颜色在较多的训练集动物中出现过,当然在测试集中我们也能发现,测试集中的有些颜色可能是训练中所没有的(我是没有理睬这些颜色,1是这些颜色毕竟占少数。其次这些颜色由于训练集中没有出现,根本没有合适的方法处理(至少我没有)),因此通过这一列数据分裂了60多种颜色特征和IsMix(是否是混合色)这接近70维的特征。

4、模型的训练

a、朴素贝叶斯

刚开始尝试的第一个模型就是朴素贝叶斯,因为我发现特征有很多都是离散的,对于处理离散特征,朴素贝叶斯的效果还是可以的,而且算法复杂度低,程序运行时间很快。可是结果并不理想,交叉熵达到了1.8左右,这是很大的一个值。后来调整Alpha的参数效果也不理想。于是,分析了一下原因,可能是年龄这一列特征种类太多,离散程度比较小吧,所以放弃了该方法。

b、随机森林

随机森林可以处理离散和连续的特征,因此理论上来说很适合处理该数据。用了随机森林的默认参数进行尝试,结果效果并不好。结果对相关参数进行了调整包括n_estimator (即树的数量)、分裂特征时所考虑的最大特征数量(max_features)以及最小叶子节点的数量。利用Grid Search进行搜索,结果发现最小叶子数量对结果的影响挺大的,默认为1,当把其调整到2时,结果出现了巨大的提升,交叉熵降为了0.83左右,所以说过拟合对结果的影响还是挺严重的。

c、提升树(GBDT)

记得在某个地方看到过,说GBDT在一般情况下和RF的效果不会相差太多,但由于利用随机森林的方法,没有什么提升,就想尝试了一下,GBDT在调参时和RF是十分类似的毕竟都是CART tree的组合模型,尝过之后效果果然和RF没有太大区别,只稍微提升了一点点。

d、bagging(投票)

既然RF和GBDT效果相当,那么将他们两者的概率结果取bagging回怎么杨呢,我也尝试了一下,但是效果很类似。

e、其他方法

尝试了logistics Regression、Softmax、SVM、ANN,几乎把比较主流的多分类方法都尝试了一遍,但效果还是不甚理想,其实后来想想叶挺然亦理解,毕竟这些方法很多都需要处理连续的特征,对于离线特征的效果自然不会好。但神经网络除外,神经网络的调参是比较难的,隐含层的个数的确定是一个难题、而且由于是非凸优化,存在多个极值点,因此很容易陷入局部最优解。

4、几点感悟

a、特征工程是重中之重,还是前面提到的,特征的提取做的好的话,就相当于成功了一半,甚至还要多。但难就难在特征提取没有统一的范式,需要自己去仔细思考,有时甚至需要自己的相关的专业知识和一些常识。可能只有通过不断的去总结经验才可以吧。

b、其次,参数的调节也是很重要的,像在RF里将最小叶子节点从1调整到2,交叉熵几乎减小了1半。很多人可能会觉得调参无非就是交叉验证,但我并不这么以为,因为这里边可能需要你对某些算法的特性十分的了解,换句话来说,你需要知道调节哪些参数、哪些参数比较重要,这些都依赖于经验的积累。

c、对于类似kaggle的比赛,往往需要建立离线测试,什么是离线测试呢,就是说你要用训练数据的一部分作为验证集,按照项目的要求进行测试,因为好多比赛的提交次数都是有限制的,所以你需要在提交之前明白自己的算法效果有多好,从而可以更方便快捷的进行模型的修改或者调参。

继续阅读