34 Python 离群点检测:什么是离群点?为什么要做异常检测?

Python 数据分析入门:什么是离群点?为什么要做异常检测?

在做数据分析时,经常会遇到这样一种情况:

大多数数据都比较集中、变化也比较稳定,但其中总会出现几个"特别奇怪"的值。

比如:

  • 学生成绩大多在 70 到 90 分之间,突然出现一个 5 分
  • 某商品平时日销量只有几百件,某一天却变成了 50000 件
  • 某台设备的温度一直比较平稳,某次采集结果却突然飙升

看到这类数据,很多人的第一反应往往是:

这是不是录错了?要不要直接删掉?

但问题在于,这些"看起来不正常"的数据,并不一定都是错误。

有时候,它可能确实是录入错误;

但有时候,它反而代表着一个非常重要的异常事件,比如设备故障、网络攻击、金融欺诈,甚至某种新的行为模式。

这类明显不同于大多数数据的对象,通常被称为 离群点(Outlier)

而识别这类数据的过程,就叫做 离群点检测 ,也常被称为 异常检测


一、为什么要关注离群点?

很多初学者会把离群点简单理解为"脏数据"或者"错误数据"。

但在实际应用中,离群点往往并不是应该被忽略的对象,反而可能是最有分析价值的数据。

异常检测已经在很多领域得到了广泛应用,比如:

  • 入侵检测
  • 工业损毁检测
  • 金融欺诈识别
  • 股票分析
  • 医疗处理

从本质上看,异常检测是在寻找"观测值与参照值之间有意义的偏差"。

也就是说,重点不只是找出"不一样的数据",而是找出那些 值得关注的不一样

一个常见场景

以银行卡交易为例。

如果某个账户平时消费金额较小、消费地点也相对固定,但某天突然在异地连续发生多笔大额消费,那么这些交易记录就很可能与用户的正常行为模式明显不同。

对于这类数据,真正需要做的并不是直接删除,而是进一步判断它是否代表着潜在风险。

所以,离群点检测的重要性在于:

它帮助我们从大量数据中,尽早发现那些可能隐藏着异常事件的信息 。


二、什么是离群点?

离群点是指 显著偏离一般水平的观测对象

离群点检测,就是找出那些 不同于预期对象行为 的数据对象的过程 。

如果用更直白的话来解释,就是:

当一个数据点和大多数数据相比,表现得特别不合群时,它就可能是离群点。

例如下面这组数据:

python 复制代码
[68, 72, 75, 70, 69, 74, 71, 73, 150]

前面大多数值都在 68 到 75 之间,而最后一个 150 明显偏离整体范围。

在这种情况下,150 就很可能是一个离群点。

这里需要注意,离群点强调的是"显著偏离",而不是普通波动。

也就是说,数据之间本来就允许存在差异,但如果这种差异大到明显脱离整体规律,就值得进一步关注。


三、离群点和噪声有什么区别?

这是学习异常检测时最容易混淆的一个问题:

离群点和噪声是不是一回事?

答案是:不是。

噪声通常指观测数据中的随机误差或方差,而离群点属于观测值的一部分,它既可能是真实数据产生的,也可能是由噪声带来的 。

可以简单区分为:

1. 噪声

噪声更强调"误差来源"。

比如:

  • 传感器抖动
  • 测量偏差
  • 录入误差
  • 采集环境干扰

2. 离群点

离群点更强调"结果表现"。

也就是说,某个数据对象在结果上明显偏离了整体数据分布。

因此,二者的关系可以理解为:

  • 噪声可能导致离群点出现
  • 但离群点不一定都是噪声
  • 有些离群点本身是真实而且有意义的

这也是为什么面对异常值时,不能简单地"一看不正常就删掉"。

在很多实际任务中,离群点恰恰是最需要被单独分析的对象 。


四、离群点为什么会出现?

离群点出现的原因通常可以分为两类 。

1. 数据本身的极端表现

这类离群点虽然看起来"很异常",但它依然是真实发生的。

它属于总体固有变异性的极端情况 。

