Zessay / tianchi_metro

关于天池地铁流量预测比赛的总结和代码 rank82

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

地铁乘客流量预测

Table of Contents

竞赛题目

 通过分析地铁站的历史刷卡数据,预测站点未来的客流量变化。开放了20190101至20190125共25天的刷卡记录,共涉及3条线路81个地铁站约7000万条数据作为训练数据Metro_train.zip,供选手搭建地铁站点乘客流量预测模型。同时大赛提供了路网地图,即各个地铁站之间的连接关系表,存储在文件Metro_roadMap.csv文件中。

 测试阶段,提供某天所有线路所有站点的刷卡记录数据,预测未来一天00时至24时以10分钟为单位的各时段各站点的进站和出站人次。

 测试集A集上,提供2019年1月28日的刷卡数据testA_record_2019-01-28.csv,选手需对2019年1月29日全天各地铁站以10分钟为单位的人流量进行预测。

 评估指标采用平均绝对误差Mean Absolute Error, MAE,分别对入站人数和出站人数预测结果进行评估,然后在对两者取平均,得到最终评分。

 关于数据的具体描述以及说明详见天池官网

1. 赛题分析和前期思路

 比赛提供了1号到25号共25天的刷卡记录数据,所以第一步就是对每一天的文件进行处理。原始数据集中包含了time, lineID, stationID, deviceID, status, userID, payType这几个列,根据题目要求要预测进站和出站的人流量,所以要先统计出每一天的进站和出站流量。

1.1 数据清洗

提取基础信息

 首先对时间信息进行处理,提取出日、周、时、分、秒的信息,由于是按照10分钟为间隔统计,所以在提取分钟信息的时候只需要取整十。接着总计80个站点(除去缺失数据的54站),每个站点从0点到24点,以10分钟为一次单位,总计144段时间间隔。根据站点、日、时、分进行分组统计,得到每个时段的进站人数和出站人数。

 经过第一轮处理之后,得到了每一天的文件包含的columns有:stationID, weekday, is_holiday, day, hour, minute, time_cut, inNums以及outNums这几列。

 增加了一些和刷卡设备相关的特征,包括nuni_deveiceID_of_stationID, nuni_deviceID_of_stationID_hour, nuni_deviceID_of_stationID_hour_minute

1.2 特征工程

增加同一站点相邻时间段的进出站流量信息

 考虑到当前时刻的流量信息与前后时刻的流量信息存在一定的关系,所以将当前时间段的前两个时段以及后两个时段流量信息作为特征。

 增加的特征包括inNums_before1, inNums_before2, inNums_after1, inNums_after2, outNums_before1, outNums_before2, outNums_after1, outNums_after2

增加乘车高峰时段相关的特征

 根据杭州地铁的运营时段信息,将高峰时段分为四类,0表示非运营时间段,1表示非高峰时间段,2表示高峰时间段,3表示特殊高峰时间段。由于周末和非周末的高峰时间存在一定的差异,所以需要分别计算。

 增加了特征peak_type

增加同周次的进出站流量信息

 均值、最大值以及最小值在一定程度上反映了数据的分布信息,所以增加同周次进站流量和出站流量的均值、最大值以及最小值作为特征。

 增加的特征包括inNums_whm_max, inNums_whm_min, inNums_whm_mean, outNums_whm_max, outNums_whm_min, outNums_whm_mean, inNums_wh_max, inNums_wh_min, inNums_wh_mean, outNums_wh_mean

增加线路信息

 根据某一天的刷卡记录表统计每条线路和站点的对应信息,并计算各条线路的站点数,用站点数量代表该站的线路信息。

 增加特征line

增加站点的类型信息

 不同的站点属于不同的类型,比如起点站、终点站、换乘站、普通站等,而这些站点的类别信息可以通过邻站点的数量表示,所以根据路网图对邻站点的数量进行统计,表示各个站点的类别。

 增加特征station_type

增加特殊站点的标记

 对站点流量的分析过程中,发现第15站的流量与其他站点存在明显的区别,全天都处于高峰状态,因此给15站添加特别的标记。

 增加特征is_special

