深入理解统计学中的异常值:定义、检测方法与实践指南

在数据科学和统计分析的世界里,我们经常遇到一些“不听话”的数据点。它们像是集体中的“叛逆者”,表现得与大多数观测格格不入。我们把这些数据点称为异常值

如果你曾经处理过真实世界的数据,你一定知道如果不能得到充分的识别和处理,这些异常值就像是一锅好汤里的老鼠屎,可能会导致统计分析出现严重偏差,甚至让我们得出完全错误的结论。对于金融行业的风险控制、医疗保健的异常诊断,以及任何依赖数据驱动决策的过程来说,准确地识别和处理异常值都具有极高的相关性。

在这篇文章中,我们将深入探讨异常值的定义、示例、类型、如何查找异常值,以及它们的用途和实际处理策略。我们将通过实际的代码示例,带你一步步掌握这一关键技能。

什么是异常值?

简单来说,异常值是位于数据集整体模式之外的数据点,与其他观测值显著不同。

异常值也是一个数据点,它与其在数据集中的其他记录截然不同。这种差异通常表现为数值过高或过低。如果这些极端值没有得到精确的识别和解决,它们可能会导致基于准备好的分析得出的正确结果“失序”。

异常值的成因

在深入如何检测之前,我们需要先了解它们从何而来。异常值的出现通常源于以下几种原因:

  • 数据错误: 这是最常见的原因。在数据收集或记录过程中可能会发生错误,例如拼写错误、测量设备故障或数据录入时的手误。

例子:* 在记录身高时,单位误将“厘米”记为“米”,或者手误多输入了一个零。

  • 自然变异: 数据本身可能就是非正态分布的,或者包含了真实的极端情况。这并不一定是错误,而是数据真实分布的一部分。

例子:* 在统计家庭收入时,亿万富翁的收入就是一个真实的异常值,它不是错误,但会极大地拉高平均数。

  • 实验异常: 在实验过程中,某些条件发生了意想不到的变化,导致了个别样本的反应与其他样本截然不同。

为什么我们要关注异常值?

寻找异常值在各个层面都起着重要作用,特别是在统计结论的准确性和客观性至关重要的地方:

  • skewed 统计量: 异常值可以显著影响均值和标准差,使其不再能代表数据的中心趋势。
  • 模型假设: 许多统计模型(如线性回归)假设数据呈正态分布。异常值的存在会违反这些假设,导致模型失效。

异常值的类型:极端 vs 温和

并不是所有的异常值都是“生而平等”的。根据它们偏离数据集集中趋势的程度,我们可以将异常值分类为极端异常值温和异常值。这通常基于四分位距(IQR)来判断。

1. 温和异常值

这些数据点与数据其余部分适度不同,虽然它们仍然被视为异常,但偏离程度相对较小。通常定义为落在距离四分位数 1.5 到 3 倍 IQR 范围内的值(或者正好落在 1.5 倍边界上)。

判断标准(公式):

Upper Outlier = Q3 + (1.5 * IQR)
Lower Outlier = Q1 - (1.5 * IQR)

2. 极端异常值

指那些远离平均值或中位数的数据点,通常超过四分位距(IQR)的 3 倍。这些点通常是我们需要重点关注的“致命”错误或极特殊的个案。

判断标准(公式):

Extreme Upper Outlier = Q3 + (3 * IQR)
Extreme Lower Outlier = Q1 - (3 * IQR)

类型示例解析:

假设我们有一个数据集,计算得出:INLINECODEaff891fa,INLINECODE81aa1882,IQR = 10

温和异常值边界: 上界 = 20 + (1.5 10) = 35。

* 如果有一个数值是 40,它大于 35,但小于 50(极端边界),这就是一个温和异常值(有时也统称为异常值)。

极端异常值边界: 上界 = 20 + (3 10) = 50。

* 如果有一个数值是 55,它大于 50,这就是一个极端异常值

如何识别异常值?(实战方法)

要识别数据集中的异常值,武器库中最常用的有两种方法:Tukey 方法(也常被称为箱线图法或栅栏法)Z分数 方法。虽然名字听起来很学术,但理解起来其实非常直观。

