熵特征:近似熵、样本熵与排列熵的信号复杂性度量

FreeGuideOnline 最新 2026-06-27

熵特征:揭开信号复杂性的面纱

在信号处理、时间序列分析和生物医学工程领域,理解信号的“复杂性”至关重要。一个规律的正弦波和一段杂乱无章的白噪声,其内在结构截然不同。熵特征正是为此而生,它量化了时间序列的不规则性不可预测性复杂度。本教程将带你入门三种广泛使用的熵度量:近似熵 (Approximate Entropy, ApEn)样本熵 (Sample Entropy, SampEn)排列熵 (Permutation Entropy, PerEn),让你掌握从原始信号中提取深层动态信息的核心技术。

什么是熵?从信息论到信号分析

“熵”最初是一个热力学概念,用于描述系统的混乱程度。在信息论中,香农将熵定义为消息中不确定性的度量。将其引入时间序列分析,我们关心的不再是信号值的大小,而是其模式的重复性。一个完全可预测的信号(如单调直线)熵值为零,而完全随机的信号熵值最大。因此,通过计算熵,我们可以区分健康与病理的心率变异性、评估脑电信号的激活程度,甚至检测机械故障。

近似熵 (ApEn):衡量模式相似性的先驱

近似熵(Approximate Entropy,ApEn)由 Pincus 于 1991 年提出,旨在量化序列中相似模式存在与否。直观理解:如果一段序列在添加一个新样本点后,其相似模式的出现概率依然很高,那么序列就是规则的,ApEn 值低。

核心原理与步骤

  1. 定义容限 r:通常取序列标准差的 0.1 ~ 0.25 倍,用于判断两点是否“相似”。
  2. 构造向量序列:对长度为 N 的序列 {x(1), x(2), ..., x(N)},依次取 m 个点构成向量 X(i) = [x(i), x(i+1), ..., x(i+m-1)]
  3. 统计相似向量对:对每个 i,计算满足 X(i)X(j) 距离(通常采用切比雪夫距离,即最大绝对差)小于 rj 的数量,记为 C_i^m(r)。该距离反映两段模式的相似度。
  4. 计算条件概率:定义 Φ^m(r) = (N-m+1)^-1 Σ ln(C_i^m(r))。ApEn 即为:
    ApEn(m, r, N) = Φ^m(r) - Φ^{m+1}(r)
    
    这本质上是度量当嵌入维数从 m 增加到 m+1 时,新模式产生多少“意外”。

参数选择与注意事项

  • m:嵌入维数,通常取 2 或 3。m=2 可捕捉短时变化。
  • r:相似容限。过大会掩盖细节,过小则噪声影响显著。建议取值 0.2 * 标准差。
  • 优势:计算简单,数据长度要求相对宽松(>100 点即可)。
  • 缺陷:存在自我匹配偏差(每个向量与自己比较),导致偏倚,且对参数 r 敏感。这促进了样本熵的改进。

样本熵 (SampEn):摆脱自我匹配的稳健度量

样本熵(Sample Entropy,SampEn)由 Richman 和 Moorman 于 2000 年提出,直接修正了 ApEn 的不足。它与 ApEn 原理相似,但统计方法更严谨,对数据长度和参数变化的鲁棒性更强,是目前应用最广的生物医学信号熵特征。

与近似熵的关键区别

  1. 去除自我匹配:在计算相似向量对时,排除自身比较(i ≠ j)。这使得计算更精准,不受向量段自身偏差影响。
  2. 条件概率的全局定义:不再对每个向量取对数后平均,而是直接计算两个计数总和的比率。
  3. 保持相对一致性:如果序列 A 比序列 B 有更多的规律性,无论参数 mr 如何选择(在常见范围内),SampEn 都能一致地反映 A 的熵值低于 B,这一特性对比较研究至关重要。

计算流程

  1. 与 ApEn 相同,生成长度为 N 的序列的 m 维向量 X_m(i)m+1 维向量 X_{m+1}(i)
  2. 定义 B_i^m(r) 为与 X_m(i) 距离 < r 的向量 X_m(j) 的数量(j ≠ i)。对所有 i 求和:B^m(r) = Σ_i B_i^m(r) / (N-m)
  3. 同理,计算对应 m+1 的全局和:A^m(r) = Σ_i A_i^m(r) / (N-m)
  4. 样本熵 定义为负自然对数比率:
    SampEn(m, r, N) = -ln( A^m(r) / B^m(r) )
    
    该比值可解释为:在 m 维上匹配的向量对,在 m+1 维仍然匹配的条件概率。熵值越高,表示新点产生新模式的可能性越大,序列越复杂。

典型应用与参数建议

  • 适用场景:心电图 (ECG) 心率变异性、脑电图 (EEG) 信号、昼夜节律、金融时间序列。
  • 常用参数m = 2, r = 0.2 * 标准差。数据长度 N 最好大于 10^m,推荐 100 至 5000 个点。
  • 局限性:计算复杂度相对较高,对于极短数据(<100 点)可能会出现 B^m(r)=0 导致无法定义对数的情况,使用时需做异常处理。

排列熵 (PerEn):基于序数模式的快速熵

排列熵(Permutation Entropy,PerEn)由 Bandt 和 Pompe 于 2002 年提出,它完全跳出了“距离比较”的框架,转而分析信号中元素的时序排列模式。计算极快,对噪声鲁棒,且无需设定容限 r,特别适合实时和长序列分析。

