Giter Club home page Giter Club logo

kdd-cup-2017's Introduction

赛题及数据描述

赛题描述

本题A榜给出了9月19日到10月18日期间3个收费站共五个方向(其中2号收费站只有0方向)的车辆通过记录作为训练集。预测集中给出了10月19日到10月25日共七天 每天6点到8点,15点到17点的车辆通过记录,需要预测当天8点到10点,17点到19点以20分钟为单位的车流量

B榜训练集又给出了10月19日到10月25日所有的车辆通过记录,预测集是10月25日到10月31日6点到8点,15点到17点的车辆记录,需要预测10月25日到10月31日8点到10点,17点到19点以20分钟为单位的车流

数据定义

description of the feature:

Traffic Volume through the Tollgates

time datatime the time when a vehicle passes the tollgate
tollgate_id string ID of the tollgate
direction string 0:entry, 1:exit
vehicle_model int this number ranges from 0 to 7, which indicates the capacity of the vehicle(bigger the higher)
has_etc string does the vehicle use ETC (Electronic Toll Collection) device? 0: No, 1: Yes
vehicle_type string vehicle type: 0-passenger vehicle, 1-cargo vehicle

解题思路

B榜评分 0.1664,名次38/提交346/总队伍数3582

  • 数据中有部分车辆没有“vehicle_type”信息,通过分析数据发现:记录在案的载重量大于等于5的车辆都是货车,载重量为4的车辆以客车居多,载重量3,2的车辆货车居多, 载重量1的车辆客车居多。剩下载重量为0的车辆,不是很理解什么样的车辆载重量会是0,所以单独处理。所以“vehicle_type”为空的记录根据其载重量以及相同载重量的记录中较多的“vehicle_type”去填充空值。具体填充如下:
vehicle_model0 = volume_df[volume_df['vehicle_model'] == 0].fillna("No")
vehicle_model1 = volume_df[volume_df['vehicle_model'] == 1].fillna("passenger")
vehicle_model2 = volume_df[volume_df['vehicle_model'] == 2].fillna("cargo")
vehicle_model3 = volume_df[volume_df['vehicle_model'] == 3].fillna("cargo")
vehicle_model4 = volume_df[volume_df['vehicle_model'] == 4].fillna("passenger")
vehicle_model5 = volume_df[volume_df['vehicle_model'] >= 5].fillna("cargo")
  • 每个收费站和方向分开分析,分别有:1号收费站0方向;1号收费站1方向;2号收费站0方向;3号收费站0方向;3号收费站1方向。每块数据按照20分钟切片, 统计20分钟内通过的车流数量。以两个小时(6段)车流量为特征,用最后一个特征向后偏移20 * offset 时段的车流为因变量构建预测集,其中offset = 1,2,3...6。构建过程类似时间窗每次向后平移20分钟。例如: 2017年9月19日为例,时间切片之后车流数据如下:
时间段 车流量
00:00:00~00:20:00 a
00:20:00~00:40:00 b
00:40:00~01:00:00 c
01:00:00~01:20:00 d
01:20:00~01:40:00 e
01:40:00~02:00:00 f
02:00:00~02:20:00 g
02:20:00~02:40:00 h

构建训练集:

feature1 feature2 festure3 feature4 feature5 feature6 y
a b c d e f g
b c d e f g h