例如:

  • 某段时间出现极端天气,导致用电量暴涨
  • 某个病人的监测指标突然异常升高
  • 某只股票在重大消息影响下短期剧烈波动

这种离群点虽然偏离明显,但并不一定是错误数据。

2. 由偏差或失误导致的异常值

另一类离群点则可能来自于试验条件的偶然偏离,或者观测、记录、计算中的失误 。

例如:

  • 温度单位录错
  • 少写或多写一个数字
  • 仪器故障导致读数异常
  • 数据处理过程中出现计算错误

这类离群点往往不代表真实现象,而是数据质量问题。

因此,离群点检测并不只是"找出奇怪的数据",还包括判断这些异常究竟意味着什么。


五、离群点有哪些常见类型?

离群点通常可以分为三类:

  • 全局离群点
  • 条件离群点
  • 集体离群点

1. 全局离群点

全局离群点是最容易理解的一类。

如果一个数据对象 明显偏离了数据集中绝大多数对象,那么它就是全局离群点 。

例如:

  • 大多数学生成绩集中在 70~90 分,某个成绩只有 5 分
  • 大多数商品价格比较稳定,某个价格突然高得离谱

这种异常通常不需要结合额外背景,只看整体分布就能发现。


2. 条件离群点

条件离群点不是在任何情况下都异常,而是 只有在某种特定情境下才显得异常

例如:

  • 夏天气温 35℃ 很常见,但冬天气温 35℃ 就非常异常
  • 白天交易频繁是正常的,但凌晨突然出现大量交易可能就值得警惕
  • 某地区经常出现大雨并不异常,但在常年干旱地区就可能异常

在这种情况下,判断一个对象是否异常,必须结合它所在的上下文。

在条件离群点检测中,通常会涉及两类属性:

  • 条件属性:用于描述情境的属性
  • 行为属性:用于描述对象表现的属性

可以理解为:

  • 情境决定"在什么条件下看"
  • 行为决定"对象表现得怎么样"

因此,条件离群点的关键在于:

同一个数据值,在不同情境下,异常程度可能完全不同 。


3. 集体离群点

集体离群点关注的不是单个点,而是一组对象的整体行为。

当数据集中的一些数据对象作为一个集合,显著偏离整体数据集时,这个集合就形成了集体离群点 。

例如:

  • 单次网络访问记录可能都很正常,但某一时间段内形成的访问模式却异常
  • 单个设备读数不一定有问题,但连续一组读数共同反映出故障趋势
  • 单笔交易正常,但连续多笔交易组合起来就显得异常

这类异常的难点在于:

单个对象未必异常,但组合在一起之后,整体模式却非常异常 。


六、先从图形上理解异常点

在正式学习各种异常检测方法之前,先用图形去理解离群点,往往是最直观的方式。

下面用 Python 构造一组二维数据:

  • 大部分点集中在中心区域
  • 少量点远离主体区域

通过可视化,就可以直观看到什么叫"明显不合群的数据点"。


七、代码实操:构造一组带离群点的数据

1. 代码目标

这段代码主要完成三件事:

  1. 生成一批正常数据
  2. 手动加入几个异常点
  3. 用散点图展示正常点和异常点的分布差异

这也是理解全局离群点最简单的方式。


2. 代码示例

python 复制代码
import numpy as np
import matplotlib.pyplot as plt

# 为了结果可复现
np.random.seed(42)

# 生成正常数据:100个二维点,集中在(0, 0)附近
normal_data = np.random.randn(100, 2)

# 手动添加几个异常点
outliers = np.array([
    [4, 4],
    [5, -3],
    [-4, 5]
])

# 合并数据
data = np.vstack([normal_data, outliers])

# 绘图
plt.figure(figsize=(8, 6))
plt.scatter(normal_data[:, 0], normal_data[:, 1], c='steelblue', label='正常点')
plt.scatter(outliers[:, 0], outliers[:, 1], c='red', label='异常点', s=80)

plt.title('离群点示意图')
plt.xlabel('X1')
plt.ylabel('X2')
plt.legend()
plt.grid(True, linestyle='--', alpha=0.4)
plt.show()

3. 代码说明