工作原理:从数值到符号模式

  1. 嵌入与排序:对时间序列,取连续 m 个点(嵌入维数)作为一个 state。例如,取点 [x(t), x(t+τ), ..., x(t+(m-1)τ)],其中 τ 为时延。
  2. 确定排列模式:将这 m 个值按其大小标上序号(排序)。例如,片段 (3, 7, 2) 排序后序号为 (1, 2, 0),代表一个特定的排列模式。m 个点共有 m! 种可能的排列模式。
  3. 计算模式频率:遍历整个序列,统计每种排列模式出现的概率 p(π)
  4. 计算香农熵:排列熵即为这些概率的香农熵:
    PerEn(m) = - Σ p(π) * log₂(p(π))
    
    归一化后,0 ≤ PerEn ≤ 1。规则信号仅涉及少数几种排列,熵值低;随机信号所有排列几乎等概率出现,熵值趋近 1。

关键参数:嵌入维数和时延

  • m (嵌入维数):决定模式分辨率。太小(m=2 只有 2 种模式)区分力差,太大计算量暴涨且需要较长数据。常用 m=37。经验法则:数据长度 N 应远大于 m!,避免统计不足。
  • τ (时延):用于抽取相隔 τ 个样本的点,可捕捉不同时间尺度的动态。对于连续过采样信号,采用 τ>1 可去除冗余。常规分析中 τ=1 是常见起点。

优势与适用性

  • 计算速度极快,不含复杂距离运算和对数。
  • 天然抗噪,因为只关心值的相对顺序,不受幅值尺度影响。
  • 可检测突变,能灵敏反映信号动力学状态的突然变化。
  • 广泛应用:癫痫检测、电机故障诊断、情绪识别、气候数据分析。

三种熵特征的对比与选择指南

特征 核心思想 计算速度 鲁棒性 是否需要容限 r 数据长度要求 典型应用
近似熵 (ApEn) 距离相似性,条件对数差 中等 较低(有偏) >100 通用复杂性初探
样本熵 (SampEn) 改进的距离相似性,条件概率比 较慢 >100 (建议 200+) 生物医学信号、生理状态区分
排列熵 (PerEn) 序数模式频率的熵 极快 高(幅值无关) >5*m! (推荐) 实时监测、长序列、状态突变检测

选择建议:若追求标准、稳健的复杂度量化,尤其是生物医学领域,首选 样本熵。若数据极长、对计算资源敏感或需要探索不同时间尺度,排列熵 是理想选择。近似熵尽管经典,但因自身偏倚,现多被样本熵替代,但在一些快速评估场景仍有用。

实战要点与Python示例框架

为了更好地理解,下面给出三种熵的 Python 计算框架(基于 NumPy)。你可以根据框架填充细节,以便实际应用。

import numpy as np

def approximate_entropy(u, m, r):
    """近似熵 ApEn """
    N = len(u)
    def _phi(m):
        # 构造向量序列
        x = np.array([u[i:i+m] for i in range(N - m + 1)])
        C = np.zeros(len(x))
        for i in range(len(x)):
            # 切比雪夫距离,包括自身配对
            dist = np.max(np.abs(x - x[i]), axis=1)
            C[i] = np.sum(dist <= r) / (N - m + 1)
        return np.sum(np.log(C)) / (N - m + 1)
    return _phi(m) - _phi(m+1)

def sample_entropy(u, m, r):
    """样本熵 SampEn """
    N = len(u)
    def _count_matches(template_length):
        x = np.array([u[i:i+template_length] for i in range(N - template_length + 1)])
        count = 0
        for i in range(len(x)):
            # 排除自身 (j != i)
            dist = np.max(np.abs(x - x[i]), axis=1)
            count += np.sum((dist <= r) & (dist != 0))  # dist!=0 排除自身
        return count
    B = _count_matches(m)      # 匹配 m 维向量的总数
    A = _count_matches(m+1)    # 匹配 m+1 维向量的总数
    if B == 0 or A == 0:
        return float('inf')    # 无匹配时处理
    return -np.log(A / B)

def permutation_entropy(time_series, m, delay=1):
    """排列熵 PerEn,归一化到 [0,1] """
    n = len(time_series)
    # 生成所有排列模式
    import itertools
    permutations = list(itertools.permutations(range(m)))
    perm_dict = {perm: 0 for perm in permutations}
    # 抽取并排序
    for i in range(n - delay * (m - 1)):
        # 取出间隔为 delay 的 m 个值
        segment = [time_series[i + j*delay] for j in range(m)]
        # 获取排序索引(处理平级:按出现顺序稳定排序)
        sorted_idx = np.argsort(segment, kind='stable')
        # 建立当前排列模式(从0到m-1的顺序)
        permutation = tuple(np.argsort(sorted_idx))
        if permutation in perm_dict:
            perm_dict[permutation] += 1
    # 计算概率
    total = sum(perm_dict.values())
    probs = np.array([count/total for count in perm_dict.values() if count > 0])
    pe = -np.sum(probs * np.log2(probs))
    return pe / np.log2(len(permutations))  # 归一化

使用提示

  • 输入序列最好先进行去趋势或标准化处理,使结果更具可比性。
  • 样本熵和近似熵的 r 通常设为 0.2 * np.std(signal)
  • 排列熵捕获的是序数模式,若信号中存在大量重复值(平结),需在排序时采用稳定策略(如 np.argsortkind='stable'),或通过添加极微小噪声打破平局。

小结

熵特征为时间序列分析提供了一扇观察系统复杂性的窗口。近似熵开创了模式匹配的思路,样本熵修正了其偏差成为事实标准,而排列熵则凭借极简的序数比较打开了快速计算的大门。掌握这三者,你便能在面对心跳、脑波、振动或任何按时间记录的信号时,从容提取出反映本质复杂性的数字指纹。实践中,不妨同时计算多种熵并进行相关性分析,或将它们作为特征向量输入机器学习模型,往往能取得超越单一特征的效果。