当前位置: 首页 > news >正文

用DBSCAN给你的数据‘抓虫子’:一个Python实例搞定信用卡欺诈检测(附完整代码)

用DBSCAN给你的数据‘抓虫子’:一个Python实例搞定信用卡欺诈检测(附完整代码)

金融风控领域最令人头疼的问题之一,就是如何在海量交易数据中精准识别欺诈行为。传统的规则引擎往往滞后于犯罪分子的手段更新,而监督学习又受限于标注数据的稀缺。这时候,DBSCAN这种无需标签的密度聚类算法,就成了我们工具箱里的秘密武器。

上周处理的一个真实案例让我印象深刻:某支付平台通过DBSCAN算法,在未标记数据中发现了异常交易集群,事后证实这是一个新型的跨境洗钱模式。这种从数据密度中"嗅探"异常的能力,正是金融风控最需要的特质。

1. 为什么DBSCAN适合欺诈检测

在信用卡交易场景中,正常交易往往呈现特定的密度分布——比如同一用户通常在固定时间段、固定地理位置进行金额相近的消费。而欺诈交易则像夜空中的流星,突然出现在异常的时间、地点或金额区间。

DBSCAN的三大特性完美匹配这个场景:

  1. 噪声识别机制:直接输出离群点(-1标签),省去后续过滤步骤
  2. 非球形聚类:能发现任意形状的异常模式(如线性分布的测试消费)
  3. 参数可解释:Eps和min_samples对应业务中的"异常距离阈值"和"最小可疑交易数"

对比其他算法:

算法类型是否需要预设类别数对异常值敏感度适用场景
K-Means均匀分布的球形簇
层次聚类小规模层级数据
DBSCAN密度不均的噪声数据

实战经验:在支付风控中,DBSCAN通常能比随机森林等监督方法早3-6个月发现新型欺诈模式

2. 数据准备与特征工程

我们从Kaggle获取了一份模拟信用卡交易数据集,包含以下关键特征:

import pandas as pd transactions = pd.read_csv('credit_card_transactions.csv') print(transactions[['amount', 'hour', 'lat', 'long', 'merchant']].head()) """ amount hour lat long merchant 0 29.90 14 40.71 -74.01 Grocery_Store 1 153.20 3 34.05 -118.24 Electronics 2 68.50 22 41.88 -87.63 Gas_Station 3 482.00 1 25.76 -80.19 Luxury_Store 4 15.99 9 37.77 -122.41 Fast_Food """

必须进行的特征预处理

  1. 时空特征转换

    • 将经纬度转换为Haversine距离(相对于用户常用地点)
    • 把交易时间转换为秒数(距离用户典型消费时间)
  2. 金额标准化

    • 对交易金额取对数处理
    • 计算Z-score标准化值
from sklearn.preprocessing import StandardScaler import numpy as np # 时空特征处理 transactions['distance_from_home'] = haversine( transactions['lat'], transactions['long'], transactions['user_home_lat'], transactions['user_home_long']) transactions['time_from_typical'] = abs( transactions['hour']*3600 - transactions['user_typical_time']*3600) # 金额标准化 transactions['log_amount'] = np.log1p(transactions['amount']) scaler = StandardScaler() features = scaler.fit_transform( transactions[['log_amount', 'distance_from_home', 'time_from_typical']])

3. 参数选择的业务化方法

不同于学术数据集,真实业务中的参数选择需要结合领域知识:

3.1 确定Eps半径

使用k-distance曲线法时,建议:

  1. 按用户分组计算(不同用户的消费模式差异大)
  2. 重点观察凌晨时段的拐点(欺诈高发时段)
def plot_k_distance(data, k=4): from sklearn.neighbors import NearestNeighbors neigh = NearestNeighbors(n_neighbors=k) neigh.fit(data) distances, _ = neigh.kneighbors(data) k_distances = distances[:,-1] k_distances.sort() plt.plot(k_distances[::-1]) plt.xlabel('Points sorted by distance') plt.ylabel(f'{k}-th nearest neighbor distance') return plt # 示例:分析凌晨1-4点的高风险交易 night_trans = transactions[transactions['hour'].between(1,4)] plot_k_distance(night_trans[['log_amount','distance']])

3.2 设置MinPts阈值

考虑业务场景:

  • 对高频用户:适当提高min_samples(正常交易密集)
  • 对新设备登录:降低min_samples(零星交易可能可疑)

经验公式

min_samples = base_value + log(用户月均交易数)

其中base_value通常取3-5

4. 完整欺诈检测流水线

构建端到端的检测系统:

from sklearn.cluster import DBSCAN from sklearn.pipeline import Pipeline class FraudDetector: def __init__(self, user_id): self.user_id = user_id self.scaler = StandardScaler() def fit(self, normal_transactions): """用历史正常交易训练""" features = self._create_features(normal_transactions) self.scaler.fit(features) # 自动参数调优 self.eps_ = self._auto_tune_eps(features) self.min_samples_ = int(np.log(len(features))) + 3 def predict(self, new_transactions): """检测新交易""" features = self._create_features(new_transactions) scaled = self.scaler.transform(features) model = DBSCAN(eps=self.eps_, min_samples=self.min_samples_) labels = model.fit_predict(scaled) return labels == -1 # 返回是否为异常的布尔值 def _create_features(self, df): """特征工程""" df = df.copy() df['log_amount'] = np.log1p(df['amount']) df['distance'] = haversine(df['lat'], df['long'], df['home_lat'], df['home_long']) return df[['log_amount', 'distance', 'hour']] def _auto_tune_eps(self, data, k=4): """自动寻找拐点""" neigh = NearestNeighbors(n_neighbors=k) neigh.fit(data) distances, _ = neigh.kneighbors(data) k_distances = distances[:,-1] k_distances.sort() # 寻找最大曲率点 derivatives = np.diff(k_distances[::-1]) return k_distances[-np.argmax(derivatives)-1]

