第 4 章 DFA 核心 API 本章系统讲解 的全部公开方法,提供可直接运行的完整示例与可视化模板。 4.1 类构造 最佳实践:始终传入 的结果。 4.2 computeFlucVec — 计算波动函数 参数详解 参数 | 类型 | 默认 | 说明 | ndarray | — | 窗口尺度 n 的数组,如 | int | 1 | 局部去趋势多项式阶数 | bool | False | True:正反向分段取平均 | bool | False | 无偏版 DFA;True 时忽略 revSeg 返回值 返回 | shape | 含义 | (W,) | 窗口大小,通常等于 winSizes | (W,) | 各窗口对应的波动函数值 4.
本章系统讲解
fathon.DFA的全部公开方法,提供可直接运行的完整示例与可视化模板。
import fathon # tsVec:已做 toAggregated 的 profile,或原始序列(不推荐,应先 toAggregated) dfa = fathon.DFA(tsVec)
最佳实践:始终传入 fathonUtils.toAggregated(increments) 的结果。
n, F = dfa.computeFlucVec( winSizes, # 必填:窗口大小数组 polOrd=1, # 多项式阶数 revSeg=False, # 是否反向分段 unbiased=False # 无偏 DFA(短序列) )
| 参数 | 类型 | 默认 | 说明 |
|---|---|---|---|
winSizes |
ndarray | — | 窗口尺度 n 的数组,如 linRangeByStep(10, 2000) |
polOrd |
int | 1 | 局部去趋势多项式阶数 |
revSeg |
bool | False | True:正反向分段取平均 |
unbiased |
bool | False | 无偏版 DFA;True 时忽略 revSeg |
| 返回 | shape | 含义 |
|---|---|---|
n |
(W,) | 窗口大小,通常等于 winSizes |
F |
(W,) | 各窗口对应的波动函数值 |
H, H_intercept = dfa.fitFlucVec( nStart=-999, # 拟合区间最小窗口;-999 表示用第一个 n nEnd=-999, # 拟合区间最大窗口;-999 表示用最后一个 n logBase=2.718281828459045, # 自然对数 e verbose=False )
前置条件:必须先调用 computeFlucVec。
nStart / nEnd 用于排除标度律不成立的尺度(如过小窗口的离散效应、过大窗口的分段不足)。
import numpy as np limits_list = np.array([[15, 200], [200, 1800]], dtype=int) H_array, intercept_array = dfa.multiFitFlucVec(limits_list, verbose=False)
limits_list 为 k×2 数组,每行 [nStart, nEnd] 定义一个 log-log 拟合区间。用于检测多重标度或分段 persistence。
dfa.saveObject("experiment_run_01") # 写入 experiment_run_01.fathon
保存当前对象状态(含已计算的 F(n)),便于后续只做拟合或绘图而不重算。
以下是从原始增量到 Hurst 指数 + 可视化的标准模板(第 1 章已初探,此处补充注释与扩展):
import numpy as np import fathon from fathon import fathonUtils as fu import matplotlib.pyplot as plt # ── 1. 数据准备 ── np.random.seed(42) L = 12000 increments = np.random.randn(L) # 替换为你的真实增量序列 profile = fu.toAggregated(increments) # ── 2. 窗口设计 ── wins = fu.linRangeByStep(10, L // 4) # 详见第 8 章 # ── 3. DFA 计算 ── dfa = fathon.DFA(profile) n, F = dfa.computeFlucVec(wins, revSeg=True, polOrd=1) # ── 4. 全区间拟合 ── H, intercept = dfa.fitFlucVec(verbose=True) # ── 5. 多区间拟合(可选)── limits = np.array([[20, 300], [300, L // 4 - 50]], dtype=int) H_multi, _ = dfa.multiFitFlucVec(limits) print("多区间 H:", H_multi) # ── 6. 可视化 ── fig, axes = plt.subplots(1, 2, figsize=(12, 4)) # 左:profile axes[0].plot(profile[:500], lw=0.8) axes[0].set_title("Profile(前 500 点)") axes[0].set_xlabel("t") axes[0].set_ylabel("Y(t)") # 右:DFA 标度图 axes[1].loglog(n, F, 'o-', markersize=3, label=f'F(n), H={H:.3f}') n_fit = np.array([n[0], n[-1]]) F_fit = np.exp(intercept + H * np.log(n_fit)) # 自然对数 axes[1].loglog(n_fit, F_fit, 'r--', label='拟合线') axes[1].set_xlabel('窗口 n') axes[1].set_ylabel('F(n)') axes[1].set_title('DFA 双对数标度图') axes[1].legend() axes[1].grid(True, which='both', alpha=0.3) plt.tight_layout() plt.show() print(f"Hurst exponent H = {H:.4f}")
import numpy as np import fathon from fathon import fathonUtils as fu # 假设 CSV 第一列为日对数收益率 # data = np.loadtxt("returns.csv", delimiter=",", skiprows=1) # 演示用合成数据代替: data = np.diff(np.log(np.cumprod(1 + 0.001 * np.random.randn(5000)))) profile = fu.toAggregated(data) wins = fu.linRangeByStep(10, len(data) // 4) dfa = fathon.DFA(profile) n, F = dfa.computeFlucVec(wins, revSeg=True, polOrd=1) H, _ = dfa.fitFlucVec(nStart=20, nEnd=len(data)//4 - 10) print(f"收益率序列 DFA Hurst: H = {H:.4f}") if H > 0.55: print("解读:可能存在持久性长记忆") elif H < 0.45: print("解读:可能存在反持久性") else: print("解读:接近随机游走(H ≈ 0.5)")
DFA(tsVec) │ ▼ computeFlucVec(winSizes, ...) ──► n, F │ ├──► fitFlucVec() ──► H, intercept ├──► multiFitFlucVec(...) ──► H_array, intercept_array └──► saveObject(name)
错误用法:未调用 computeFlucVec 直接 fitFlucVec 会报错或得到无效结果。
| 算法步骤 | fathon 方法/参数 |
|---|---|
| Profile Y(t) | fathonUtils.toAggregated |
| 窗口 n 列表 | winSizes / fu.linRangeByStep |
| 局部 m 阶去趋势 | polOrd=m |
| 正/反向分段 | revSeg |
| F(n) 数组 | computeFlucVec 返回 F |
| log-log 拟合 H | fitFlucVec |
| 无偏短序列 | unbiased=True |
| 场景 | 建议 |
|---|---|
| wins 步长 1、L=10⁵ | 改用 linRangeByStep(10, L//4, step=10) 先粗扫 |
| 重复实验同一 profile | saveObject 避免重算 |
| 短序列 L<1000 | unbiased=True,缩小最大 n |
| 有多项式漂移 | polOrd=2 试跑对比 |
fathon.DFA 三步走:
toAggregated → profilecomputeFlucVec → F(n)fitFlucVec → H进阶:multiFitFlucVec 检测多重标度;saveObject 持久化中间结果。
np.diff(np.cumsum(np.random.randn(L+1))),记录 H 是否接近 1。polOrd=1,2,3 的 H 与 F(n) 曲线形状。fitFlucVec(nStart=50) 排除小窗口,观察 H 变化。本章 API 全家桶封装在「DFA 全 API 演练」示例中,分四组演示:多项式阶数与反向分段组合、多区间拟合检测多重标度、状态保存与恢复、短序列无偏修正。下面给出其中「多区间拟合 + 状态保存」的完整脚本,可直接复制运行:
"""DFA 多区间拟合与状态保存完整示例。 演示 multiFitFlucVec 检测多重标度、saveObject 跳过重算。 依赖:pip install fathon numpy """ import os import numpy as np import fathon from fathon import fathonUtils as fu def demo_multi_fit(): """multiFitFlucVec:对多个尺度区间分别拟合,揭示多重标度。""" np.random.seed(2) # 用累积随机游走构造一个含趋势的序列 profile = fu.toAggregated(np.cumsum(np.random.randn(8000))) wins = fu.linRangeByStep(10, 2000) dfa = fathon.DFA(profile) dfa.computeFlucVec(wins, revSeg=True) # 两个拟合区间:短尺度 vs 长尺度 limits = np.array([[15, 200], [200, 1800]], dtype=int) H_list, _ = dfa.multiFitFlucVec(limits) print("=== multiFitFlucVec 多区间拟合 ===") for (lo, hi), H in zip(limits, H_list): print(f" 区间 [{lo:4d}, {hi:4d}] H={H:.4f}") print("若两区间 H 差异显著,提示多重标度 → 考虑 MFDFA(第 5 章)。") def demo_save_object(): """saveObject / 还原:把计算结果存盘,下次跳过 computeFlucVec。""" np.random.seed(3) profile = fu.toAggregated(np.random.randn(5000)) # 第一次:完整计算并保存 dfa = fathon.DFA(profile) dfa.computeFlucVec(fu.linRangeByStep(10, 1000)) H_save, _ = dfa.fitFlucVec() dfa.saveObject("dfa_analysis") # 写入 dfa_analysis.fathon # 第二次:还原后直接拟合,不必重算波动 dfa2 = fathon.DFA() dfa2.loadObject("dfa_analysis") H_load, _ = dfa2.fitFlucVec() print("\n=== saveObject / loadObject ===") print(f" 保存时 H = {H_save:.4f}") print(f" 还原后 H = {H_load:.4f}") print(f" 差异 = {abs(H_save - H_load):.2e}") # 清理演示产物 try: os.remove("dfa_analysis.fathon") except OSError: pass if __name__ == "__main__": demo_multi_fit() demo_save_object()
💡
saveObject适合 MFDFA 等计算量大的场景:先算完波动函数存盘,后续多次换拟合区间 / q 列表时无需重算,直接fitFlucVec。
下一章进入 MFDFA:当单一 H 不足以描述序列时,如何用 q 阶波动函数揭示多分形结构。