项目链接:
https://www.kaggle.com/c/amazon-employee-access-challenge
解决方案:
https://github.com/pyduan/amazonaccess
参考资料:
https://blog.youkuaiyun.com/qq_25300563/article/details/50944957
可能有用的分析:
https://blog.youkuaiyun.com/csqazwsxedc/article/details/51338266
问题描述:
当任何公司的员工开始工作时,他们首先需要获得履行其职责所必需的计算机访问权限。此访问可允许员工通过各种应用程序或Web门户读取/操作资源。假设履行给定角色功能的员工将访问相同或类似的资源。通常情况下,员工在日常工作中遇到障碍时会找出所需的访问权限(例如,无法登录报告门户)。然后,主管需要时间手动授予所需的访问权限以克服访问障碍。随着员工工作的进行,这种访问发现/恢复周期浪费了大量的时间和金钱。
关于员工在组织中的角色以及他们可以访问的资源,有大量数据。鉴于与当前员工及其配置访问相关的数据,可以构建模型,以便在员工进入和离开公司内的角色时自动确定访问权限。这些自动访问模型旨在最大限度地减少授予或撤销员工访问权限所需的人为参与。
本次竞赛的目的是建立一个使用历史数据学习的模型,该模型将确定员工的访问需求,以便随着员工的属性随时间变化而最小化手动访问事务(授权和撤销)。 该模型将获取员工的角色信息和资源代码,并返回是否应授予访问权限。
数据描述:
train.csv - 训练数据集包括action(我们要预测的标签)、请求的资源号和员工本人的信息
test.csv - 测试数据集包括每个请求事件,资源号和员工信息,预测是否批准访问(即action)
列名信息:
ACTION 需要预测的标签值,如果允许访问则为1,否则为0
RESOURCE 请求的资源ID
MGR_ID 请求资源的员工的boss,员工和boss只能是多对一不能是一对多
ROLE_ROLLUP_1 公司角色分组类别ID1(例如美国工程)
ROLE_ROLLUP_2 公司角色分组类别ID2(例如美国零售)
ROLE_DEPTNAME 公司角色部门描述(例如零售)
ROLE_TITLE 公司角色业务职称描述(例如高级工程零售经理)
ROLE_FAMILY_DESC 公司角色家族扩展描述(例如零售经理,软件工程)
ROLE_FAMILY 公司角色家庭描述(例如零售经理)
ROLE_CODE 公司角色ID; 此代码对每个角色都是唯一的(例如Manager)
【这个family,我没太搞懂是哪里来的,百度翻译译为“系列”,大概是对头衔的一种简短描述吧】
所有的data都是纯数字,这很有趣,如何对数字进行组合呢?如果随便拿sklearn做一个归一化扔进逻辑斯蒂回归或者支持向量机,然后应该可以拿到差不多0.6的分数我也可以打败10%的人【不】。
代码框架:
1.external模块:数据基本预处理
引用来源https://blog.youkuaiyun.com/qq_25300563/article/details/50944957
ben.py
该脚本构建了基础数据集bsfeats,只对原始数据集做了最基本的特征工程。1.对个别变量进行线性组合得到新变量 2.按变量对数据进行分组,计算不同观测在组中出现的次数并取对数 3.计算各部门的资源使用率 4.计算各经理的资源占有量。需要强调的是,这些特征工程都是紧紧围绕业务知识展开的。
greedy.py
该脚本构建数据集greedy,greedy1,greedy2。分别将各列两两组合生成元组,对元组取哈希得到新的列,这个新的列可以代表之前组合的两列的交互作用,将原始数据集横向合并新生成的列得到了全是新特征的tuples数据集。同理,将各列三个一组进行组合用同样的方法得到全是组合再hash后全是新特征的triples数据集。最后将原始数据集、tuples数据集以及triple数据集横向拼在一起,即把新生成的特征放进去。由于不管是原始数据集还是新生成的tuples、triples数据集,很多都是类别型变量,对它们分别进行One-hot编码得到稀疏矩阵Xts。遍历Xts中的每一个特征,用自编的cv-loop函数分别计算auc得分,依照auc得分筛选出good_features。这里用的是前进法,比如第五个特征符合要求属于good_features,考查第六个特征时,把该特征与前五个特征一起放到函数中计算auc得分,相当于每放一个feature进来就计算一次auc,遍历完所有特征后对auc进行排序。需要注意的是,由于之前进行过one-hot编码,计算得分前要用scipy中的tocsr()将稀疏矩阵转化为压缩形式。
2.helpers模块:特征提取
data.py
用作整个模块的IO,写入和读出数据。
Diagnostics.py
作图
引用来源https://blog.youkuaiyun.com/qq_25300563/article/details/50944957
feature_extraction.py
tuples和triples函数分别对数据集中的变量两两组合和三三组合得到新的变量,至此,数据集的六大框架(bsfeats,greedy,greedy2,greedy3,tuples,triples)都已构建好。create_feature()函数按照基础模型、LR模型、Trees模型(这里指的是GradientBoostingClassifier、RandomForestClassifer和ExtraTreesClassifier)分别构建含有不同特征的数据集。在构建的过程中使用了变量的取平方、取平均、取对数、除总算频率等特征工程方法。其中用于LR模型和Trees的数据集都进行了进一步的预处理过程,包括各特征相互乘除构造新特征(用于表征特征间的相互作用)、去除常数变量、变量标准化处理、变量值加上1取对数、变量取平方、变量取三次方、用One-Hot编码稀疏化处理等。另外,这些特征工程并不是都用上,而是有选择的使用,使用不同的特征工程方法,能得到不同的数据集。
utils.py
辅助脚本,提供了两个辅助函数stringify()和compute_auc(),前者用正则表达式将模型和该模型用到的数据集的名称进行组合作为一个identifier,而后者是计算auc值的函数
ml.py
提供了 模型训练的框架,包括AUCRegressor、MLR和StackedClassifier这三个类。其中StackedClassifier是主力,它将几个模型整合到一起以期达到最好的效果(用AUC来衡量),用来计算AUC的模型输出值有三中形式可供选择,mean_preds、stack_preds和fwls_preds,其中mean_preds是模型组合中所有模型输出结果的简单平均值,stack_preds和fwls_preds都是利用RidgeCV选择最佳的参数,fwls相较于stack增加了metafeatures。而find_params()函数利用GridSearchCV()筛选出最优的参数值,该函数的输出结果作为classifier.py中model.set_params(),从而保证能利用到最优参数值。函数fit_predict()用来训练每个模型并输出结果的平均值。
3.BSman模块:模型融合
Logistic.py
这个我并没有明白它是什么意思,而且起了一个逻辑斯蒂回归的名字,等看到这里了再认真看
ensemble.py
基于上面的内容构建融合的模型
据说这样运行它们
[python] logistic.py log 75
[python] ensemble.py
4.classifier.py:输出结果
类似于main函数的存在
5.conbine.py:融合结果
似乎是把PD和BS的代码按照比例做了融合
【我理解这个有些杂乱的代码分布是这样的关系:
】
数据挖掘总过程:
这份方案实际上包含了两个人的代码,在最后用一些简单的回归模型综合了这两个人的预测结果。代码里有非常多很有价值的内容。
方案一解析:
方案二解析:方案二的特征预处理跟方案一基本重合,只是没有交叉验证字典的部分,主要说一下模型融合,模型融合的思想不同,在BSMan的ensemble里。
我从来没有见过这种融合思路,很新鲜。
上面两种方法得到的结果,用逻辑斯蒂回归或桥回归做一个统一。
阅后总结:
对纯数字特征搞出来这么多道道,着实令人佩服。几点收获:
- 对独热稀疏编码的应用。这个我还不是特别懂,但是似乎可以加快特征选择。稀疏矩阵输入模型前要先to_scr,这个如果看不懂的话可以复制过来直接用。
- Stacking,这个方案的stacking写得非常漂亮
- auc,以前从来没有这个意识,不仅是二元分类,其他分类也要注意看有没有更好的损失函数可选,注意auc对应的是pred_proba
- 利用sklearn包中自带的一些cv
- 随时输出结果,利用缓存,可以避免反复运行
- 融合结果和预测特征时通常都选简单的模型比如逻辑斯蒂回归,不知道是不是因为其他的会跑不动。
- 二元特征融合、三元特征融合、特征之间的关系是常规操作,其他特征工程需要丰富的想象力和熟练的业务知识。
解读的方案来自github上大佬开源的工程文件,标明引用的函数块剖析来自csdn,流程图、思维导图均为自己总结绘制。感谢方案原作者,博文所有内容不保留版权,如有需要请任意使用。