这段代码的逻辑比较清楚,可以拆成几个步骤来理解,这种分步说明方式也比较适合专栏写作 。

第一步:生成正常数据
python 复制代码
normal_data = np.random.randn(100, 2)

这里生成了 100 个二维点,它们大致围绕原点分布,可以看成是一批"正常样本"。

第二步:手动构造异常点
python 复制代码
outliers = np.array([
    [4, 4],
    [5, -3],
    [-4, 5]
])

这几个点被故意放在离中心较远的位置,用来模拟离群点。

第三步:合并数据
python 复制代码
data = np.vstack([normal_data, outliers])

把正常点和异常点合并成一个完整数据集。

第四步:可视化
python 复制代码
plt.scatter(...)

通过散点图把两类点画出来,就能直观看到异常点和主体数据之间的差异。


4. 运行结果怎么理解?

运行这段代码后,通常可以从图形上直接观察到结果 :

  • 大多数蓝色点集中在图中央附近
  • 红色点明显远离主要数据区域

这些红点就是非常典型的 全局离群点,因为它们相对于整体数据分布来说偏离非常明显 。

这个例子也说明了一个很重要的事实:

离群点并不是"数学上突然出现的概念",而是在图形、分布和行为上都能体现出明显异常的数据对象。


八、练习:试着判断哪些数据可能是离群点

在理解了基本概念之后,可以先做一个简单练习,加深对离群点的直观认识。

练习1

观察下面这组数据:

python 复制代码
[72, 75, 71, 74, 73, 76, 150]

思考:

  1. 哪个值最可能是离群点?
  2. 它属于哪一类离群点?
  3. 这个值一定是错误数据吗?

练习2

考虑下面这个场景:

某地 7 月份的最高气温是 35℃,某地 1 月份的最高气温也是 35℃。

思考:

  1. 这两个 35℃ 是否都属于异常?
  2. 如果不是,为什么?
  3. 这里体现的是哪一种离群点?

练习3

某网站某一分钟内突然连续出现大量来自同一来源的访问请求。

单独看每一次请求都很普通,但这一组请求组合起来非常异常。

思考:

  1. 这属于哪一类离群点?
  2. 为什么单个点不明显异常,但整体却可能异常?

九、小结

这一篇主要围绕一个基础问题展开:

什么是离群点,为什么要做异常检测?

可以概括为以下几点:

  1. 离群点是 显著偏离一般水平的观测对象,异常检测就是识别这些与预期行为明显不同的数据对象 。
  2. 离群点 不同于噪声。噪声强调随机误差,而离群点强调结果上明显偏离整体分布 。
  3. 离群点可能来自真实的极端情况,也可能来自观测、记录或计算错误 。
  4. 常见离群点包括三类:
    • 全局离群点
    • 条件离群点
    • 集体离群点
  5. 在很多场景中,离群点并不是应该被简单删除的数据,而是最值得深入分析的数据 。

最后,通过一个简单的 Python 可视化示例,可以直观看到离群点在数据分布中的表现形式。

相关推荐
平常心cyk2 小时前
Python基础快速复习——集合和字典
开发语言·数据结构·python
AC赳赳老秦2 小时前
OpenClaw关键词挖掘Agent配置(附SOP脚本,可直接复制使用)
java·大数据·开发语言·人工智能·python·pygame·openclaw
qq_416018722 小时前
数据分析与科学计算
jvm·数据库·python
深藏功yu名2 小时前
Day24(进阶篇):向量数据库 Chroma_FAISS 深度攻坚 —— 索引优化、性能调优与生产级落地
数据库·人工智能·python·ai·agent·faiss·chroma
njidf2 小时前
趣味项目与综合实战
jvm·数据库·python
李昊哲小课2 小时前
PyMySQL完整教程
服务器·数据库·python·pymysql
sqyno1sky2 小时前
Python数据库操作:SQLAlchemy ORM指南
jvm·数据库·python
belldeep2 小时前
python:spaCy 源代码解析,性能优化方法
python·性能优化·cython·spacy
deephub3 小时前
TPU 架构与 Pallas Kernel 编程入门:从内存层次结构到 FlashAttention
人工智能·python·深度学习·tpu