方法 1:Tukey 方法(箱线图法/IQR法)

Tukey 方法,由著名统计学家 John Tukey 提出,是一种基于四分位距的鲁棒检测方法。它的优点是不受极端值本身的干扰(不像均值那样容易被拉偏)。

#### 核心原理

想象一下你的数据排成一列。我们把它切成四份,关键点在于 Q1(25%处的数)和 Q3(75%处的数)。这两个点中间的距离(IQR)代表了数据中间 50% 的密集程度。

Tukey 设定了一个“安全区”或者说“栅栏”:

  • 下栅栏: Q1 - 1.5 × IQR
  • 上栅栏: Q3 + 1.5 × IQR

任何跑出这两个栅栏之外的数据,就被标记为异常值

#### 代码实战:使用 Python 检测异常值

让我们来看一个实际的例子。假设我们有一组测试成绩,但里面混杂了一些极其错误的分数(比如有人考了 500 分,满分才 100)。

import numpy as np

# 模拟数据集:包含一个极端值 500
data = np.array([10, 12, 14, 16, 18, 500])

def detect_outliers_iqr(dataset):
    # 步骤 1:对数据进行排序(虽然 numpy 会自动处理,但这是好习惯)
    sorted_data = np.sort(dataset)
    
    # 步骤 2:计算四分位数 Q1 (25%) 和 Q3 (75%)
    Q1 = np.percentile(dataset, 25)
    Q3 = np.percentile(dataset, 75)
    
    # 步骤 3:计算四分位距
    IQR = Q3 - Q1
    
    # 步骤 4:计算上下限(栅栏)
    lower_bound = Q1 - (1.5 * IQR)
    upper_bound = Q3 + (1.5 * IQR)
    
    print(f"Q1: {Q1}, Q3: {Q3}")
    print(f"IQR: {IQR}")
    print(f"下限: {lower_bound}, 上限: {upper_bound}")
    
    # 步骤 5:筛选出异常值
    outliers = []
    for x in dataset:
        if x  upper_bound:
            outliers.append(x)
            
    return outliers

# 执行检测
found_outliers = detect_outliers_iqr(data)
print(f"检测到的异常值: {found_outliers}")

代码解析:

在这个例子中,INLINECODEa44be670 是 12,INLINECODEb5865a14 是 18。数据的正常范围主要集中在 10 到 20 之间。IQR 是 6。

  • 正常数据的预期上限应该是 18 + 9 = 27
  • 但是,我们的数据中有一个 500
  • 500 > 27,所以程序准确地捕捉到了这个“格格不入”的家伙。

方法 2:Z分数 方法

如果你的数据呈现正态分布(钟形曲线),那么 Z分数 是另一种非常强大的方法。它告诉我们一个数据点距离平均值有多少个“标准差”。

#### 核心原理

  • 均值: 数据的中心。
  • 标准差: 数据的离散程度。
  • Z分数公式: Z = (X - 平均值) / 标准差

在正态分布中:

  • 大约 68% 的数据落在距离平均值 1 个标准差范围内。
  • 大约 95% 的数据落在距离平均值 2 个标准差范围内。
  • 大约 99.7% 的数据落在距离平均值 3 个标准差范围内。

经验法则: 通常,如果一个数据点的 Z分数 绝对值大于 3,我们就可以认为它是一个异常值。

#### 代码实战:Z分数检测

让我们用一组更接近正态分布的数据来看看这个方法。

import numpy as np

# 模拟正态分布数据:均值为 25,标准差为 4
# 我们故意构建一个数据集,其中 30 是相对正常的,但 45 是可疑的
# 注意:真实场景下数据量需要足够大才能体现正态性
data = np.array([20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 45]) 