连接训练特征和目标值

 本次建模的**使用前一天的流量特征和时间特征,以及预测当天的时间特征,来预测进站流量和出站流量。所以要对之前处理好的数据集进行拼接。

 增加新的特征yesterday_is_holiday以及today_is_holiday,增加目标值列inNumsoutNums

对时间间隔进行目标编码

 考虑时间间隔信息与进站、出站流量的相关性,对时间间隔信息针对inNumsoutNums进行目标编码。(这一步并非必须的,一定程度上可能会导致过拟合,所以可以考虑加入和不加入的情况都测试一下)

 目标编码后得到了in_time_cutout_time_cut

1.3 划分训练集和测试集

 根据上面数据清洗以及特征工程得到的结果对数据集进行划分。

1.4 搭建模型预测

 我们使用了LightGBM和CatBoost两个模型预测并取其均值,其实也可以尝试加入XGBoost,然后取3个模型的加权平均,但是我们当时训练时发现XGBoost得到的结果不是很好,所以直接丢掉了。其实,通过加权平均,给XGBoost的结果一个比较好的权重,也有可能会得到比较不错的结果。最后,对模型结果平均

2. 其他的一些想法

(1) 由于官方给了路网图,所以我们尝试将路网图拼接在特征后面,表示各个站点之间的连接关系,但是这样反而降低了模型最终的性能。


(2) 过程中我们一直想充分利用邻站点的信息,想在邻站点上提取尽可能多的特征,包括邻站点相同时刻以及相邻时刻的流量信息,但是这样都会降低模型的性能,也在这上面浪费了不少的时间。


(3) 除了从以后的数据中提取特征之外,我们还对提出出来的特征做了一些特征工程,包括计算一些可能有一定关联的特征计算加减以及比率信息,但是这些工作都没有能够提升模型的性能。


(4) 根据官方交流群的讨论,我们在A榜的时候尝试去掉周末的信息,只讲工作日的信息进行提取和拼接,这在一定程度上提升了模型的效果,后来我们在鱼的代码基础上加入了我们之前找到的一些特征。之后,仔细推敲了一下鱼的代码,发现在进行特征feature和目标值target拼接的时候,和deviceID相关的特征使用的是预测当天的,这样一方面会导致leak,另一方面就是最后的测试集这些特征都是nan值,也就是说在最终的预测中没有起到作用。于是,我们改变了拼接的方法,再次加入了自己提取的特征,最终在A榜跑出的成绩是12.99。注意,这里使用的数据并不是全部的数据,而只是使用了工作日的数据拼接


 在B榜的时候,我们还是希望能够训练一个通用的模型,所以这次把所有的数据放在一起训练,并没有将周末的数据单独提取出来,但是在滑窗的时候使用了1320两天的数据作为验证,最终跑出了12.57的成绩,说明这种想法是可行的。为了验证一下只提取周末信息的效果,我们也尝试把周末的信息单独提取出来,最后得分一直在14以上,可能也是因为我们提的特征不太适用于这种场景。


 最终,我们使用了全部的数据通过Stacking的方法进行了训练,将三个梯度提升树模型进行了堆叠,最后得到的结果也是14多一点。

3. 总结与思考

(1) 首先是对数据的EDA做的不够,包括对各个站点的分析,各个时间段综合分析,对特征重要性的分析等等。主要还是因为经验不够,不知道该怎么做,甚至15站点的特殊性也是从交流群里得到的信息。另外,就是调参做的有问题,反而把模型的性能调低了,说明对参数的理解不够。


(2) 第一次团队作战,不知道该怎么协作,分工不是很明确,所以效率不是很高,没能有机会尝试更多的模型。代码写的不规范,导致后面修改的时候浪费了比较多的时间,包括整理也花了不少的时间。


(3) 知道的模型太少,只使用了梯度提升树模型,其实还有很多可能有效的模型可以尝试,包括图神经网络,时空模型以及LSTM,但是都因为不够熟悉而无从入手。


(4) 总结:

  • 了解自己能做的事情,明确分工;
  • 做好EDA,做到对数据的充分理解;
  • 代码书写规范,每一个功能模块应该定义为一个函数;
  • 熟悉不同模型的功能以及试用场景。

About

关于天池地铁流量预测比赛的总结和代码 rank82


Languages

Language:Python 100.0%