第三章 数据探索与可视化:交易金额与时间分布
数据拿到手,别急着建模。我个人的习惯是,先花半小时做探索性分析。这一步看似简单,但能帮你避开很多坑。说白了,就是先跟数据「混个脸熟」。
本章我们聚焦两个核心维度:交易金额和交易时间。异常交易往往在这两个维度上露出马脚。
3.1 用Pandas快速概览数据
先加载数据,看看整体面貌。我一般用这几行代码起手:
import pandas as pd
import numpy as np
# 加载交易数据
df = pd.read_csv('transaction_data.csv')
# 快速概览
print(df.head())
print(df.info())
print(df.describe())
head() 看前5行,确认字段名和数据类型。info() 检查缺失值和内存占用。describe() 看数值列的统计分布。
df.sample(10000) 先抽样看看。别一上来就全量加载,容易把内存撑爆。
我曾经接手过一个项目,数据有500万行,直接 head() 没问题,但 describe() 跑了快两分钟。后来发现是金额字段被读成了字符串,内部做了类型转换。嗯,这里要注意——数据类型不对,后续所有统计都会出问题。
3.2 交易金额分布:直方图与箱线图
交易金额的分布,能直接反映是否存在极端值。正常交易金额通常集中在某个区间,而异常交易往往金额特别大或特别小。
3.2.1 绘制直方图
import matplotlib.pyplot as plt
import seaborn as sns
plt.figure(figsize=(10, 6))
sns.histplot(df['amount'], bins=50, kde=True)
plt.title('交易金额分布直方图')
plt.xlabel('交易金额')
plt.ylabel('频次')
plt.show()
为什么用 kde=True?因为核密度估计曲线能帮你看出分布的「形状」。如果曲线在右侧拖了一个长长的尾巴,那大概率存在高额异常交易。
- 分布是否集中?正常交易金额通常呈右偏分布
- 是否有明显的离群点?比如金额是平均值的10倍以上
- 是否有奇怪的「尖峰」?比如大量交易恰好是1000元整——这可能是刷单行为
3.2.2 箱线图看异常值
plt.figure(figsize=(8, 4))
sns.boxplot(x=df['amount'])
plt.title('交易金额箱线图')
plt.show()
箱线图的好处是,它用四分位数和IQR(四分位距)来定义异常值。超出上下须的点,就是潜在的异常交易。我个人习惯把箱线图和直方图放在一起看,互相印证。
3.3 交易时间分布:时序与周期
交易时间能揭示行为模式。正常用户有作息规律,而异常交易往往发生在「不该出现」的时间段。
3.3.1 按小时统计交易量
# 假设时间字段是 'timestamp'
df['hour'] = pd.to_datetime(df['timestamp']).dt.hour
hourly_counts = df.groupby('hour').size()
plt.figure(figsize=(12, 5))
sns.barplot(x=hourly_counts.index, y=hourly_counts.values)
plt.title('各小时交易量分布')
plt.xlabel('小时')
plt.ylabel('交易笔数')
plt.show()
你想想看,凌晨3点突然出现大量交易,这正常吗?大概率是机器在刷单。我见过一个案例,某平台凌晨2点到5点的交易量占全天40%,后来一查,全是薅羊毛的脚本在跑。
3.3.2 按星期几统计
df['weekday'] = pd.to_datetime(df['timestamp']).dt.weekday
weekday_counts = df.groupby('weekday').size()
plt.figure(figsize=(10, 5))
sns.barplot(x=weekday_counts.index, y=weekday_counts.values)
plt.title('各星期交易量分布')
plt.xlabel('星期(0=周一)')
plt.ylabel('交易笔数')
plt.show()
正常交易在工作日和周末会有明显差异。如果某个星期几的交易量突然暴增,或者周末交易量比工作日还高,那就要警惕了。
3.4 核心逻辑:数据探索的流程
下面这张图,是我做数据探索时常用的流程。你可以把它当作一个检查清单:
3.5 实战:综合可视化
把金额和时间结合起来看,效果更好。比如,按小时统计平均交易金额:
hourly_amount = df.groupby('hour')['amount'].mean()
plt.figure(figsize=(12, 5))
sns.lineplot(x=hourly_amount.index, y=hourly_amount.values, marker='o')
plt.title('各小时平均交易金额')
plt.xlabel('小时')
plt.ylabel('平均金额')
plt.grid(True, alpha=0.3)
plt.show()
如果某个小时的平均金额突然飙升,那很可能有异常交易混入。我记得有一次,发现凌晨4点的平均金额是白天的5倍,后来查出来是某个商户在批量刷大额交易。
3.6 本章小结
数据探索不是走过场。它帮你回答三个问题:
- 数据长什么样?——分布、范围、缺失情况
- 哪里可能有问题?——异常值、离群点、时间模式
- 下一步该做什么?——特征工程、数据清洗、模型选择
做完这一步,你心里就有底了。接下来,我们才能放心地进入特征工程环节。
- 用
describe()和info()做快速概览 - 直方图 + 箱线图,双图验证金额分布
- 按小时和星期统计交易量,发现时间维度的异常
- 交叉验证,别被单一图表误导
好了,数据探索就到这里。记住,好的模型,始于对数据的深刻理解。
公众号:蓝海资料掘金营,微信deep3321