def detect_outliers_zscore(dataset):
    threshold = 2  # 设定阈值,通常为 2.5 或 3,这里设为 2 用于演示
    
    mean = np.mean(dataset)
    std_dev = np.std(dataset)
    
    print(f"平均值: {mean}, 标准差: {std_dev}")
    
    outliers = []
    for x in dataset:
        z_score = (x - mean) / std_dev
        print(f"数值 {x} 的 Z分数: {z_score:.2f}")
        if np.abs(z_score) > threshold:
            outliers.append(x)
            
    return outliers

# 执行检测
found_outliers = detect_outliers_zscore(data)
print(f"检测到的异常值 (阈值=2): {found_outliers}")

深入理解:

在这个例子中:

  • 30 的 Z分数计算为 (30 - 25) / 4 = 1.25。这意味着它只比平均值高了 1.25 个标准差。这在统计学上是非常常见的,所以它不是异常值
  • 45 的 Z分数计算为 (45 - 25) / 4 = 5.0。这意味着它比平均值高出了 5 个标准差!这在正态分布中发生的概率极低(小于 0.00003%)。因此,45 是一个强烈的异常值

异常值的实际应用与处理策略

当我们找到了异常值,接下来该怎么办?直接删除吗?不一定。这取决于异常值的性质和分析的目标。

场景 1:数据清洗(如果是错误)

如果异常值是由于数据错误(如录入错误、传感器故障)造成的,我们的目标通常是修正或删除它们,以免污染模型。

  • 策略: 删除、视为缺失值处理、或者用相邻值的平均值填充(插值法)。
  • 注意: 删除前最好标记出来,检查一下是否真的全是错误。

场景 2:欺诈检测(如果是信号)

在金融交易监控中,异常值不是“噪音”,而是信号

  • 例子: 一张平时在国内消费的信用卡,突然在亚马逊热带雨林有一笔巨额消费。这个“异常值”可能代表着信用卡被盗刷。
  • 策略: 建立预警系统,实时捕捉这些异常值进行人工审核。

场景 3:性能优化(鲁棒性)

有时候,我们不想删除异常值,但也不想被它们影响。我们需要使用对异常值不敏感的统计量。

  • 用中位数代替平均数: 就像我们在文章开头提到的,如果你在酒吧里,比尔·盖茨走了进来,大家的“平均财富”会瞬间变成亿万富翁,但这没有意义。这时,“中位数财富”依然能反映真实情况。
  • 算法选择: 使用基于树的模型(如随机森林、XGBoost),它们通常对异常值比线性回归更鲁棒。

最佳实践:处理异常值的流程建议

作为一名开发者,当你拿到数据集时,建议遵循以下流程:

  • 可视化先行: 在做任何数学计算前,先用箱线图或散点图把数据画出来。人类的眼睛识别模式的能力很强,一眼就能看出那些“孤零零的点”。
  • 分段处理: 不要只看总体,有时一个值在总体上看是异常,但在特定子群中是正常的(例如:新生儿体重 3kg 正常,但成年人 3kg 就是异常)。
  • 记录决策: 如果你决定删除某个异常值,一定要在代码注释或文档中记录原因(例如:“删除了超过 3 倍标准差的数据点,推测为传感器故障”)。这有助于后续的代码审查和模型解释。

总结

异常值是数据分析中不可避免的一部分。它们既可能是干扰我们分析的噪音,也可能是隐藏着重大发现的金矿。

在这篇文章中,我们学习了:

  • 定义: 什么是异常值及其成因。
  • 类型: 区分温和异常值与极端异常值。
  • 检测: 掌握了基于 IQR 的 Tukey 方法和基于标准差的 Z分数 方法。
  • 代码实践: 通过 Python 代码亲手实现了检测逻辑。

下一步建议:

在你的下一个项目中,尝试加入异常值检测的步骤。不要仅仅满足于计算出平均值,试着看看那些“不在预期内”的数据,问问它们“为什么在这里”。你会发现,数据的故事往往就藏在这些异常之中。

希望这篇文章能帮助你更好地理解统计数据中的异常值,如果你在代码实现中有任何问题,欢迎随时交流探讨。

声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。如需转载,请注明文章出处豆丁博客和来源网址。https://shluqu.cn/42376.html
点赞
0.00 平均评分 (0% 分数) - 0