天池&Datawhale二手车新手赛-Task03

如何做特征工程

首先确定你选用的模型是什么

特征工程应当结合模型来做,这看起来似乎是一句废话,但与一些参赛的小伙伴讨论过后,发现很多人都没有认识到这一点。或者说只是表面上知道这一点,却并没有很好地在建模中践行。我觉得这里有一个原因,就是很多同学在做data mining的时候,只是调包,然后顶多调一下超参数,只能从结果来判断参数好坏,并不知道为什么好,甚至连有哪些超参数都不清楚。基于此,对特征工程这一块也是胡子眉毛一把抓,网上看了些资料,然后就按照别人说的处理一通,并没有深入思考别人为什么那样处理。

举个例子,很多同学上来就看特征分布,然后就发现很多不满足正态分布,然后也不管用的什么模型,先做一通正态转换。然而却完全没考虑,自己用的是XGBoost模型。而XGBoost模型根本就不管你特征什么分布,人家就是安特征排序,然后取点进行split,所以转换特征的分布,对算法并没有任何影响,因为多数的特征转换都是单调的,不改变原特征排序。什么?你说你用的是线性模型? 那当我没说。

好了回归正题,本次赛题,个人选用的是XGBoost,别问我为什么不用lbg,因为我还没学懂这个算法。基于XGBoost,特征工程有哪些需要注意的?

基于XGBoost的特征工程

这里仅仅谈一些个人的思考,说不上什么方法论。
首先,XGBoost是根据特征的排序,然后分别取不同分位数的值来进行split,计算GINI值,决定选取哪个特征的哪个分位点进行split。从算法原理可以判断,任何单调的数值变换,都不会提升算法的准确率,甚至对也不会提升算法效率。所以那些normalize,scalable的算法就必要做了。那应该做什么呢?这里分不同的变量进行探讨。

连续变量:

对于变量中的缺失值,如果有先验,补上当然好,不补问题也不大。对于异常值,比如异常高的值或者异常低的值,个人觉得可以进行截断。但也有例外,比如本赛题中的power,我看到有很多超过500的值,而超过500后,这些观测的价格会骤降,这时候截断的方式就不好了,因为模型会认为500以上的跟500的是一波人,也就不会把他们分开。因此个人建议是,超过500了就标位缺失值,认为是消费者自己乱填的。同样的,很多power = 0, 是否也标为缺失值呢?个人看了下分布,认为如果也将0标为缺失值,模型会认为这些人 跟power 大于500的那些人是一波人,但实际上又会很不一样,因此就不适宜把0再转为缺失值,而且从价格的变化趋势,power接近0 的价格都不高,因此模型会很容易把这些低power的跟正常power的人分开。这时候我做的是,把power低于10 的都规整到0,这样模型会更容易的把0 这波人单独分开来。
此外,对于连续变量,还可以进行分桶操作,比如通过creatdate - regdate 能得到二手车的使用年限(注:regdate有部分错误日期,转换的时候不处理会出现缺失的情况),而经验告诉我们,二手车年限往往跟年数是有关系的,比如第一年第二年,因此处理使用年限的时候,对其记性了按年取整的操作。这样一方面能减少过拟合(可能也会损失部分信息),另一方面能够加速模型的训练,实测进行了该操作后,模型的分数并没有降低,但是速度确实快了。
嗯,想到这里,还是得回去翻一下XGBoost的算法,比如算法是否能精准的把power中的0值与非0值进行分割?可能刚开始的时候不一定行,因为算法是对特征进行分桶,然后再取点进行分割。

分类变量:

本赛题里面,像model、brand这样的分类变量,也进行了连续值编码,但千万不能把它当做连续值来放入模型(别问我为什么)。这些变量都需要进行one hot编码。但model有好几百个,算法作者不建议对这种变量不进行处理就直接one hot,因为过于稀疏,个人认为可以对model 这样的变量,可以根据model 观测数的多少来进行one hot,比如观测数据低于一定阈值的,统统编码成一个model。当然这么做会略显粗糙,但也总比什么都不做直接one hot的好。对于one hot,本人开始也犯了一个低级错误,就是为了防止完全共线性,把one hot后的某一列丢弃了。完全共线性那是回归里面的大忌(抱歉本人回归中毒太深),但树模型则完全不担心,而且去掉了某一列后,对于模型来说,需要排除掉其余所有的变量后才能“找回”丢弃的那一列,这是弄巧反拙,因此,one hot后千万不能丢弃某列。

其他问题

听说有同学把regioncode提取第一位当做城市,却没发现regioncode是连续编码的,就是主办方压根就不希望你从里面获取城市信息。这种强行提取城市的做法,出发点虽然对的,却没有观察数据的特点。也是很多新人会犯的错误吧,切记。
对于v_1 这种疑似主办方对部分数据做了平移的特征,本人尝试把其拆成三列(不要问我为什么不平移回去,万一我猜错了呢),一列表示左半部分,一列表示右半部分,还有一列是标识 哪些观测属于左半部分,属于的标1, 不属于标 0。 这也是受线性回归的影响,这样能够完整的保留信息的同时,让模型区别的对待左右两部分数据。但让我不解的是,XGBoost似乎不太认同 0/1 标识列,做的几个变量重要性都很低。有待进一步思考。
对于y是否需要做转换,这个不同于特征的变换,是有价值的,y的取值首先就会极大的影响到超参数的设置,同时也会影响到模型split的优先顺序,对于这一点,是需要结合GINI值的计算来进行推敲。目前个人的判断是,当y的值域跨度太大时,确实需要对其进行转换。而且如果我们对某一种值域范围的y所对应的超参数有较强把握的时候,把y转换成相应的值域,也能提升我们调超参数的效率。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值