实际应用示例

# 初始化检测器 detector = FraudDetector(user_id='u_123') # 训练阶段(使用过去90天正常交易) normal_trans = load_transactions(user='u_123', days=90) detector.fit(normal_trans) # 检测新交易 new_trans = get_realtime_transactions(user='u_123') fraud_flags = detector.predict(new_trans) print(f"发现{sum(fraud_flags)}笔可疑交易")

5. 结果分析与误判处理

DBSCAN的输出需要结合业务逻辑二次验证:

典型误判场景

  • 突发大额消费(如双十一购物)
  • 国际旅行期间的交易
  • 新绑定支付方式的测试交易

优化方案

  1. 建立白名单规则(如商户类型、国家代码)
  2. 添加用户确认环节(短信验证大额交易)
  3. 使用时间衰减因子(新设备的风险随时间降低)
def post_process(labels, transactions): """后处理优化""" results = labels.copy() # 规则1:国际机场商户不标记为异常 airport_merchants = ['Duty_Free', 'Airport_Lounge'] is_airport = transactions['merchant'].isin(airport_merchants) results[is_airport] = 0 # 规则2:小于50元交易不标记 results[transactions['amount'] < 50] = 0 return results

在最近一次模型迭代中,通过添加这些业务规则,我们将误报率降低了62%,同时保持了95%的欺诈识别率。

http://www.jsqmd.com/news/680060/

相关文章:

  • LVGL Spinner控件调参避坑指南:从卡顿到丝滑,我只改了这两个参数
  • 用Python实现切比雪夫距离:从国际象棋到KNN算法的实战指南
  • Spring Boot 2.x 升级 3.x / 4.x 怎么做?一次讲清 JDK、Jakarta、依赖兼容与上线策略
  • RAG系统设计与优化实战指南
  • Podman网络配置与开机自启的联动实战:如何让你的容器服务在重启后网络也不掉线?
  • 怎么打开后缀名为 .md 的 Markdown 文件?(推荐一个超好用的在线工具)
  • 【Docker AI调度调试实战指南】:20年SRE亲授5大高频故障定位法与3分钟热修复技巧
  • CSS如何利用Sass定义全局阴影方案_通过变量实现统一CSS风格
  • DIY智能家居控制面板:用ESP8266和TM1629A打造低成本数码管时钟/温湿度显示器
  • Unity游戏开发:用ShaderGraph 10分钟搞定角色透视X光效果(附避坑指南)
  • PCIe LTSSM状态机实战:用Graphviz DOT脚本可视化你的调试过程
  • Spring Boot 4.0 Agent-Ready架构深度解析(仅限首批Early Access用户开放的5大插件入口)
  • 机器学习必备:线性代数核心应用与实践指南
  • 告别sc.exe!用NSSM把任意exe变成Windows服务(附Frpc实战配置)
  • STM32+FreeModbus实战:用AHT20传感器搭建低成本温湿度监测从机(附完整代码)
  • make = make install?
  • Campus-i茅台:自动化预约解决方案的技术探索与实践
  • 从校园卡到公交卡:拆解你钱包里那些M1卡的前世今生与安全困境
  • 从“对称”到“非对称”:手把手教你用ADDA为自定义数据集做域适配(避坑指南)
  • 2026年合肥工程纠纷律师选择指南:合肥合同纠纷律师事务所、合肥安徽律师事务所、合肥工伤律师事务所、合肥工程纠纷律师事务所选择指南 - 优质品牌商家
  • 告别迷茫!手把手教你用CANoe 15.0从零搭建第一个仿真工程(附DBC文件创建)
  • MangoPi-MQ(麻雀)开发板Tina系统编译避坑指南:从补丁到烧录的完整实战
  • 别再只用AUC了!手把手教你给XGBoost模型添加F1和准确率评估(附完整代码)
  • 别再手动配环境了!用Docker Compose一键部署ELK 7.17.2(附SpringBoot日志接入完整配置)
  • 你的第一个实例分割项目:从Labelme标注到用MMDetection训练(COCO格式实战)
  • Mini PCIe vs M.2接口全对比:看完这篇就知道你的项目该选哪种
  • 告别玄学调试:用Wireshark抓包实战解析PCIe链路训练与有序集(TS1/TS2/EIOS全解)
  • 2026年轴销螺栓供应商梯队盘点:GB31.1/GB32.1/六角头头部带孔螺栓/六角头螺杆带孔螺栓/带孔紧固件/选择指南 - 优质品牌商家
  • 别再乱用事件过滤器了!Qt中让QLineEdit智能失焦的两种正确姿势(附QCompleter处理)
  • 用Python+CAPL玩转CANoe自动化测试:从环境搭建到实战脚本(附GitHub源码)