第 6 章 DCCA 与 MFDCCA 双序列分析 当研究两个时间序列之间的长记忆交叉相关时,使用 DCCA 与 MFDCCA。本章涵盖波动函数、Hurst 估计、ρDCCA 指数及置信区间。 6.1 为什么需要 DCCA? Pearson 相关系数只衡量线性、平稳关系。金融、气候等领域常见: 两序列各自非平稳 相关结构随时间尺度变化 需要标度意义下的交叉相关 Detrended Cross-Correlation Analysis(DCCA)(Podobnik & Stanley, 2008)将 DFA 的局部去趋势推广到双序列:在同一窗口内同时拟合趋势,计算交叉残差的标度。 MFDCCA 进一步引入 q 阶,分析交叉相关的多分形结构。 6.
当研究两个时间序列之间的长记忆交叉相关时,使用 DCCA 与 MFDCCA。本章涵盖波动函数、Hurst 估计、ρ_DCCA 指数及置信区间。
Pearson 相关系数只衡量线性、平稳关系。金融、气候等领域常见:
Detrended Cross-Correlation Analysis(DCCA)(Podobnik & Stanley, 2008)将 DFA 的局部去趋势推广到双序列:在同一窗口内同时拟合趋势,计算交叉残差的标度。
MFDCCA 进一步引入 q 阶,分析交叉相关的多分形结构。
给定两条 profile Y₁(t)、Y₂(t)(分别由两序列 toAggregated 得到):
[
F^2_{DCCA}(n) = \frac{1}{2N_n}\sum_\nu \frac{1}{n}\sum_{i=1}^{n} \epsilon_{1,\nu}(i),\epsilon_{2,\nu}(i)
]
与单序列 DFA 的区别:波动来自两序列残差的乘积而非单序列残差平方。
import fathon # 两条 profile 必须长度相同 dcca = fathon.DCCA(tsVec1, tsVec2)
n, F = dcca.computeFlucVec( winSizes, polOrd=1, absVals=True, # True:用 |ε₁|、|ε₂| 计算(默认) overlap=False, # True:重叠窗口 revSeg=False ) H, intercept = dcca.fitFlucVec()
| 参数 | 说明 |
|---|---|
absVals |
True 时使用绝对值波动(Podobnik 原始定义常用) |
overlap |
重叠分段,与 revSeg 互斥(overlap=True 时 revSeg 无效) |
revSeg |
反向分段平均 |
n, rho = dcca.computeRho(winSizes, polOrd=1, overlap=False, revSeg=False)
ρ(n) 在每个尺度 n 上给出去趋势交叉相关系数,用于判断两序列在该尺度上正/负相关。
对独立随机序列蒙特卡洛模拟,得到 ρ 的置信带:
# 空构造:无需真实数据 dcca_empty = fathon.DCCA() n, cInt1, cInt2 = dcca_empty.rhoThresholds( L=300, # 模拟序列长度 winSizes=wins, nSim=100, # 模拟次数 confLvl=0.95, # 95% 置信水平 polOrd=1 )
若实测 ρ(n) 超出 [cInt1, cInt2],则在该尺度上显著相关。
import numpy as np import fathon from fathon import fathonUtils as fu import matplotlib.pyplot as plt np.random.seed(42) L = 10000 # 构造相关序列:共享因子 + 独立噪声 common = np.cumsum(np.random.randn(L)) noise1 = np.random.randn(L) * 0.3 noise2 = np.random.randn(L) * 0.3 x1 = np.diff(common) + noise1 x2 = np.diff(common) + noise2 p1 = fu.toAggregated(x1) p2 = fu.toAggregated(x2) wins = fu.linRangeByStep(20, L // 4, step=10) dcca = fathon.DCCA(p1, p2) n, F = dcca.computeFlucVec(wins, polOrd=1, absVals=True, revSeg=True) H, _ = dcca.fitFlucVec() # ρ 指数(较小窗口范围) wins_rho = fu.linRangeByStep(20, 200, step=20) n_rho, rho = dcca.computeRho(wins_rho, polOrd=1) # 置信区间 dcca_ref = fathon.DCCA() n_ci, lo, hi = dcca_ref.rhoThresholds(300, wins_rho, nSim=200, confLvl=0.95) # ── 可视化 ── fig, axes = plt.subplots(1, 2, figsize=(11, 4)) axes[0].loglog(n, np.abs(F), 'o-', ms=3) axes[0].set_xlabel('n'); axes[0].set_ylabel('|F_DCCA(n)|') axes[0].set_title(f'交叉波动标度 H={H:.3f}') axes[1].plot(n_rho, rho, 'b-o', ms=4, label='ρ_DCCA') axes[1].fill_between(n_ci, lo, hi, alpha=0.2, color='gray', label='95% 独立零假设') axes[1].axhline(0, color='k', lw=0.5) axes[1].set_xlabel('n'); axes[1].set_ylabel('ρ') axes[1].set_title('交叉相关系数 vs 尺度') axes[1].legend() plt.tight_layout() plt.show() print(f"交叉 Hurst H = {H:.4f}")
接口与 MFDFA 平行,但输入为两条 profile:
mfdcca = fathon.MFDCCA(tsVec1, tsVec2) n, F = mfdcca.computeFlucVec( winSizes, qList, # q 阶列表 polOrd=1, revSeg=False ) h_q, _ = mfdcca.fitFlucVec() tau = mfdcca.computeMassExponents() alpha, mfSpect = mfdcca.computeMultifractalSpectrum()
import numpy as np import fathon from fathon import fathonUtils as fu np.random.seed(0) L = 8000 base = np.random.randn(L) p1 = fu.toAggregated(base) p2 = fu.toAggregated(base * 0.7 + np.random.randn(L) * 0.3) wins = fu.linRangeByStep(10, L // 4, step=5) q_list = np.arange(-2, 5, 0.5) mfdcca = fathon.MFDCCA(p1, p2) n, F = mfdcca.computeFlucVec(wins, q_list, revSeg=True) h_q, _ = mfdcca.fitFlucVec() tau = mfdcca.computeMassExponents() alpha, mfSpect = mfdcca.computeMultifractalSpectrum() print("h(q=2) =", h_q[np.argmin(np.abs(q_list - 2))]) print("Δh =", h_q.max() - h_q.min())
| 方法 | 优势 | 局限 |
|---|---|---|
| Pearson r | 简单 | 要求平稳,单尺度 |
| DCCA | 双非平稳、多尺度标度 | 计算量较 Pearson 大 |
| MFDCCA | 交叉多分形 | q×wins 成本高 |
| 小波相干 | 时频局部化 | 不同数学框架 |
| 场景 | 序列对 | 关注量 |
|---|---|---|
| 金融 | 两资产收益率 | H、ρ(n) 显著性 |
| 气候 | 温度 vs 降水 | 交叉 persistence |
| 生理 | 心率 vs 呼吸 | 多尺度耦合 |
| 能源 | 负荷 vs 电价 | 标度相关结构 |
| 参数 | DCCA 建议 |
|---|---|
absVals |
默认 True;False 保留符号信息,可试对比 |
overlap |
短序列可 True 增加样本 |
nSim(置信区间) |
≥ 100,论文级建议 500+ |
| 窗口 wins | 与单序列 DFA 相同原则(第 8 章) |
序列 x, y ──► toAggregated ──► Y1, Y2 │ DCCA(Y1, Y2) ──► F_DCCA(n) ──► H │ computeRho ──► ρ(n) │ rhoThresholds ──► 置信带 MFDCCA(Y1, Y2) ──► F_q(n) ──► h(q), τ, f(α)
absVals=True/False 对 F(n) 的影响。本章有两个配套示例:「DCCA 交叉相关分析」(构造耦合序列对,算交叉 H、ρ_DCCA、95% 置信带,自动判定显著尺度)与「MFDCCA 双序列多分形」(输出 h(q)/τ(q)/f(α))。下面给出 DCCA 的完整可运行脚本:
"""DCCA 双序列交叉相关分析完整示例。 构造一对共享因子的序列,计算交叉 Hurst、ρ_DCCA 与独立零假设置信带, 自动判定哪些尺度上两序列显著相关。 依赖:pip install fathon numpy """ import numpy as np import fathon from fathon import fathonUtils as fu def make_coupled_pair(L, seed=42): """构造一对共享因子的序列:交叉相关显著。""" rng = np.random.default_rng(seed) common = np.cumsum(rng.standard_normal(L)) noise1 = rng.standard_normal(L) * 0.3 noise2 = rng.standard_normal(L) * 0.3 x1 = np.diff(common) + noise1 x2 = np.diff(common) + noise2 return x1, x2 def main(): np.random.seed(42) L = 10000 x1, x2 = make_coupled_pair(L) p1, p2 = fu.toAggregated(x1), fu.toAggregated(x2) wins = fu.linRangeByStep(20, L // 4, step=10) # ── DCCA 交叉标度 ── dcca = fathon.DCCA(p1, p2) n, F = dcca.computeFlucVec(wins, polOrd=1, absVals=True, revSeg=True) H, _ = dcca.fitFlucVec() print(f"交叉 Hurst H = {H:.4f}") # ── ρ_DCCA:交叉相关系数 vs 尺度 ── wins_rho = fu.linRangeByStep(20, 200, step=20) n_rho, rho = dcca.computeRho(wins_rho, polOrd=1) # ── 置信带:对独立随机序列蒙特卡洛模拟 ── # 空构造(无数据),用模拟的独立序列估算零假设分布 dcca_ref = fathon.DCCA() n_ci, lo, hi = dcca_ref.rhoThresholds(300, wins_rho, nSim=100, confLvl=0.95) # ── 显著性判断:ρ 超出置信带的尺度即为显著相关 ── significant = (rho < lo) | (rho > hi) print(f"显著相关尺度占比:{significant.mean():.0%}") print("(ρ 超出置信带的尺度上,两序列的去趋势交叉相关显著。)") print("这是 Pearson 相关系数给不了的多尺度信息。") if __name__ == "__main__": main()
💡 「显著相关尺度占比」这个输出,能直观告诉你「两序列在多大窗口上真的有交叉相关」——小尺度显著而大尺度不显著,往往暗示耦合是短程的;反之则是长程联动。
下一章介绍 HT:Hurst 指数随时间/尺度变化的局部估计。