序
KDD CUP 2017从四月开始做,到今天(0508)已经做了一段时间,成绩目前虽然较以前有了不少提升,但距离顶尖还有不少距离。
最近把想到的好实现的东西都实现了,效果也都不错,但是貌似遇到了瓶颈,现在捋一捋思路,看看还有什么地方可以继续提高。
由于目前只做了volume的部分,所以下文中只涉及vol。
Data Analysize
接触到数据,首先做了一些简单的分析和可视化。然后定了基本思路。
定义问题
- 高速公路收费口流量预测
- 已知的大部分数据都是高速收费口外(合流区,分流区)的数据
输入:
- 目标区域的道路网络拓扑
- 车辆轨迹
- 车型
- 收费口历史流量
- 天气
- 节假日
输出:
- 预测路口A-收费口1之间的通行时间
- 收费口流量
可视化
- plot(y)之后发现时间区间包含了十一假期,流量会有异常,而预测区间内不包含法定节假日,推测该部分数据对预测帮助不大,所以在后来当作异常数据给处理掉了。
- 流量的周期变化十分明显,周期为一天,常识上也认为每周会有对应的变化。
- 长期趋势不明显。
基本思路
- 通行时间和收费口流量应该是强相关的(不一定是同一时段)
volume:
- 回归:收费口的时空特性,作为feature,应该有个baseline了
- 相似性分析:kNN找出历史数据中相似情形的流量作为预测(在没有明显趋势特征的情况下,效果应该可以)
- 更多的研究高速公路特性,收费口上下游流量,可以结合通行时间,test中找出上游流量,以此作为预测
- 时间序列算法,时序数据平稳化处理。。
- stacking以上。。。
travel time:
- 后面再做
数据预处理
- 异常检测处理
- 移除十一期间的数据
- 流量基本符合正态分布,使用
$3\sigma$
原则,对于每个tollgate-dir对计算并删除界外数据
- 类别特征编码
- 基本特征中的类别特征均以数值化表示,进一步区分的话进行哑变量编码
- 简单的比较发现模型对于编码不敏感
- 标准化(数值缩放)
- 将所有数值以MaxMinScaler()缩放到(0, 1)
- 对svr, knn有影响
基础特征及模型
举办方除了提供流量数据,还提供了期间的天气信息。
先提取了最直观的特征:
- 时间信息
- 提取流量数据中time_window中的时间信息。
- month
- day
- day of week
- hour
- time_window of day
- 天气
- 默认的天气数据
- 温度
- 气压
- 降水
模型先用了几个集成树模型:
- gradient boost tree regression
- random forest regression
- xgb
以及几个基本模型:
- linear regression
- svm regression
- knn
- decision tree
这里先用比较粗糙的方式进行预测,存在着很多问题,但是已经有了第一次提交,这时候默认参数下,gb, rf等效果比较好的模型成绩已经接近0.20
存在问题:
- 特征存在较多冗余。
- 除了tw和dayofweek其他特征的importance都较低。
- 模型使用默认参数gb欠拟合较严重。dt之类过拟合。
交叉验证
一般步骤是调整模型参数,使预测结果在测试集上的mape更低。
这里的理解数据分为为训练集,验证集,测试集(线上)。
有不同的划分方法:
- train_test_split划出训练集以及验证集
- 简单,易于实现
- 数据集较小时,浪费了一部分数据(一般认为数据越多,学习上限越高)
- 与验证集结果差别较大(验证集较少时,有过拟合的可能)
- 使用交叉验证,不需要单独的验证集
- 实现需要一定工作量,不过sklearn中集成了不少cv函数,提供了便利。
- 实际交叉验证的mape可以一定程度和线上成绩挂钩,比较适合作为调参的标准。
- 充分利用数据,目前采用的方法是,使用全部数据做预测,交叉验证得出一个oof_score。还有一种思路是将交叉验证中的模型结果做平均,是否存在差别需要尝试呢,值得思考
存在问题:
- 交叉验证的结果只能体现模型参数的调整结果。
- 对于超参数(数据,特征)的调整,交叉验证的结果还无法用来横向对比。
- gb等模型交叉验证的速度较慢。
- grid search目前理解就是流程化的cv比较,需要对每个参数的范围有所掌握才好使用,所以暂时米有采用。
模型调参
调参首先理解偏差方差均衡,然后调整参数使模型表现处于方差和偏差的均衡位置。
sklearn中模型的大部分参数都是和模型复杂度成正比(其实不然。。。),画出train_score, 和test_score可以更加直观。
实际上,目前的经验来说,直接找到test_score的最低点就好了,这样参数的train_score的表现可能过拟合,但经验上来说,线上的成绩变化与cv得到的oof_score(test_score)保持一致。
集成模型中常用的参数:
- max_depth(控制子模型中决策树的深度,直接体现模型的复杂度)
- 同样的表现,gb(max_depth=3~6), rf(max_depth=5~10)
- n_estimators子模型数量,这个参数与直观有较大不同。
- 不直接体现模型的复杂度,反而gb中较少的子模型数更可能过拟合
- 与步长(learning_rate)协同调整
- 实际操作中,较大的子模型数可以换来性能的提高(上万,虽然训练时间极大增加)
线型模型调参经验:
- lasso, ridge是lr添加l1, l2正则化项后的算法
- 二者的区别有待研究
- 正则化是为了减少过拟合
- 目前的数据来看,lr表现为欠拟合,所以两个改进算法的表现反而不如lr
svr, knn:
- 这两个模型涉及到特征之间距离的计算,所以最好预处理时进行缩放标准化。
特征工程
特征提取
短期流量
特征工程贯穿数据挖掘项目的始终,对成绩的影响也相当大。放在最后的步骤阐述。
除了基本特征外,目前加入了短期流量特征。
考虑到test数据中短期流量只给出了每天的4h,为了避免特征缺失的情况,将训练集的时间区间缩减到4h,所幸有限数据集的成绩还有些许提升。
考虑到基本模型和特征均没有体现趋势,所以只有4h,对成绩的影响不大,后续可以考虑使用全数据集的模型,对结果进行stacking。
短期流量特征对于不同时间段可能是有缺失的,上一次客流量预测比赛中就卡在了这里。这一次不想特征工程做的太难看,所以加入了tw*short_vol作为区分。
more
- 基本特征的简单运算
- 模型预测结果(与stacking的区别联系呢?)
- 通行时间
特征筛选
上述特征中存在不少弱特征和冗余,以gb.feature_importaces_为依据简单的删掉几个弱特征后性能有了一定提升。但是保留的比例该是多少还有待斟酌。
模型集成
做了stacking,较基础模型有一定提升。
stacking用白话来说就是,对基础模型再训练,综合多个基础模型,按照准确率分配权重,集成输出。
模型集成中的基础模型不止局限在不同的算法,可以扩展到各种超参数(特征,数据集等)的组合,可以综合各种方法优势。
后续工作
目标:前50(现在130+)
考虑到还有二十天左右时间。还是更多的学习吧,所以travel time先不做了。
下面一周做时间序列算法
再一周做特征工程
- 组合已有特征
- 加入travel time特征
- 加入模型预测结果作为特征
- 特征筛选
赛后更新
之后有了一点进步loss: 0.1439最高在109名,换数据之前也还在200+。
还是有很多不足,继续学习!