3. 异常值检测与处理

异常值检测与处理 学习卡片

案例3:异常值检测(IQR法)——识别数值列异常值

一、案例目标与场景

在信贷审批系统中,客户收入、负债、年龄等数值字段常因录入错误、欺诈行为或极端真实情况产生异常值。若不处理,将直接影响信用评分的稳定性与模型训练效果。本案例聚焦于使用四分位距法(IQR)对数值列进行异常值识别,并借助箱线图(boxplot)可视化验证检测结果。

二、技术原理与实现路径

IQR法基于数据分布的分位数进行检测:

  • 计算第一四分位数(Q1,25%分位)与第三四分位数(Q3,75%分位);
  • 定义四分位距:IQR = Q3 - Q1;
  • 设定异常值边界:下界 = Q1 - 1.5 × IQR,上界 = Q3 + 1.5 × IQR;
  • 超出边界的样本点即判定为异常值。

该方法不依赖数据分布假设,计算高效,适合信贷字段的快速筛查。实现路径为:加载数据 → 逐列计算IQR边界 → 标记异常 → 箱线图可视化验证。

三、关键代码实现

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

# 示例数据:模拟信贷客户收入与年龄字段
data = {
    'age': [25, 32, 45, 58, 23, 41, 36, 29, 51, 44, 120, 33, 47, 38, 26],
    'annual_income': [50000, 62000, 88000, 95000, 43000, 78000, 69000, 55000, 120000, 81000, 999999, 72000, 91000, 67000, 48000]
}
df = pd.DataFrame(data)

def detect_outliers_iqr(series):
    """使用IQR法检测异常值,返回布尔掩码(True=异常)"""
    Q1 = series.quantile(0.25)
    Q3 = series.quantile(0.75)
    IQR = Q3 - Q1
    lower_bound = Q1 - 1.5 * IQR
    upper_bound = Q3 + 1.5 * IQR
    return (series < lower_bound) | (series > upper_bound)

# 对每一列执行检测
for col in df.columns:
    outlier_mask = detect_outliers_iqr(df[col])
    print(f"{col} 列异常值索引: {df.index[outlier_mask].tolist()}")
    print(f"异常值个数: {outlier_mask.sum()}")

# 箱线图可视化验证
fig, axes = plt.subplots(1, 2, figsize=(10, 4))
df.boxplot(column='age', ax=axes[0])
df.boxplot(column='annual_income', ax=axes[1])
plt.tight_layout()
plt.show()

四、验证路径与预期现象

运行上述代码后,控制台输出显示:age列索引为10(值120)被标记为异常;annual_income列索引为10(值999999)被标记为异常。箱线图中,这两个点以“○”形式显示在须线之外,直观验证了IQR检测的有效性。实际业务中,可将检测结果与人工复核结合,区分“录入错误”与“真实高净值客户”。

IQR异常值检测流程与边界示意 年龄分布 120岁(异常) Q3 (75%) 中位数 Q1 (25%) 下界 = Q1 - 1.5×IQR 上界 = Q3 + 1.5×IQR IQR边界计算 Q1 = 29.0, Q3 = 47.0 IQR = 47.0 - 29.0 = 18.0 下界 = 29.0 - 1.5×18.0 = 2.0 上界 = 47.0 + 1.5×18.0 = 74.0 → 120 > 74,判定为异常 计算Q1/Q3 求IQR与边界 标记异常点 箱线图验证

五、可迁移要点

  • IQR法对偏态分布稳健,适合收入、负债等长尾字段;
  • 边界系数1.5为默认值,业务中可调整为3.0以放宽检测;
  • 检测结果务必结合业务复核,避免误杀真实高价值客户。