"""ex12practices.py — 第 9 章 工程实践:参数调优、性能、可复现 对应教程:tutorials/09-practices.md。 汇总工程经验: maxdim 选择(H0/H1/H2 的成本与收益) thresh 与 numedges 的关系 可复现:固定种子 + 记录参数 大数据三条路:稠密 / 稀疏 / nperm 的决策 运行: python ex12practices.
"""ex12_practices.py — 第 9 章 工程实践:参数调优、性能、可复现
对应教程:tutorials/09-practices.md。
汇总工程经验:
运行:
python ex12_practices.py
"""
import time
import numpy as np
from ripser import ripser
from common import sample_sphere, sample_torus
def maxdim_cost():
"""maxdim 越高,成本越高(单纯形数量爆炸)。"""
print("=== maxdim 对计算成本的影响 ===")
data = sample_sphere(n=300, noise=0.03, seed=0)
for maxdim in [0, 1, 2]:
t0 = time.perf_counter()
r = ripser(data, maxdim=maxdim, thresh=1.2)
dt = time.perf_counter() - t0
sizes = [d.shape[0] for d in r['dgms']]
print(f" maxdim={maxdim}: {dt:.2f}s, edges={r['num_edges']}, "
f"各维点数={sizes}")
def thresh_vs_edges():
"""thresh 控制复形规模。"""
print("\n=== thresh vs num_edges ===")
data = sample_torus(n=500, seed=1)
print(f"{'thresh':>8s} {'time':>8s} {'edges':>10s} {'H1点数':>8s}")
for thresh in [0.5, 1.0, 1.5, 2.0, 3.0]:
t0 = time.perf_counter()
r = ripser(data, maxdim=1, thresh=thresh)
dt = time.perf_counter() - t0
print(f"{thresh:8.2f} {dt:8.2f}s {r['num_edges']:10d} "
f"{len(r['dgms'][1]):8d}")
def reproducibility():
"""可复现:固定种子 + 记录所有参数。"""
print("\n=== 可复现性检查 ===")
cfg = dict(maxdim=1, thresh=1.5, coeff=2)
for trial in range(2):
rng = np.random.default_rng(42)
data = sample_sphere(n=200, noise=0.05, seed=42)
r = ripser(data, **cfg)
pers = r['dgms'][1][:, 1] - r['dgms'][1][:, 0]
pers = pers[np.isfinite(pers)]
print(f" trial {trial}: H1 点数={len(r['dgms'][1])}, "
f"max persistence={pers.max() if len(pers) else 0:.6f}")
print(" 两次应完全一致(同种子 + 同参数)。")
print(f" 参数记录: {cfg}")
def decision_tree_demo():
"""大数据三条路的决策演示。"""
print("\n=== 大数据三条路决策 ===")
print(" 规则:")
print(" n < 5000 → 稠密 ripser(X)")
print(" n ≥ 5000 + 可近似 → n_perm 子采样")
print(" 边很稀疏 / k-NN → 稀疏 D + thresh")
data = np.random.default_rng(2).standard_normal((4000, 4)) print(f"\n 示例数据 n={len(data)}(< 5000,走稠密路径)") t0 = time.perf_counter() r = ripser(data, maxdim=1, thresh=3.0) print(f" 稠密: {time.perf_counter()-t0:.2f}s, edges={r['num_edges']}") print(f"\n 同数据用 n_perm=500 子采样:") t0 = time.perf_counter() r = ripser(data, maxdim=1, n_perm=500) print(f" 子采样: {time.perf_counter()-t0:.2f}s, " f"r_cover={r['r_cover']:.4f}, edges={r['num_edges']}")
def main():
maxdim_cost()
thresh_vs_edges()
reproducibility()
decision_tree_demo()
if name == "main":
main()