2. 数据分布与统计基础:均值、中位数、标准差、四分位数、箱线图原理

聊到异常值检测,咱们得先打好地基。说白了,你得先知道“正常”长什么样,才能揪出那些“不正常”的家伙。这一节,我就带你过一遍最常用的几个统计量,以及它们背后的逻辑。

2.1 均值与中位数:两个“中心”的故事

均值,就是咱们常说的平均数。把所有数加起来,除以个数,搞定。它很直观,但有个致命弱点——怕“被平均”。

举个例子,一个小区里,九户人家月收入都是5000块,突然搬来一户月入500万的。这时候均值会被瞬间拉高,完全不能代表“普通人家”的水平了。我在处理环境监测数据时,就遇到过类似情况。某个传感器偶尔跳出一个离谱的读数,均值立马就“漂移”了。

中位数,就稳得多。把数据从小到大排好,取中间那个数。如果数据量是偶数,就取中间两个数的平均值。它不受极端值影响,能更真实地反映数据的“中心位置”。

核心区别:

  • 均值:对异常值敏感,适合数据分布对称、没有极端值的情况。
  • 中位数:对异常值稳健,适合数据分布偏斜或存在极端值的情况。

我个人习惯,拿到数据第一件事,就是同时看均值和位数。如果两者差距很大,那基本可以断定——数据里有“刺头”。

2.2 标准差:数据有多“散”

均值告诉你“中心在哪”,标准差告诉你“大家离中心有多远”。

公式不复杂:每个数减去均值,平方,求和,除以个数,再开方。嗯,我知道你看着公式头疼。咱们换个说法:标准差越大,数据越“散”;标准差越小,数据越“聚”。

我在做空气质量监测项目时,经常用标准差来判断传感器的稳定性。如果某个站点PM2.5的标准差突然变大,那要么是天气突变,要么是传感器出问题了。你想想看,一个稳定的监测点,数据波动不该那么大。

避坑指南: 我曾经犯过一个错,直接用标准差判断异常值。后来发现,如果数据本身不是正态分布,用“均值±3倍标准差”来划界限,会漏掉很多真正的异常。所以,别迷信这个“3σ法则”,得先看看数据长什么样。

2.3 四分位数:把数据切成四份

如果说中位数是把数据切成两半,那四分位数就是切成四份。

  • Q1(第一四分位数):排在25%位置的那个数。
  • Q2(第二四分位数):就是中位数,排在50%位置。
  • Q3(第三四分位数):排在75%位置的那个数。

四分位距(IQR) = Q3 - Q1。这个IQR特别有用,它衡量的是中间50%数据的“宽度”。和标准差不同,IQR不受极端值影响,非常稳健。

为什么我偏爱四分位数?因为它能直观地告诉你数据的“骨架”。比如,你看到Q1和Q3差距很大,说明数据分布很宽;差距很小,说明数据很集中。这在环境数据里特别常见——不同季节、不同地点的数据,分布形态差异巨大。

2.4 箱线图:一张图看懂所有

箱线图,就是把上面这些统计量画在一张图上。它包含五个关键点:最小值、Q1、中位数、Q3、最大值。但这里的“最大值”和“最小值”,通常不是数据里的实际极值,而是用“Q1 - 1.5×IQR”和“Q3 + 1.5×IQR”算出来的“内限”。超出这个范围的,就被标记为异常值。

我个人觉得,箱线图是异常值检测的“第一把刀”。它不需要任何假设,看一眼就能知道数据有没有问题。我在做水质数据分析时,每次拿到新数据,第一件事就是画箱线图。哪个指标有异常点,一目了然。

注意: 箱线图标记的“异常值”,只是统计学意义上的“离群点”,不一定是真正的错误数据。有时候,这些“异常”恰恰是我们要找的“信号”。比如,某个监测点突然出现高浓度污染物,箱线图会把它标出来,但你可能需要去核实——是仪器故障,还是真的发生了污染事件?

2.5 知识体系图:统计基础与异常值检测

下面这张图,帮你理清这些概念之间的关系。我习惯用这种图来建立“全局观”,而不是零散地记公式。

数据分布与统计基础 中心趋势 均值 中位数 离散程度 标准差 四分位距 位置度量 Q1 Q3 可视化工具 箱线图 最小值 · Q1 · 中位数 · Q3 · 最大值 · 异常值 核心逻辑:从中心 → 离散 → 位置 → 可视化,层层递进

2.6 实战:用Python快速计算

光说不练假把式。下面这段代码,是我常用的“快速诊断”脚本。拿到数据,跑一遍,心里就有数了。

import numpy as np
import pandas as pd

# 模拟一组环境监测数据(比如:某河流的溶解氧浓度 mg/L)
data = [7.2, 6.8, 7.5, 7.0, 6.9, 7.3, 6.7, 7.1, 7.4, 6.6,
        7.8, 6.5, 7.6, 7.2, 6.9, 7.0, 7.3, 6.8, 7.1, 7.5,
        0.5, 7.2, 7.0, 6.9, 7.4]  # 注意那个 0.5,是个异常值

# 计算统计量
mean_val = np.mean(data)
median_val = np.median(data)
std_val = np.std(data, ddof=1)  # 样本标准差
q1 = np.percentile(data, 25)
q3 = np.percentile(data, 75)
iqr = q3 - q1

print(f"均值: {mean_val:.2f}")
print(f"中位数: {median_val:.2f}")
print(f"标准差: {std_val:.2f}")
print(f"Q1: {q1:.2f}, Q3: {q3:.2f}, IQR: {iqr:.2f}")

# 用IQR方法检测异常值
lower_bound = q1 - 1.5 * iqr
upper_bound = q3 + 1.5 * iqr
outliers = [x for x in data if x < lower_bound or x > upper_bound]
print(f"异常值: {outliers}")

运行一下,你会发现均值被那个0.5拉低了,但中位数依然坚挺。而箱线图的IQR方法,能准确地把0.5揪出来。嗯,这就是统计的力量。

我的习惯: 每次分析前,我都会用这个脚本跑一遍。不是为了找茬,而是为了“感受”数据。你想想看,如果连基本分布都不了解,后面的建模、检测,都是空中楼阁。

好了,这一节的内容就到这里。记住,统计量不是冰冷的数字,它们是数据的“语言”。学会听懂它们,你就能在数据海洋里,找到那些不寻常的信号。


蓝海数据掘金营,专注资料整理