第4章 Z‑score 方法 —— 最基础的统计异常检测
Z‑score 方法,说白了就是看你的数据点偏离平均值的“标准差个数”。我刚开始做数据清洗时,第一个学会的异常检测方法就是它。简单、直观,而且能快速跑出结果。不过你想想看,它这么简单,是不是有什么坑?嗯,我们一点点拆开讲。
什么是 Z‑score?
Z‑score 又叫标准分数。它告诉你一个数据点和均值的距离,用标准差做尺子量。公式很简单:
Z = (x − μ) / σ
算出来如果是 2.5,意思就是该点比均值高出 2.5 个标准差。如果 Z 的值很大,那这个点就可能是异常。我通常把 |Z| > 3 当作可疑点,但这只是经验值,具体看场景。
阈值怎么选?
阈值不是拍脑袋定的。我习惯先画个分布图,看看数据长什么样。下面这张表你参考一下:
| 阈值(|Z|) | 对应概率(正态分布) | 每百万数据中的异常数(近似) |
|---|---|---|
| 2.0 | 95.45% | 45,500 |
| 2.5 | 98.76% | 12,400 |
| 3.0 | 99.73% | 2,700 |
| 3.5 | 99.95% | 465 |
| 4.0 | 99.993% | 63 |
看明白了吗?阈值设 2 会抓到很多正常点(误报高),设 4 又可能漏掉真正的异常。我一般从 3 开始试,再根据业务容忍度微调。
Z‑score 的适用条件
这个方法有个大前提:数据近似服从正态分布。如果不满足,计算出来的 Z‑score 可能不准。我在项目中遇到过一回路基站的流量数据,分布是长尾的,直接用 Z‑score 阈值 3,结果漏了一大半异常。后来改用修正的 Z‑score(用中位数替代均值,用 MAD 替代标准差)才解决问题。
所以用之前,先做两步:
- 画直方图或 Q-Q 图,看数据是否大致对称、钟形。
- 检查有没有严重离群点——它们会拉偏均值,让 Z‑score 失效。
另外,Z‑score 对样本量也有要求。样本太少(比如小于 10),均值和标准差不稳定,算出来的 Z 值没啥参考意义。我建议至少 30 个样本再开始玩 Z‑score。
Python 实战:用 Z‑score 检测异常
写代码之前,先看看整体流程。我画了张图,帮你理清思路:
下面是我常用的 Z‑score 检测函数,加了可选的阈值参数,业务直接调:
import numpy as np
def detect_outliers_zscore(data, threshold=3.0):
"""
基于 Z-score 的异常检测
:param data: array-like
:param threshold: 阈值,默认 3.0
:return: (布尔数组 True=异常, 异常索引, 异常值列表)
"""
data = np.array(data)
mean = np.mean(data)
std = np.std(data)
if std == 0:
raise ValueError("标准差为0,数据无变化,无法计算Z-score")
z_scores = (data - mean) / std
outlier_mask = np.abs(z_scores) > threshold
outlier_indices = np.where(outlier_mask)[0]
outlier_values = data[outlier_mask]
return outlier_mask, outlier_indices, outlier_values
# 举个栗子
data = [2.1, 2.2, 2.0, 2.3, 2.1, 25.0, 2.2, 2.0, 2.1]
mask, idx, vals = detect_outliers_zscore(data, threshold=3.0)
print(f"异常索引: {idx}")
print(f"异常值: {vals}")
运行结果你会看到索引5的 25.0 被揪出来了。嗯,干活就是这么快。
优缺点与避坑
先说说好处:计算成本极低,O(n) 搞定;结果可解释性强;适合做初筛。但缺点也不少:
- 对异常值敏感:一个极端值就能把均值和标准差拉跑偏。效果是 Z‑score 可能“免疫”了真正的异常。
- 依赖正态分布:数据严重偏态时误差很大。我曾经处理过用户点击时长数据,分布是右偏的,直接 Z‑score 结果惨不忍睹。后来改用中位数和中位差(MAD)才解决了。
- 阈值主观:没有“标准答案”,需要结合业务调参。
另外,Z‑score 也假设数据是独立同分布的。如果你的数据有时序相关性(比如传感器连续采集),那直接套 Z‑score 会有一堆误报,因为趋势变化会被当成异常。这种情况请参考后续章节的移动窗口法。
scipy.stats.zscore 快速计算,但它不带阈值判断,自己封装一层就够了。
总结一下:Z‑score 是一把快刀,但要看清楚脑袋的形状再用。做异常检测没有银弹,Z‑score 价值在于简单、可解释、能快速落地。我建议你把它当作检测流水线的第一道筛子,先把明显离谱的点标记出来,再上更精细的方法。