熵特征:近似熵、样本熵与排列熵的信号复杂性度量
熵特征:揭开信号复杂性的面纱
在信号处理、时间序列分析和生物医学工程领域,理解信号的“复杂性”至关重要。一个规律的正弦波和一段杂乱无章的白噪声,其内在结构截然不同。熵特征正是为此而生,它量化了时间序列的不规则性、不可预测性或复杂度。本教程将带你入门三种广泛使用的熵度量:近似熵 (Approximate Entropy, ApEn)、样本熵 (Sample Entropy, SampEn) 和排列熵 (Permutation Entropy, PerEn),让你掌握从原始信号中提取深层动态信息的核心技术。
什么是熵?从信息论到信号分析
“熵”最初是一个热力学概念,用于描述系统的混乱程度。在信息论中,香农将熵定义为消息中不确定性的度量。将其引入时间序列分析,我们关心的不再是信号值的大小,而是其模式的重复性。一个完全可预测的信号(如单调直线)熵值为零,而完全随机的信号熵值最大。因此,通过计算熵,我们可以区分健康与病理的心率变异性、评估脑电信号的激活程度,甚至检测机械故障。
近似熵 (ApEn):衡量模式相似性的先驱
近似熵(Approximate Entropy,ApEn)由 Pincus 于 1991 年提出,旨在量化序列中相似模式存在与否。直观理解:如果一段序列在添加一个新样本点后,其相似模式的出现概率依然很高,那么序列就是规则的,ApEn 值低。
核心原理与步骤
- 定义容限
r:通常取序列标准差的 0.1 ~ 0.25 倍,用于判断两点是否“相似”。 - 构造向量序列:对长度为
N的序列{x(1), x(2), ..., x(N)},依次取m个点构成向量X(i) = [x(i), x(i+1), ..., x(i+m-1)]。 - 统计相似向量对:对每个
i,计算满足X(i)与X(j)距离(通常采用切比雪夫距离,即最大绝对差)小于r的j的数量,记为C_i^m(r)。该距离反映两段模式的相似度。 - 计算条件概率:定义
Φ^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 原理相似,但统计方法更严谨,对数据长度和参数变化的鲁棒性更强,是目前应用最广的生物医学信号熵特征。
与近似熵的关键区别
- 去除自我匹配:在计算相似向量对时,排除自身比较(
i ≠ j)。这使得计算更精准,不受向量段自身偏差影响。 - 条件概率的全局定义:不再对每个向量取对数后平均,而是直接计算两个计数总和的比率。
- 保持相对一致性:如果序列 A 比序列 B 有更多的规律性,无论参数
m和r如何选择(在常见范围内),SampEn 都能一致地反映 A 的熵值低于 B,这一特性对比较研究至关重要。
计算流程
- 与 ApEn 相同,生成长度为
N的序列的m维向量X_m(i)与m+1维向量X_{m+1}(i)。 - 定义
B_i^m(r)为与X_m(i)距离 <r的向量X_m(j)的数量(j ≠ i)。对所有i求和:B^m(r) = Σ_i B_i^m(r) / (N-m)。 - 同理,计算对应
m+1的全局和:A^m(r) = Σ_i A_i^m(r) / (N-m)。 - 样本熵 定义为负自然对数比率:
该比值可解释为:在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,特别适合实时和长序列分析。
工作原理:从数值到符号模式
- 嵌入与排序:对时间序列,取连续
m个点(嵌入维数)作为一个 state。例如,取点[x(t), x(t+τ), ..., x(t+(m-1)τ)],其中τ为时延。 - 确定排列模式:将这
m个值按其大小标上序号(排序)。例如,片段(3, 7, 2)排序后序号为(1, 2, 0),代表一个特定的排列模式。m个点共有m!种可能的排列模式。 - 计算模式频率:遍历整个序列,统计每种排列模式出现的概率
p(π)。 - 计算香农熵:排列熵即为这些概率的香农熵:
归一化后,PerEn(m) = - Σ p(π) * log₂(p(π))0 ≤ PerEn ≤ 1。规则信号仅涉及少数几种排列,熵值低;随机信号所有排列几乎等概率出现,熵值趋近 1。
关键参数:嵌入维数和时延
m(嵌入维数):决定模式分辨率。太小(m=2只有 2 种模式)区分力差,太大计算量暴涨且需要较长数据。常用m=3至7。经验法则:数据长度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.argsort的kind='stable'),或通过添加极微小噪声打破平局。
小结
熵特征为时间序列分析提供了一扇观察系统复杂性的窗口。近似熵开创了模式匹配的思路,样本熵修正了其偏差成为事实标准,而排列熵则凭借极简的序数比较打开了快速计算的大门。掌握这三者,你便能在面对心跳、脑波、振动或任何按时间记录的信号时,从容提取出反映本质复杂性的数字指纹。实践中,不妨同时计算多种熵并进行相关性分析,或将它们作为特征向量输入机器学习模型,往往能取得超越单一特征的效果。