3. 数据探索与可视化:使用Pandas进行数据概览、Matplotlib/Seaborn绘制分布图与箱线图识别异常

在坏样本归因任务中,数据探索与可视化是连接原始数据与特征工程的桥梁。本章将系统讲解如何利用 Pandas 进行高效的数据概览,并借助 Matplotlib 与 Seaborn 绘制分布图与箱线图,从而快速定位异常值与数据分布特征。

3.1 使用Pandas进行数据概览

Pandas 提供了丰富的方法来快速了解数据集的全貌,包括数据维度、列类型、缺失值分布以及基本统计量。

方法 功能描述 关键参数/输出
df.info() 打印 DataFrame 的摘要信息 行数、列数、列数据类型、非空计数、内存使用
df.describe() 生成数值型列的统计摘要 均值、标准差、最小值、四分位数、最大值
df.isnull().sum() 统计每列的缺失值数量 返回 Series,索引为列名,值为缺失数
df.nunique() 统计每列的唯一值数量 适用于类别型特征的基数检查
df.head() / df.sample() 预览数据前几行或随机抽样 默认 head() 显示前5行
实战要点: 在坏样本场景中,务必先检查 df['label'].value_counts() 以确认正负样本比例。若坏样本占比低于 5%,后续可视化与建模需考虑采样或代价敏感策略。
import pandas as pd

# 加载数据
df = pd.read_csv('bad_sample_data.csv')

# 数据概览
print("=== 数据基本信息 ===")
df.info()

print("\n=== 数值列统计描述 ===")
print(df.describe())

print("\n=== 缺失值统计 ===")
print(df.isnull().sum())

print("\n=== 标签分布 ===")
print(df['label'].value_counts(normalize=True))

3.2 分布图:理解单变量分布

分布图用于观察单个特征的数值分布形态,帮助识别偏态、多峰以及潜在的异常值区间。Seaborn 的 histplot 和 kdeplot 是首选工具。

  • 直方图 (Histogram):将数据分箱,展示每个箱内的样本频数。
  • 核密度估计 (KDE):平滑的连续概率密度曲线,便于观察分布形状。
  • 联合分布图 (JointPlot):同时展示两个变量的分布与散点关系。
import matplotlib.pyplot as plt
import seaborn as sns

# 设置中文字体
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False

# 绘制单变量分布图
fig, axes = plt.subplots(1, 2, figsize=(12, 4))

# 直方图 + KDE
sns.histplot(df['feature_amount'], bins=50, kde=True, ax=axes[0])
axes[0].set_title('特征 amount 分布 (含KDE)')

# 按标签分组绘制KDE
sns.kdeplot(data=df, x='feature_amount', hue='label', fill=True, ax=axes[1])
axes[1].set_title('按标签分组的KDE分布')

plt.tight_layout()
plt.show()
识别异常信号: 若分布图在远离主体数据的位置出现孤立小峰,或 KDE 曲线出现长尾拖拽,通常意味着该特征中存在极端值或坏样本特有的分布偏移。

3.3 箱线图:识别异常值的标准工具

箱线图通过五数概括(最小值、Q1、中位数、Q3、最大值)直观展示数据分布,并将超出 1.5 倍 IQR 范围的点标记为异常值。

箱线图元素 含义 异常判定规则
箱体 (Box) Q1 到 Q3 的范围,包含 50% 的数据 —
中位线 (Median) 箱体内部的横线,表示第 50 百分位数 —
须 (Whisker) 从箱体延伸至非异常值的最远点 上限 = Q3 + 1.5 * IQR;下限 = Q1 - 1.5 * IQR
异常点 (Flier) 超出须范围的点,以菱形标记 超出 1.5 倍 IQR 即为潜在异常
# 绘制箱线图
plt.figure(figsize=(10, 5))
sns.boxplot(data=df[['feature_amount', 'feature_age', 'feature_score']])
plt.title('多个特征的箱线图对比')
plt.xticks(rotation=45)
plt.show()

# 按标签分组绘制箱线图
plt.figure(figsize=(8, 4))
sns.boxplot(x='label', y='feature_amount', data=df)
plt.title('按标签分组的箱线图 (坏样本 vs 好样本)')
plt.show()
注意: 箱线图标记的异常值不一定是“坏样本”,它仅代表统计意义上的极端值。在坏样本归因中,需要结合业务逻辑判断:某些极端值可能是正常的高价值交易,而非欺诈或坏账。

3.4 数据探索与异常识别流程

下图展示了从原始数据到异常识别的完整可视化分析流程,帮助你在实战中建立系统性的探索路径。

数据探索与异常识别流程图 原始数据集 Pandas 数据概览 分布图 (Hist/KDE) 箱线图 (BoxPlot) 异常值识别与归因 结合业务规则与统计方法,区分“统计异常”与“业务坏样本”

3.5 实战案例:从可视化到异常标记

以下代码演示了如何结合分布图与箱线图的结果,对识别出的异常值进行标记,为后续的坏样本归因提供特征层面的证据。

# 基于箱线图规则标记异常
def mark_outliers_iqr(df, column):
    Q1 = df[column].quantile(0.25)
    Q3 = df[column].quantile(0.75)
    IQR = Q3 - Q1
    lower_bound = Q1 - 1.5 * IQR
    upper_bound = Q3 + 1.5 * IQR
    return ((df[column] < lower_bound) | (df[column] > upper_bound))

# 对关键特征标记异常
df['amount_outlier'] = mark_outliers_iqr(df, 'feature_amount')
df['score_outlier'] = mark_outliers_iqr(df, 'feature_score')

# 查看异常样本与坏样本的重叠情况
cross_tab = pd.crosstab(df['amount_outlier'], df['label'], 
                         margins=True, margins_name='总计')
print("异常标记与标签的交叉表:")
print(cross_tab)

# 可视化异常样本的分布
plt.figure(figsize=(8, 4))
sns.scatterplot(data=df, x='feature_amount', y='feature_score', 
                hue='amount_outlier', style='label', alpha=0.6)
plt.title('异常标记与标签的散点分布')
plt.show()
关键洞察: 在坏样本归因项目中,可视化不是终点,而是特征工程的起点。通过分布图发现偏态分布后,可考虑对数变换或分箱;通过箱线图识别异常后,可构建“是否异常”的二值特征,或对极端值进行截断处理。