这么做是因为预测集中需要用前两个小时预测后两个小时车流。尝试过不区分收费站和方向的情况,效果没有区分的好。

  • 20分钟切片里除了有车流量,还有货车数量,客车数量,客车载重量,货车载重量等特征;2个小时内的数据也包含了一些信息,包括总的车流量,总货车数,总客车数,总货车载重量,总客车载重量,平均货车载重量,平均客车载重量等。用sklearn的GBDT预测, 参数设置为:默认参数基础上增加一些泛化能力,没有针对评分调参

  • 因变量的时间特征也能用上,包括因变量所处时间点的月,日,时,分,周几等;注意时间信息有两种处理方式,当作离散标签处理(用one_hot编码),或者当作连续值处理,实验发现后者效果好。在GBDT等树形模型中,两者的区别还是很 明显的,前者在叶子节点时相当于只将某一个值作为划分点(例如是以是三点不是三点作为叶子节点的划分),后者就能以多个连续值作为划分点(例如以12点为划分点,小于12点和大于等于12点分别是两个叶子节点)。

  • 分析车流波形发现10月1日到10月7日之间的车流波形和其他时间区别非常大,所有收费站的所有方向都是如此。不知道用的是不是**的数据,感觉就是国庆期间啊……所以将训练集中这段时间的数据全部删除

  • 参考Kaggle里Stacking Start的帖子,做了三层Stacking模型,第一层用了9个模型(LASSO,Ridge,GBDT,ADABoost,XgBoost,XgBoost2,ExtraTrees,Liner,RandomForest),第二层用了(GBDT,XgBoost,XgBoost2),第三层是将第二层取平均。 为了增加第二层模型之间的不相关程度,第二层的输入不是第一层所有模型的输出,其中(LASSO,Ridge,GBDT,ADABoost,XgBoost,XgBoost2,ExtraTrees,Liner)的输出为第二层GBDT的输入,(LASSO,Ridge,GBDT,ADABoost,XgBoost,XgBoost2,ExtraTrees,Liner,RandomForest) 的输出为第二层XgBoost的输入,(Ridge,GBDT,ADABoost,XgBoost,XgBoost2,ExtraTrees,Liner,RandomForest)输出是第二层XgBoost2的输入。参数设置为:在默认参数的基础上增强了泛化能力,没有针对评分调参

  • 观察GBDT对各特征的评分,发现虽然增加时间特征能够提高名次,但是时间特征在模型中的评分非常低,通过对数据的观察发现客流量有非常明显的时间特征。因此建立第二套训练集,特征只有前两个小时每20分钟的车流量,载重量, 以及待预测时段的时间特征(离散时间特征和连续时间特征同时加上)。第二套训练集同样用Stacking模型训练。通过实验发现,不区分收费站和方向的预测结果要比区分的结果好,所以这套训练集不区分收费站和方向

  • 两套训练集得到的预测结果根据名次高低线性加和,名次高的结果乘以0.6,名次低的结果乘以0.4

  • 学习了去年KDD第三名的分享,发现不能的通过单纯增加Stacking的模型种类提高成绩。因此决定使用相关性低的模型,或者单模型效果好的模型因此去掉了Stacking模型了部分模型,第一套Stacking的一层模型模型中去掉了ADABoost,Liner; 第二套Stacking的第一层模型中去掉所有线性模型;

  • 进一步观察数据,发现存在7万条记录没有车辆类型,而且全部都是各收费站0方向,因此去掉之前填空值策略能更加尊重原数据,因此在去掉第一步填充空值的方法,这样就只能减少0方向的部分特征,包括货车数量,客车数量,货车载重量,客车载重量等。使用如下特征替代: 重量0-2的车辆数量,重量3-4的车辆数量,重量5-7的车辆数量。这一步优化的结果没有提升,但毕竟是尊重原数据,所以还是保留了这次优化。

  • B榜数据给出后,立马用B榜数据和之前的预测结果做对比,同时再次观察训练集数据,发现下午17点到19点是一个下降趋势(每个收费站,每个方向的每一天几乎都是这个趋势),反观之前的建模,好像并没有将每天这四个小时车流的特点凸显出来,当时有两种 解决方案:利用重采用,将训练集中6点到8点,15点到17点的数据复制多次;增加训练集中6点到8点,15点到17点数据权重;最后选择使用第一个方案,因为该方案能够通过实验得到较好的重采样次数,而第二个方案在不知道sklearn会对权重高的样本怎样处理的情况下, 没办法控制权重的值。于是利用方案一优化A榜单模型预测结果,而且模型区分上下午。根据实验结果,最后选择在原始训练集基础上,上午数据重采样10份作为上午的训练集,下午数据重采样10份作为下午训练集。

  • B榜两套训练集分别进行上一步的改进,区分上下午,并对特定时段数据做重采样,并根据各自的预测结果设定权值,最终结果 = 结果1 * 0.3 + 结果2 * 0.7

总结:

  1. 解法只考虑了前2个小时的车流,没有考虑前一天,三天,五天,七天等时段的车流特点。之前没想好要怎解做,比赛最后一天才想到,以第二步训练集最后一维特征的时间点为基准点,获取该时间点前一天,前三天,前五天,前七天的车流量。

  2. Stacking模型没有调参,个人决定应该是通过单模型调参,再放到Stacking里训练。我的解法数据划分的太细,导致单模型调参难度同样非常大,所以到最后也没时间调参。

  3. 借鉴第二名的思路,可以在构建训练集的时候,时间窗口平移幅度变成5分钟,同时将数据集中在预测时段,这样即能够突出训练集中预测时段的特点,同时能够增加数据量

  4. 借鉴第一名的思路,可以通过设置样本权重为真实值倒数的方式将损失函数等价转换。传统gbdt提供的损失函数只有平方损失函数和绝对值误差损失函数,而题目给出的评估函数是MAPE,特点是损失值会受到样本真实值大小的影响。将样本权重设置为真实值的倒数,综合考虑加权损失的时候就等价于对损失函数进行改造。

  5. 借鉴第一名的思路,可以更加合理的构建验证集,传统的验证集是从训练集中不交叉的选择10%的数据进行验证,该操作同时进行10次。而由于本题目预测集是有时间段限制的,即严格固定了时间段,因此需要构造和预测集相同时间段,相同时间跨度的验证集才比较合理。具体可以参考第一名的构造验证集思路,有一点复杂,但是方便后续的线下优化工作

部分提交思路以及结果

