1. 从零开始:理解信用卡欺诈检测的挑战
大家好,我是老张,在金融风控领域摸爬滚打了十来年,经手过的反欺诈模型项目少说也有几十个。今天想和大家聊聊一个非常经典,但也让无数新手头疼的实战项目——信用卡欺诈检测。如果你刚接触机器学习,想找一个能串联起数据清洗、特征工程、模型调优全流程的练手项目,那这个Kaggle上的信用卡欺诈数据集绝对是你的不二之选。
这个项目听起来高大上,但核心问题其实很直接:给你一堆信用卡交易记录,让你用算法判断哪一笔是盗刷。听起来像侦探破案,对吧?但难点在于,数据极度不平衡。想象一下,你检查了10万笔交易,其中只有172笔是欺诈,就像大海捞针。如果你让一个模型去学,它很可能“偷懒”,把所有交易都预测为“正常”,这样准确率高达99.8%以上,看起来漂亮极了,但一个欺诈都没抓到,模型完全没用。这就是我们面临的第一个,也是最核心的挑战:数据不平衡。不解决它,后续所有模型构建都是空中楼阁。
除了数据不平衡,这个数据集本身也很有特点。出于隐私保护,原始特征(比如交易商户、地点)都被PCA(主成分分析)处理过了,变成了V1到V28这28个神秘的数字特征。我们能直接用的只有“时间”和“交易金额”。这要求我们不能简单地套用模型,必须深入理解数据,做好特征工程,从有限的信息里挖出“金子”。整个流程,从数据导入、探索分析,到处理不平衡、训练模型、调参优化,再到最后根据业务选择阈值,是一套完整的机器学习实战链路。接下来,我就带你一步步走通它,分享我踩过的坑和验证过的好方法。
2. 数据预处理与探索性分析:像侦探一样审视数据
拿到数据后的第一步,绝不是急着跑模型。我习惯先花足够的时间“把玩”数据,理解它的每一寸肌肤。这就像侦探勘察现场,任何细节都可能成为破案关键。我们用的数据集来自Kaggle,包含了欧洲持卡人两天内的28万多笔交易,其中欺诈交易仅有492笔,占比0.172%。
2.1 数据初窥与质量检查
首先,我们得看看数据长什么样,有没有“硬伤”。用Pandas加载数据后,head()、tail()、info()、describe()这几个函数是我的标准动作。
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
import warnings
warnings.filterwarnings('ignore')
# 加载数据
data = pd.read_csv('creditcard.csv')
print(f"数据形状: {data.shape}")
print(data.info())
print(data.describe())
运行后你会发现,数据有31列,从Time、V1...V28到Amount和Class。好消息是,info()显示所有字段都是非空的,没有缺失值,这省去了我们处理缺失值的大麻烦。describe()则能快速查看数值特征的统计分布,比如Amount(金额)的均值、标准差,你会发现它的范围波动很大,从0到几万,这提示我们后续可能需要做标准化。
2.2 深入洞察:可视化揭示数据秘密
数字是冰冷的,图表却能讲故事。对于不平衡数据,我们首先要看清“不平衡”到什么程度。
# 查看目标变量分布
fig, axs = plt.subplots(1, 2, figsize=(14, 5))
sns.countplot(x='Class', data=data, ax=axs[0])
axs[0].set_title('欺诈与非欺诈交易数量')
data['Class'].value_counts().plot.pie(autopct='%1.2f%%', ax=axs[1])
axs[1].set_title('类别占比')
plt.show()
图表会直观地告诉你,正常交易(Class=0)的柱子高耸入云,而欺诈交易(Class=1)的柱子几乎贴着地面。这再次强调了处理不平衡问题的紧迫性。
接下来,分析欺诈行为的特点。我通常会从时间和金额两个维度入手:
-
交易时间分析:原始‘Time’特征是以秒为单位的连续值,不利于分析。我通常会将其转换为小时‘Hour’,看看欺诈是否集中在特定时段。
data['Hour'] = data['Time'].apply(lambda x: int(x // 3600) % 24)然后绘制欺诈交易在不同小时的分布图。我常发现,欺诈交易在深夜至凌晨(比如0点到6点)的相对比例可能更高,因为这时真实用户活跃度低,不易被察觉。
-
交易金额分析:比较欺诈交易和正常交易的金额分布。
f, (ax1, ax2) = plt.subplots(2, 1, sharex=True, figsize=(12,8)) ax1.hist(data[data['Class']==1]['Amount'], bins=50, color='red', alpha=0.7) ax1.set_title('欺诈交易金额分布') ax1.set_yscale('log') # 因为欺诈交易少,用对数坐标更清晰 ax2.hist(data[data['Class']==0]['Amount'], bins=100, color='blue', alpha=0.7) ax2.set_title('正常交易金额分布') ax2.set_yscale('log') plt.xlabel('Amount ($)') plt.show()你往往会发现,欺诈交易的金额大多较小且分散。盗刷者为了不触发风控警报,倾向于进行多次小额测试或消费。
-
特征间关系分析:虽然V1-V28是PCA结果,含义不明,但我们仍可以观察它们在欺诈和正常样本中的分布差异。使用
seaborn的distplot或kdeplot绘制同一特征在两

1139

被折叠的 条评论
为什么被折叠?



