参考caixinjun代码:https://dintl-ml-s2-8077.intra.didiglobal.com/tree/caixinjun/BR/code/最优化ECR、AR模型.ipynb
今天看明白它的逻辑,已经解决了基本训练流程,特征 样本 lgb训练 评估 (jupyter中)。
预计明天看一看各个列的具体含义,包括grid和call的线上sql和通过计算得到的其他几样指标
OptmizARECR.py代码逻辑:
1. 读取配置文件,预处理,调包等
略
2. 用到的各类函数
2.1 划分数据集
func data_preparation(df_train, df_test)-> X_train, Y_train, X_test, Y_test
分类特征onehot处理,对齐test train尺寸,输出训练/测试的x/y
2.2-2.4 时间str处理函数,返回int;
func get_day_of_week_from_date: 将日期字符串转换为星期几(0-6),int
func get_week_of_month_from_date: 计算给定日期是所在月的第几周,int
func get_hour_from_date: 从日期时间字符串中提取小时值(24),int
2.5 concat
func concat_data(bubble_data, rider_data, grid_data) -> df
将格子数据、冒泡数据、司机数据拼接成一个df,返回df; no usage,在主函数里又写了一次这个逻辑
2.6-2.9 加入特征列的几个函数
func add_time_features(df) -> df:调用上面三个函数,加三行特征列
func one_hot_enciding(df, columns) -> df:
对指定列(w, m, h)进行onehot编码
func dummy_time_features(df) -> df:
和上面的区别是编码后将原先的列删除,加入新的列;;上面是不改变原先的列,只返回新的列
func split_train_test(bubble_rider_grid)-> df_train, df_test:
基于日期划分train test,其中test包含最近test_days天的数据,train包含之前的数据
2.10-2.12 gb模型相关的参数传递,用到了再细看
func get_lgb_params() -> params:
func get_ar_lgb_params() -> params:
func get_psm_ar_lgb_params() -> params:
2.13 模型训练
func train_model(X_train, Y_train, X_test, Y_test, model_type) -> model, y_test_pred, y_train_pred
训练模型,返回模型和预测值; model_type:ar, ecr, cr; 支持样本加权的boost;训练boost轮数和早断设置写在函数内,自己写的时候记得挖出来new func
2.14,2.15 两个可视化展示函数
func ar_sort_qcnt && func ecr_sort_qcnt
相似逻辑,预测值排序;计算每组真实值、预测值;计算mae,auc;plot
2.16 func getK:算斜率,可是为什么要算斜率,先疑惑一下
3. ar模型训练/测试
3.1 获取训练数据
获取格子/冒泡 grid_data:df , call_data:df
# 4. ecr模型训练/测试
上午: ar模型和ecr模型的大体逻辑都一致,但是一直前者可以运行后者报错,对比调试无果,遂先吃饭
下午: 继续调试ecr模型,发现是前后对catagorical特征的处理不一致。在预处理时,day week hour等特征应该进行哑元变量处理,ar模型跳过了直接训练。当然统计学角度看这模型练的也有问题。ecr模型只进行了哑元变量处理,但是特征列用的还是老的day week hour,于是对不上遂报错。
思考:树模型对于这种标签变量到底要不要哑元处理,按道理应该要,明天带上李航书来细看一下。
全体数据真实ecr:0.159284
全体数据预测ecr:0.156985
AUC: 0.807
iteration: 1150
ecr的预测效果应该还可以增加。
虽然ar/ecr模型的预测问题是针对结构化数据的,但是目前使用的列有160+,其中不少列之间是correlated的,比如3日期和7日期gmv等,尝试通过降维方法减少特征列数量,提速、提高解释性和性能。
在原先的原始数据集call_data,grid_data上,使用主成分分析和因子分析的方法,进行降维,逻辑如下:
1. 获取grid_data, call_data
2. 获取特征列,只需要数值型的列,id,时间等去掉
3. pca 输出前n个主成分,作图
原始数据集12.6G,超过了numpy.array的限制,做了一些尝试减少内存开销,包括将int64和float64改为int32和float32,以及随机抽数据进行训练。以下为根据特征值排序的前3主成分。
计划降维处理后,用lgb进行训练。对于grid data和call data,计算出特征列间相关系数,并且用并查集方法将高相关(>0.85)的列进行去重。降维后主成分分析发现基本没有冗余变量。
详细的实验过程可以参考我的线上仓库:https://dintl-ml-s2-8077.intra.didiglobal.com/notebooks/YangX/ecr.ipynb