2017-05-11

  • 在单模型的基础上加上一个清洗脏数据的功能,用三层gbdt清洗掉百分之十的数据,再用五层GBDT预测(不知道为什么才0.7876)

  • 纯时间特征模型加上数值类型的时间特征(成功从0.2016提高到了0.1730)

  • stacking1使用的训练集做微小调整,在构造训练集过程中不处理nan值,拿到模型里才处理,这样训练集的Volume0~volume5和y之间更有连贯性(0.1788已经被纯时间特征超过了)

2017-05-12

  • 重新提交2017-05-11日第一个优化点(>0.3)

  • 在2017-5-11的基础上减少stacking2模型的数量,纯时间模型去掉ADAboost(0.1775)

  • 检查训练集,在2017-05-11的基础上减少stacking1模型的数据,去掉所有ADAboost模型,二层不适用随机模型,尽量减少模型之间的相关度(0.1735)

2017-05-13

  • 在2017-05-12基础上修改过滤时的评分函数

  • 修正时间特征计算代码0.1681

  • stacking的第二层备选模型中去掉随机模型(ET和RF)(0.1739)

2017-05-15

  • 在2017-05-13项目1的基础上,舍弃数据过滤功能,改成特征选取功能,功能按照单个特征做回归的评分高低降序排序,每次选取一个效果最好的特征加到备选集中,并预测打分,得到最好的特征集(0.1841降了)

2017-05-18 都是单模型调整

  • GBDT3层和5层有没有区别,可以尝试一下,而且注意用评价函数(3层效果好,说明5层有严重的过拟合)

  • 加一些特征吧,比如说最大值,最小值(0.1747)

2017-05-17 训练集和预测集数据分析

  • 发现不论是原始的训练集还是原始的预测集,0方向(entry)的车辆都不记录vehicle_type,而1方向(exit)的方向都记录了该值, 所以不能盲目用众数来填充vehicle_type的空值,在分端口和方向的时候适当剔除掉一些特征

  • 3层GBDT(0.1627)

  • 存在7万条记录没有车辆类型,而且全部都是各收费站0方向,都没用电子桩(暂时不做处理,因为题目也说载重量是0到7,说明0载重量是存在的)

2017-05-18

  • 在昨天基础上,删除处理后产生的空值,之前我都是在stacking文件里专门处理训练集和预测集的空值,在volume_predict2文件里 没有这功能。(0.1683)

  • 在昨天基础上,增加层数到5层(0.1694)

过拟合了,想想怎么肥四

2017-05-19

  • 把10月1日到10月7日的数据加回来,增加部分特征,包括20分钟内使用etc的车辆数、总载重量,没使用etc的车辆数、总载重量

2017-05-21

两种筛选训练集方式

  • 按照预测集分布筛选,用预测集车流的最大值,最小值,均值,标准差压缩训练集vloume0 ~ volume5的区间,注意用均值加减二倍标准差和 最大值,最小值比较(0.1687)

  • 直接用训练集本身的分布特点筛选数据,用训练集的最大值,最小值,均值,标准差压缩区间,均值加二倍标准差为上限, 下限设置常数3(0.1692)

之前单模型提交的数据结果及方式概要:

  • 0.1672 分端口方向构造不同的特征,10月1日到10月7日数据全部变成null,但是当时忘记删除这些值,将其全部填成0

  • 0.1747 在上面的基础上删除所有的空值

  • 0.1647 在上面的基础上删除部分特征,包括最大值,最小值,均值等特征

  • 0.1658 考虑到大量的0数据能够改变树的分布,将部分较小的数值隔离开,因此想增加10月1日至10月7日数据来平衡数据分布

  • 0.1687 用测试集的最大值,最小值,均值,方差清洗数据,均值加减二倍方差

  • 0.1692 用训练集的最大值,最小值,均值,方差清洗数据,均值加减二倍方差和最大值,最小值,用最大区间

2017-05-22

暂时放弃上述两种数据清洗方式,使用如下数据清理方式:

  • 10月1日至10月7日数据全部删除

  • 除此之外,其余数据resample得到的空值均填为0

待提交方法

  • 用之前的非调参stacking模型+时间特征模型的融合(0.1728, 0.1617)

  • 使用另一种stacking方式,二层固定使用两种参数的XGB和一个GBDT,一层使用三种模型集合,集合长度分别为6,7,6(0.1673,0.1602)

  • 单模型调整,单独剔除10月1日到10月7日的数据(保证resample之后没有这个东西),在此基础上将所有的空值设置为0(0.1674)

2017-05-23

  • 单模型调整,删除全部空值(尽量合理删除空值),顺便检查代码

  • 把1放到05-22的第二个stacking模型中

  • 时间特征模型调参,可以稍微过拟合,目的是降低和主train&test1模型的相关度,0.5x+0.5y的比例分配结果,最后成绩是0.1589

kdd-cup-2017's People

Contributors

akirara avatar ttff96989 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.