arduvey29/mule-detection

GitHub: arduvey29/mule-detection

基于大规模银行交易数据的反洗钱骡子账户检测端到端机器学习管线,通过领域驱动特征工程识别洗钱行为模式。

Stars: 0 | Forks: 0

# AML 骡子账户检测挑战赛 ## 主要目标/问题描述 从银行交易和账户数据中识别用于洗钱的骡子账户。给定带有标签的训练数据和未标记的测试账户,预测哪些测试账户是骡子账户。 ## 评估 - 准确的提交指南将很快提供 - 评估标准如下所列: - 模型/特征独创性占 40% 的权重 - 奖励在使用的模型/特征类型上的创意和创新想法,可以使用串联/并联的多个模型/算法来生成最终预测 - 模型性能得分占 20% 的权重 - 奖励高准确率/精确率得分,如 AUC-ROC 和 F1 分数等计算得分 - 避免数据中的干扰项占 15% 的权重 - 奖励成功避免训练数据中注入的多个干扰项 - 额外见解(如时间 IoU 得分和其他见解)占 15% 的权重 - 报告质量占 10% 的权重 - 奖励在报告中以数据驱动逻辑呈现的清晰简洁的见解。 ## 快速开始 1. 安装依赖: ``` pip install -r requirements.txt ``` 2. 运行完整 pipeline: ``` python 01_explore_data.py python 02_feature_engineering.py python 03_train_model.py python 04_generate_submission.py ``` 3. 验证输出文件: - `output/cv_results.json` - `output/feature_importance_lgb.csv` - `submission.csv` ## 数据文件 ### 提供给您的文件 | 文件 | 行数 | 大小 | 描述 | |---|---|---|---| | `customers.parquet` | 159,000 | 2.3 MB | 客户人口统计和 KYC 信息 | | `accounts.parquet` | 160,000 | 6.7 MB | 账户级别属性 | | `transactions/` | ~400,000,000 | 8.2 GB | 个人交易记录(5年跨度:2020年7月 - 2025年6月),4个批次共 396 个分片 | | `demographics.parquet` | ~159,000 | 4.6 MB | 客户人口统计(姓名、性别、地址、电话) | | `accounts-additional.parquet` | ~160,000 | 0.9 MB | 每个账户的计划代码 | | `transactions_additional/` | ~400,000,000 | 8.4 GB | 扩展交易字段,4个批次共 311 个分片 | | `branch.parquet` | ~9,000 | 0.3 MB | 网点级别元数据 | | `customer_account_linkage.parquet` | 160,000 | 1.8 MB | 将客户映射到其账户 | | `product_details.parquet` | 159,000 | 2.9 MB | 每个客户的汇总产品持有量 | | `train_labels.parquet` | 96,000 | 0.6 MB | 训练标签 — `is_mule`:1 = 骡子账户,0 = 合法账户 | | `test_accounts.parquet` | 64,000 | 0.4 MB | 您需要对其进行预测的账户 ID | **总计:720 个文件,16.2 GB** **注意:** `transactions/` 和 `transactions_additional/` 被拆分到批次子目录(`batch-1/`, `batch-2/` 等)中,每个目录最多包含 100 个 part 文件。要读取所有部分: ``` import pandas as pd from glob import glob # 读取所有 transaction 部分 parts = sorted(glob("transactions/batch-*/part_*.parquet")) df = pd.concat([pd.read_parquet(p) for p in parts], ignore_index=True) ``` ### Schema **customers.parquet** | 列 | 描述 | |---|---| | `customer_id` | 唯一客户标识符 | | `date_of_birth` | 出生日期 (YYYY-MM-DD) | | `relationship_start_date` | 客户关系建立日期 | | `pan_available` | 档案中是否有 PAN 卡 (Y/N) | | `aadhaar_available` | 档案中是否有 Aadhaar (Y/N) | | `passport_available` | 档案中是否有护照 (Y/N) | | `mobile_banking_flag` | 是否注册手机银行 (Y/N) | | `internet_banking_flag` | 是否注册网上银行 (Y/N) | | `atm_card_flag` | 是否签发 ATM/借记卡 (Y/N) | | `demat_flag` | 是否关联 Demat 账户 (Y/N) | | `credit_card_flag` | 是否持有信用卡 (Y/N) | | `fastag_flag` | 是否关联 FASTag (Y/N) | | `customer_pin` | 居住地 PIN code | | `permanent_pin` | 永久地址 PIN code | **accounts.parquet** | 列 | 描述 | |---|---| | `account_id` | 唯一账户标识符 | | `account_status` | `active` 或 `frozen` | | `product_code` | 产品代码 | | `currency_code` | 货币 (1 = INR) | | `account_opening_date` | 账户开立日期 | | `branch_code` | 网点标识符 | | `branch_pin` | 网点位置 PIN code | | `avg_balance` | 平均余额(透支时可为负数) | | `product_family` | `S` (储蓄), `K` (K 系列), `O` (透支) | | `nomination_flag` | 是否登记提名 (Y/N) | | `cheque_allowed` | 是否提供支票便利 (Y/N) | | `cheque_availed` | 是否选择支票簿 (Y/N) | | `num_chequebooks` | 签发的支票簿数量 | | `last_mobile_update_date` | 最后一次手机号码更改日期 | | `kyc_compliant` | 是否符合 KYC (Y/N) | | `last_kyc_date` | 最后一次 KYC 验证日期 | | `rural_branch` | 是否为农村网点 (Y/N) | | `monthly_avg_balance` | 月平均余额 | | `quarterly_avg_balance` | 季度平均余额 | | `daily_avg_balance` | 日平均余额 | | `freeze_date` | 账户被冻结的日期(如果从未被冻结,则为空) | | `unfreeze_date` | 账户解冻的日期(如果从未解冻,则为空) | 注意:此文件中不包含 `customer_id`。请使用 `customer_account_linkage.parquet` 将账户关联到客户。 **transactions (partitioned)** | 列 | 描述 | |---|---| | `transaction_id` | 唯一交易标识符 | | `account_id` | 交易所属的账户 | | `transaction_timestamp` | ISO 格式时间戳 | | `mcc_code` | 商户类别代码 | | `channel` | 交易渠道(见下文) | | `amount` | 金额(以 INR 为单位,负值表示冲正) | | `txn_type` | `D` (借记) 或 `C` (贷记) | | `counterparty_id` | 交易对手标识符 | 交易渠道:`UPC` (UPI 贷记), `UPD` (UPI 借记), `END` (电商/POS), `IPM` (IMPS), `STD` (常设指令借记), `P2A` (付款至账户), `FTD` (资金转账借记), `NTD` (NEFT 借记), `MCR` (手机贷记), `FTC` (资金转账贷记), `MAC` (手机应用), `TPD` (第三方借记), `APD` (自动支付借记), `CHQ` (支票), `ATW` (ATM 取款), `TPC` (第三方贷记), `STC` (常设指令贷记), `OCD` (柜台存款), `RCD` (定期存款贷记), `IFD` (内部资金借记), `ETD` (电子转账借记), `NWD` (网络借记), `CSD` (现金存款), `IFC` (内部资金贷记), `PCA` (支付卡授权), `MAD` (强制扣款), `CHD` (清算所借记), `RTD` (退货借记), `CCL` (关联信用卡), `OPI` (在线支付发起), `CTC` (清算转账贷记), `SID` (系统发起借记), `ASD` (自动清算借记), `IAD` (跨账户借记), `SCW` (智能卡取款)。 **customer_account_linkage.parquet** | 列 | 描述 | |---|---| | `customer_id` | 客户标识符 | | `account_id` | 账户标识符 | 一个客户可能持有多个账户。 **product_details.parquet** | 列 | 描述 | |---|---| | `customer_id` | 客户标识符 | | `loan_sum` | 总未偿还贷款金额(可为负数) | | `loan_count` | 活跃贷款数量 | | `cc_sum` | 信用卡总未偿余额(可为负数) | | `cc_count` | 信用卡数量 | | `od_sum` | 总透支额度金额(可为负数) | | `od_count` | 透支账户数量 | | `ka_sum` | K 系列账户的总余额 | | `ka_count` | K 系列账户数量 | | `sa_sum` | 储蓄账户的总余额 | | `sa_count` | 储蓄账户数量 | **train_labels.parquet** | 列 | 描述 | |---|---| | `account_id` | 账户标识符(仅限训练集) | | `is_mule` | `1` = 骡子账户,`0` = 合法账户 | | `mule_flag_date` | 账户被标记为骡子账户的日期(合法账户为空) | | `alert_reason` | 账户被标记的原因(合法账户为空) | | `flagged_by_branch` | 报告该活动的网点代码(合法账户为空) | 注意:标签可能包含噪声/干扰项。不能保证所有标签都是正确的。 **test_accounts.parquet** | 列 | 描述 | |---|---| | `account_id` | 需要生成预测的账户 ID | **demographics.parquet** | 列 | 描述 | |---|---| | `customer_id` | 客户标识符 | | `name` | 客户全名 | | `gender` | M 或 F | | `address_last_update_date` | 最后一次地址更新日期 | | `address` | 街道地址和城市 | | `phone_number` | 电话号码 | | `passbook_last_update_date` | 最后一次存折更新日期 | | `joint_account_flag` | 是否为联名账户 (Y/N) | | `nri_flag` | 是否为非居民印度人 (Y/N) | **accounts-additional.parquet** | 列 | 描述 | |---|---| | `account_id` | 账户标识符 | | `scheme_code` | 政府计划代码 (PMJDY, PMSBY, PMJJBY, APY, SCSS, SSA, REGULAR) | **transactions_additional (partitioned)** | 列 | 描述 | |---|---| | `transaction_id` | 交易标识符(关联至 transactions) | | `mnemonic_code` | 交易类型助记符(与 channel 相同) | | `latitude` | 交易位置纬度 | | `longitude` | 交易位置经度 | | `ip_address` | 源 IP 地址 | | `balance_after_transaction` | 本次交易后的账户滚动余额 | | `part_transaction_type` | CI (客户发起), BI (银行发起), IP (已付利息), IC (已收利息) | | `atm_deposit_channel_code` | 用于 ATM 存款的 CDM 或 CRM,否则为空 | | `transaction_sub_type` | CLT_CASH, LOAN, 或 NORMAL | **branch.parquet** | 列 | 描述 | |---|---| | `branch_code` | 网点标识符 | | `branch_address` | 网点街道地址 | | `branch_pin_code` | 网点位置 PIN code | | `branch_city` | 城市 | | `branch_state` | 州代码 | | `branch_employee_count` | 网点员工人数 | | `branch_turnover` | 网点营业额指标 | | `branch_asset_size` | 网点资产规模 | | `branch_type` | 城市、半城市或农村 | ## 已知的骡子账户行为模式 已知现实世界的银行数据中存在以下洗钱模式。此数据集中的骡子账户可能表现出以下一种或多种行为: 1. **休眠激活** — 长期不活动的账户突然出现高价值交易爆发 2. **结构化** — 重复交易刚好低于报告阈值(例如,金额接近 50,000) 3. **快速过境** — 大额贷记后紧随匹配的借记(资金几乎不停留在账户中) 4. **扇入 / 扇出** — 许多小额流入聚一笔大额流出,反之亦然 5. **地理异常** — 交易地点与账户持有人的资料不符 6. **新账户高额** — 最近开立的账户具有异常高的交易量 7. **收入不匹配** — 交易价值与账户余额或客户资料不成比例 8. **更改手机后的峰值** — 更新手机号码后交易突然激增(潜在的账户接管) 9. **整数金额模式** — 不成比例地使用精确的整数金额(1K、5K、10K、50K) 10. **分层/隐蔽** — 来自多种模式组合的微弱信号,没有单一强烈的指标 11. **薪金周期利用** — 伪装在月末边界自然薪金贷记和账单支付周期内的洗钱活动 12. **网点级别串通** — 同一网点的一群可疑账户,具有共享的交易对手和协调的时间 13. **MCC-金额异常** — 交易金额对于其商户类别代码而言属于统计异常值 ## 关系 ``` customers ──(customer_id)──> customer_account_linkage ──(account_id)──> accounts | | (customer_id) (account_id) | | v v demographics transactions | (transaction_id) | v transactions_additional customers ──(customer_id)──> product_details accounts ──(account_id)──> train_labels / test_accounts accounts ──(account_id)──> accounts-additional accounts ──(branch_code)──> branch ``` ## 提交格式 ``` account_id,is_mule,suspicious_start,suspicious_end ACCT_000000,0.02,, ACCT_000003,0.87,2023-11-15T09:30:00,2024-02-20T16:45:00 ... ``` `test_accounts.parquet` 中的每个账户对应一行: - **`is_mule`**:介于 0 和 1 之间的概率得分 - **`suspicious_start`**:疑似可疑活动窗口开始的 ISO 时间戳(如果预测合法则为空) - **`suspicious_end`**:疑似可疑活动窗口结束的 ISO 时间戳(如果预测合法则为空) 时间窗口应涵盖您认为发生骡子活动的时间。主要评分基于 `is_mule`。时间窗口的准确性将作为一项奖励指标进行单独评分,使用时间 IoU(Intersection over Union,交并比)与真实活动期进行比对计算。 祝您好运。
标签:Apex, BSD, 反洗钱, 数据挖掘, 机器学习, 欺诈检测, 特征工程, 逆向工具, 金融风控