令人吐血的作业…
机器学习作业-欺诈识别报告
1. 任务描述
2. 数据集描述
数据集包括了三个部分:
driver_data
,建模样本表,每行数据是一笔交易,数据可以分为几部分:交易主键,交易主体, 交易属性,数值型变量,行为序列编码,是否欺诈的标签;event_data_card
, driver数据中收益卡近15天(从driver表中的交易时间算起)的历史收款数据,包含交易主键,交易主体,交易属性;event_data_user
,driver数据中用户近15天的历史付款数据,包含交易主键,交易主体, 交易属性(注意这里的付款场景不止转账到卡的交易数据);
详细说明
建模样本表driver_data
的数据描述
交易属性
交易时间
交易的用户(用户id)
收款方id(b_id, c_id)等
交易用户信息(基本属性)
收款方信息(收款为账号) b_info_1
收款方信息(收款为卡) c_info_1
用户信息 a_info_1, a_info_2, a_info_3
交易的设备位置信息 e_info2, e_info3
用户信息
a_id_1 + a_info_1-7
a_info_4, a_info_6 这两列明显种类数量较少 适合使用Onehot编码
其余的a_info3,5,7等的量级在70-350之间 可以正常使用label-encoding
a_id_1这个用户标识几乎没有重复的, 让人怀疑究竟是怎会做到的, 即使存在诈骗行为也是很多的人(切换不同的账号进行诈骗)
3.方法介绍
数据处理的关键点:
数据分散在多张数据表里面(包括了交易模型, 卡片的交易记录, 用户的交易记录等), 需要用合适的方式组织数据;
数据类型复杂, 包括了大量的STRING类型数据, 序列化数据等无法被模型使用的类型, 需要进行转换处理;
数据的特征不明显, 由于很多的数据都被经过编码, 无法从编码本身看出对应的含义;
因此, 结合以上几个问题, 我们首先对于三张数据表进行了特征的筛选和合并, 得到相应的用于训练和测试的数据集
对于数据特征工程: 提取重要的特征, 重新组成一些新特征&去掉一些特别离谱的数据
模型选择:对于此类识别的问题来说, 基于决策树/随机森林的模型一般不错
正负类差距过大, 可以通过一些方式, 例如imblearn进行适当修正, 或者使用负采样的方式 提升负类比例 down-sampling
3.1数据预处理(如有)
数据类型复杂, 含义较为模糊, 在这里进行了比较多的预处理工作
driver_data表的处理
总结一下, 给我们的driver_data数据表中的数据主要就是以下这些
发起交易的用户信息
收款方信息, 这里包含了两种收款方
- 收款方为卡
- 收款方为体系内账号
交易双方的设备位置信息
交易发生的时间(时间+日期+消失)
交易金额
交易是否完成
那么从中我们发现, driver_data里可以提取的特征例如:
- 观察收款方的特点, 是否与诈骗率有关系?
- 收款为卡和收款为账号
GPS位置信息与诈骗率关系
组合以上特征得到的一些新的, 更高级特征是否与诈骗率有关系?
event_card表的处理
event_user表的处理
由于交易行为表中关于用户的交易记录完全缺失, 所以在我们的模型训练中没有包含这一张表的信息.
3.2算法描述
诈骗识别采用的模型是随机森林+参数优化算法
4.实验结果分析
4.1评价指标
4.2定量评价结果
4.3可视化结果
5.总结
比较不同方法的优缺点等。
特征工程
做特征的思路
因为是识别当前交易是否为欺诈交易,在做特征之前可能需要基于一定的业务背景分析下欺诈的场景,一般来讲,线上支付欺诈一般是盗号,那么实施欺诈时可能会有两种表现
盗取后,集中高频交易,从而在最短时间内套现;
模拟真实用户的交易特征,在尽可能不被系统和用户发现的前提下实现盗刷等;
提取特征
去除了7列无关紧要的数据列(这里主要是用户信息, 因为无论是在训练集和还是测试集都没用!)
去掉了训练集中所有被系统拦截的交易(if_succ = -1)这些全部去掉 总共900+行数据.
在XGBoost模型下反而降低了ROC-AUC到82%(性能变差了! 说明好像去掉了什么重要的内容!)
可能的改进方案:
- 时间序列数据 在训练+测试集上是有一个明显的先后顺序的!
todo:
- dt 一项实际上和time有重复! (time包含了当天的小时+分钟+秒等信息)
apply自定义时间(YY MM DD: hh:mm:ss to 时间戳整数)
将time转为时间戳, 去掉dt(重复了), 序列化week_day(0-1-2-3-4-5-6)表示星期天-星期六即可, hh小时可以不用改
- 增加特征, 替换time(绝对时间)
time_in_day 表示天内的时间偏移量
cents 表示 交易金额取整之后剩余部分()
df[‘time_in_day’] = uni.TransactionDT % 86400
df[‘cents’] = uni.TransactionAmt % 1
使用lgb替代原先使用的XGBoost(实际上可以两种都使用)
借鉴他人的方案
我认为这个或许可以替代手工实现一波特征的生成(引用openfe的feature-generation方法)
https://github.com/IIIS-Li-Group/OpenFE/blob/master/examples/IEEE-CIS-Fraud-Detection/main.py
或者这个比较传统的方式
https://www.kaggle.com/code/jtrotman/ieee-fraud-adversarial-lgb-split-points
- Cached OOF(Out-Of-Fold) 折外预测
- FAST Cross
特征分析
用户信息
a_id_1 + a_info_1-7
a_info_4, a_info_6 这两列明显种类数量较少 适合使用Onehot编码
其余的a_info3,5,7等的量级在70-350之间 可以正常使用label-encoding
a_id_1这个用户标识几乎没有重复的, 让人怀疑究竟是怎会做到的, 即使存在诈骗行为也是很多的人(切换不同的账号进行诈骗)
发起交易方的用户信息数据列
用户信息 主要是以下这些列相关的信息
- [‘a_id_1’, ‘a_info_1’, ‘a_info_2’, ‘a_info_3’, ‘a_info_4’, ‘a_info_5’, ‘a_info_6’, ‘a_info_7’]
a_id_1基本上都不相同(基本上都是不同的用户)
a_info_[1-7] 这些给出的都是uuid编码数据 看得出来比较分散, 需要LABEL-ENCODING后进行处理
地理位置相关的参数
- [‘e_info_2’,’e_info_3’,’e_info_4’,’e_info_5’]
4个编码字符串 类别化之后是否可以发现一些关系?
注意是否需要和测试集一起编码?
收款方相关的参数
收款方是用户
- [‘b_id_1’,’b_info_1’, ‘b_info_2’, ‘b_info_3’, ‘b_info_4’, ‘b_info_5’]
总结: 根本就没有, 可以忽略
收款方是 卡
- [‘c_id_1’, ‘c_info_1’, ‘c_info_2’, ‘c_id_2’, ‘c_info_4’, ‘c_info_5’]
很多的编码字符串 类别化之后是否可以发现一些关系?
注意是否需要和测试集一起编码?
我认为有必要先划分driver data成两半
收款是用户的 merge 用户
收款是卡的 merge 卡
然后分别在对应的主体上生成模型, 最后进行评估
c_id_1 不清楚 23个相同用户 保留
c_id_2 不清楚 911个共同特征 保留
c_info_1 也可以留着(虽然关联不大 272个共同标签
c_info_2 可以保留
c_info_3 这个好多空值 建议去掉
c_info_4 可以保留
c_info_5 可以保留
交易相关参数
这些:
[‘time’, ‘hh’, ‘week_day’,’e_info_6’,’e_info_13’,’if_succ’, ‘dt’]
e_info_6 反映了交易类型(完全一致)
e_info_13 标识了交易金额相关
if_succ = 0的案例可以丢到(防止影响)
time其实没什么用(看起来) 测试集合的时间都在训练集合后面
e_info_6这一列数据在测试集合和训练集合一模一样 去掉
hh和week_day还是比较有用的
e_info_13分布相近 可以利用
dt同理 没有什么用
总结
这一些参数内部 可以被作为’类别category’的列有以下:
1 |
而剩余的non-numeric列自然成为了’ordinal_features’
通过open_fe的特征生成, 使得最终成绩提高到了0.34, 说明很有效果(特征的选择)
继续提升的话需要考虑更精细的特征组合(高维度的特征加入)
模型继续使用随机森林
- 比如组合”地理信息”, “用户信息”为新标签列加入数据集
- 加入一些_FREQUENCY列(例如某一个标签出现的频率)
- 细分AMOUNT(包括零头部分)