Skip to content
第14回: トポロジーという顕微鏡: 穴とループの発見

第14回: トポロジーという顕微鏡: 穴とループの発見

TIP

読了後に、理解度チェックで要点を確認できる。 このページで登場した用語は、キーワード集でも確認できる。

注意事項

  • パーシステントホモロジーは数学的に厳密な手法だが、「何を測っているか」の解釈はデータとタスクに依存する。
  • 「ResNetがトポロジーを保存する」等の主張は特定の研究の議論であり、一般的に確立された結論ではない。
  • TDAの深層学習への応用は発展途上の分野であり、実務での有効性は限定的な場面にとどまる。
  • 本回は「形ではなく構造を測る」という視点の導入が主目的であり、TDAの数学的厳密性は別途専門書を参照されたい。

導入:形を超えて構造を見る

これまでの講義では、表現空間の「形」を測る道具を整えてきた。距離、角度、曲率(これらは幾何学の言葉であり、「どれだけ離れているか」「どの方向を向いているか」を定量化する)。この道具立てで、表現空間の性質はもう十分に捉えられているように思える。

ところが、幾何学の物差しをどれだけ精密にしても、測り漏れる性質がある。

コーヒーカップとドーナツを考えよう。幾何学的には似ても似つかない。一方は取っ手が突き出し、もう一方は環状にくびれている。距離も曲率も違う数値を返すはずだ。それなのに、ある視点から見ると、両者は「同じ」と言い切れてしまう。どちらも「穴が1つある」という構造を共有しているからである。

この「穴」を数える数学が トポロジー(位相幾何学) である(Carlsson, 2009)。

トポロジーは、連続変形(伸ばす、曲げる、ねじる。ただし切ったり貼ったりしない)で保存される性質を研究する。この視点を深層学習の表現空間に向けると、そこにも「穴」や「ループ」が潜んでいることがある。その構造が学習の質や汎化性能と関係しているらしい、という報告もある。ただし、この関係がどこまで一般的に言えるものかは、まだ見極めがついていない。

これまで、私たちは望遠鏡で星の配置(表現空間の大域的な形)を眺めてきた。望遠鏡は全体の配置を捉える道具であり、個々の点がどこに位置するかを教えてくれる。しかし、点と点のあいだに空いた隙間が何を意味するかまでは、望遠鏡には答えられない。本回は道具を顕微鏡に持ち替え、その形の内側にある「穴」や「ループ」を覗き込む。

CAUTION

「顕微鏡」の比喩の限界: 望遠鏡・顕微鏡という対比は、大域的な形(距離・角度)と局所的な構造(穴・ループ)という異なる観点を直感的に伝えるための比喩である。実際のTDAは倍率を上げて詳細を見る操作ではなく、点の集合からスケールを変えながら位相的な特徴(連結成分・ループなど)を代数的に抽出する手法であり、光学的な拡大とは仕組みが異なる。

幾何学とトポロジー:二つの視点

何を測るか

コーヒーカップとドーナツが「同じ」だと認めるなら、距離や角度はもう主役ではない。幾何学とトポロジーは、空間を見る二つの異なるレンズである。

視点問い測るもの変換に対する不変性
幾何学どれだけ「離れている」か距離、角度、曲率等長変換(回転、平行移動)
トポロジーどのように「つながっている」か穴、ループ、連結成分連続変形(切らない、貼らない)

幾何学は「定量的」な測定を行う。2点間の距離が3なのか5なのかは、幾何学的に重要な区別である。

一方、トポロジーは「定性的」な性質を捉える。穴が「ある」か「ない」かは重要だが、穴の「大きさ」は(基本的には)問わない。数値を手放す代わりに、数値では表現できなかった区別が手に入る。

コーヒーカップとドーナツ

先ほどの言い切りが検証に耐えるか、トポロジーの定番の例で、実際に手を動かして確かめてみよう。

コーヒーカップを粘土でできていると想像する。取っ手を少しずつ太くし、本体を小さくしていく。この変形を続けると、最終的にドーナツ(トーラス)の形になる。この過程で、粘土を切ったり、新しく穴を開けたり、穴を塞いだりしていない。

このとき、コーヒーカップとドーナツは 同相(homeomorphic) であるという。同相とは、位相空間として両者の間に「連続かつ逆も連続な全単射(同相写像)」が存在することを意味する。直感的には「切らずに連続的に変形できる」ということだ。粘土をこねる手つきひとつで、二つの「別物」が同一視される。

NOTE

同相の直感: 二つの空間が同相であるとは、一方を「ゴムのように」伸び縮みさせて他方に変形できることを意味する。ただし、切断・接着は許されない。この条件下で保存される性質が「位相的性質」である。

ベッチ数:穴を数える

「穴がある・ない」という区別だけでは、じきに物足りなくなる。穴が2つある図形と3つある図形は、区別できて当然だろう。この数え上げを担うのが、トポロジーで最も基本的な不変量、 ベッチ数(Betti numbers) である。

ベッチ数意味直感
β0連結成分の数「島」がいくつあるか
β11次元の穴(ループ)の数「トンネル」がいくつあるか
β22次元の穴(空洞)の数「空洞」がいくつあるか
βnn 次元の穴の数高次元の「穴」

具体例を見よう:

図形β0β1β2説明
100連結成分1つ、穴なし
円周 S11101つのループ
球面 S2101内部に空洞
トーラス1212つのループ(縦と横)と1つの空洞
8の字1202つのループ

CAUTION

ベッチ数の限界: ベッチ数は「穴の数」を数えるが、穴の「配置」や「関係」は捉えない。例えば、2つの離れた円と8の字はどちらも β1=2 だが、構造は異なる。より精密な不変量(ホモロジー群の構造、持続ベッチ数など)が必要になる場合がある。

パーシステントホモロジー:スケールを超えた穴の追跡

問題:どのスケールで見るか

ベッチ数はきれいな図形の上でこそよく効く。円周にも球面にも、迷いなく穴の数を割り当てられた。しかし、実データは「きれいな」図形ではない。点群として与えられ、ノイズを含み、どのスケールで「穴」を認識すべきか自明ではない。

例えば、円周上にサンプリングされた点群を考えよう。点と点の間には隙間がある。この隙間を「穴」と見なすべきか。それとも、点群全体が作る「円」としての穴を見るべきか。どちらの答えも、単独では据わりが悪い。

パーシステントホモロジー(Persistent Homology) は、この問いに対する洗練された回答を与える(Edelsbrunner & Harer, 2010)。「どのスケールか」を一つに決めるのではなく、スケールそのものを動かしてしまう。そのアイデアは:

スケールを連続的に変化させ、各スケールで「穴」を数え、その「寿命」を記録する。

長く生き残る穴は「本質的な構造」を反映し、すぐに消える穴は「ノイズ」である可能性が高い。

フィルトレーション:スケールの掃引

「スケールを動かす」と言葉で言うのはたやすい。実際にどう計算するのか、手順を追ってみる。

Step 1: 点群から始める

データ点の集合 X={x1,x2,,xn} が与えられる。

Step 2: 各点の周りに「球」を描く

パラメータ ϵ0 を導入し、各点 xi の周りに半径 ϵ の球を描く。

Step 3: 球が重なったら「つなぐ」

2つの球が重なったら(つまり、2点間の距離が 2ϵ 以下なら)、その2点を辺で結ぶ。3つ以上の球が共通部分を持てば、三角形や高次元の単体を作る。これにより、スケール ϵ での 単体複体(simplicial complex) が構成される。

Step 4: ϵ を0から∞まで動かす

ϵ=0 では孤立した点のみ。 ϵ を大きくすると、点がつながり始め、ループができ、やがて全体が一つの塊になる。この単調な成長の途中で、ループは生まれては塞がれていく。

この過程で得られる単体複体の列を フィルトレーション(filtration) と呼ぶ:

K0K1K2Km

NOTE

Vietoris-Rips複体とČech複体: 上記の構成法には複数のバリエーションがある。Vietoris-Rips複体 は「すべての点対が 2ϵ 以内にある」場合に単体を作る(同値に、距離閾値以内の辺でできるグラフのクリーク(完全部分グラフ)から単体を構成する)。Čech複体 は「球の共通部分が非空」な場合に単体を作る。Rips複体の方が計算が容易だが、Čech複体の方が幾何学的に正確。実用上はRips複体が多く使われる。

閾値の流儀: 文献によって閾値を ϵ (球の半径)で書くか 2ϵ (直径)で書くかが異なる。実装や論文を参照する際は、どちらの流儀かを確認すること。

パーシステンス図:穴の「寿命」を可視化する

生まれては塞がれる穴を、一つずつ律儀に記録していけば、それぞれの穴に人生ならぬ「寿命」が書き込める。フィルトレーションを追跡すると、各「穴」には 誕生時刻(birth)死亡時刻(death) が定まる。

  • 誕生(birth):その穴が初めて現れる ϵ の値
  • 死亡(death):その穴が消える(塞がる) ϵ の値

これを2次元平面上にプロットしたものが パーシステンス図(persistence diagram) である。

txt
death
  ^
  |     *          * は「穴」を表す点
  |   *   *        対角線から遠いほど「長寿命」
  |  *     *
  | *   *
  |*__________> birth
  • 対角線上の点:誕生と同時に死亡(寿命0)→ ノイズ
  • 対角線から遠い点:長寿命 → 本質的な構造

TIP

パーシステンス図の読み方: 対角線からの距離(death - birth)を persistence(持続性) と呼ぶ。持続性が大きい点は、広いスケール範囲で観測される「頑健な」構造を表す。逆に、持続性が小さい点はノイズや局所的な揺らぎを反映していることが多い。

バーコード:もう一つの可視化

対角線からの距離という幾何学的な読み方に、もう少し慣れておきたい。パーシステンス図と等価な情報を持つ バーコード(barcode) も広く使われる。各穴を、誕生から死亡までの区間として水平線で表す。

txt
       birth          death
         |--------------|   長いバー = 重要な構造
         |---|              短いバー = ノイズ?
           |----|

バーコードは、穴の「寿命」を直感的に把握しやすい。

深層学習への応用

表現空間のトポロジー

深層学習モデルは、入力データを高次元の表現空間に写像する。この表現空間のトポロジー的構造と、モデルの性能や振る舞いの間に 相関が観察される ことがある(Gabrielsson & Carlsson, 2019)。トポロジーが性能を左右しているのだと言い切りたくなるが、そう単純には結論できない。これが因果関係(トポロジーが性能を決める)なのか、単なる相関なのか、あるいは共通の原因による見かけの関係なのかは、多くの場合まだ明らかではない。

応用例1:クラスタリングの質の評価

良い表現は、同じクラスの点を近くに、異なるクラスの点を遠くに配置する。しかし、「近い」「遠い」だけでは不十分な場合がある。

例えば、あるクラスの表現が「リング状」になっていると、ユークリッド距離に基づく分類器は中心付近で混乱する可能性がある。パーシステントホモロジーは、このような「トポロジー的な複雑さ」を検出できる。

応用例2:学習過程のモニタリング

学習の進行に伴い、表現空間の構造はどう変化するのだろうか。

初期のランダムな重みでは、表現は無秩序に分布している。学習が進むと、クラスごとにクラスタが形成され、やがて分離が明確になる、という筋書きは自然に思い浮かぶ。実際、この過程を各エポックでのパーシステンス図として追跡すると、おおむねその通りの推移が見える。

CAUTION

解釈の難しさ: 表現空間のトポロジーが「良い」とは何を意味するか?この問いに対する普遍的な答えはない。タスクによっては、トポロジー的に複雑な表現が必要な場合もあれば、単純な方が良い場合もある。TDAは「何があるか」を測るが、「何が望ましいか」は別の問いである。

研究事例:ニューラルネットワークの決定境界

「トポロジー的に複雑な表現」を検出できるとして、では層を重ねたネットワークは、その複雑さをどう扱っているのか。 Naitzat et al.は、二値分類データが学習済みニューラルネットワークの各層を通るときのトポロジー変化を調べた(Naitzat et al., 2020)。 実験対象は実データと合成データの点群であり、訓練精度が完全で汎化誤差がほぼゼロのモデルに条件を絞っている。 そのうえで、ReLUとtanh、浅いネットワークと深いネットワークなどを比較している。

主な知見:

  1. トポロジーの単純化:調査した学習済みモデルでは、層を通るにつれて各クラスのベッチ数が減り、表現のトポロジーが単純化した。
  2. 活性化関数による差:ベッチ数の減少は、tanhよりReLUを使うモデルで速く観察された。
  3. 深さによる差:浅いネットワークではトポロジー変化が終盤の層へ偏るのに対し、深いネットワークでは各層へより均等に分散した。

NOTE

結果の適用範囲: これらは、二値分類、点群、十分に学習されたモデルという実験条件で得られた観察である。 任意のデータ、タスク、アーキテクチャで同じ変化が生じると保証する定理ではない。

TDAの現在地

決定境界の話だけを見ると、TDAはすでに深層学習の中核に食い込んでいるようにも見える。だが、それは応用範囲の一角にすぎない。TDAの深層学習への応用は、以下のような段階にある:

応用領域成熟度状況(根拠)
表現空間の可視化・分析研究ツールとして一定の有用性(パーシステント図として結果を提示する論文が定着している)
学習過程のモニタリング低~中興味深い知見はあるが、実用性は限定的(層ごとの変化を追う研究例はあるが、標準的な監視指標にはなっていない)
損失関数への組み込みペアリングが固定された領域では微分を扱える手法があり、微分可能なトポロジー層も提案済み。ただし、ペアリングの切り替わりで非滑らかになり、計算コストや安定性に課題がある(Gabrielsson et al., 2020
アーキテクチャ設計への指針示唆はあるが、広く通用する直接的な設計原理には至っていない

IMPORTANT

TDAは「診断ツール」として有用: 現時点でのTDAの最大の価値は、表現空間の構造を「別の角度から見る」ことにある(Hensel et al., 2021)。幾何学的な指標(距離、角度)では見えない構造が、トポロジー的な視点から見えることがある。ただし、TDAの出力を直接最適化する手法は、まだ発展途上である。

まとめ:穴が語る構造

概念定義深層学習での役割
トポロジー連続変形で保存される性質の研究幾何では見えない構造を捉える視点
ベッチ数各次元の「穴」の数表現空間の複雑さの指標
パーシステントホモロジースケールを変えながら穴を追跡ノイズに頑健な構造抽出
パーシステンス図穴の誕生・死亡を2次元で可視化構造の「重要度」の判定

本回のメッセージ

形(幾何)だけでなく、構造(トポロジー)を見る目を持つ。

コーヒーカップとドーナツは、幾何学の物差しでは別物のままだった。距離を測っても、曲率を測っても、両者を「同じ」と呼ぶ理由は出てこない。それでも同じだと言い切れたのは、測る対象を「どれだけ」から「どのようにつながっているか」に切り替えたからである。幾何学は「どれだけ」を測り、トポロジーは「どのように」を測る。両者は補完的であり、表現空間を理解するための異なるレンズを提供する。

TDAは万能ではない。損失関数に直接組み込むにはまだ計算上の壁が高く、アーキテクチャ設計への指針としても示唆止まりである。それでも、「この表現空間には、隠れたループ構造があるのではないか」「学習の過程で、トポロジーが急激に変化していないか」といった問いは、幾何学だけを見ていては立てられなかった。パーシステンス図の対角線から遠い一点は、ノイズの海に埋もれない構造がまだそこにあることを示している。

TIP

読了後に、理解度チェックで要点を確認できる。 このページで登場した用語は、キーワード集でも確認できる。

次回予告

第15回「次の空間を設計する」では、これまでの14回で学んだ視点を統合する。平坦な空間から曲がった空間へ、幾何から位相へ、静的な構造から動的なプロセスへ。これらのパラダイムシフトを俯瞰し、未来の深層学習設計に向けた問いを提示する。

実装ノート:Ripserによるパーシステントホモロジー計算

NOTE

以下のコードは ripser (pip install ripser) と persim (pip install persim) を使用する(Tralie et al., 2018)。Python >= 3.8 を推奨。

CAUTION

実務上の注意点:

  • スケーリング:データの標準化や正規化により距離の意味が変わる。前処理の選択がパーシステンス図に大きく影響するため、目的に応じて慎重に選ぶこと。
  • サブサンプリング:高次元埋め込みでは、データ次元・maxdim・実装に依存するが、数百~数千点程度でも計算が重くなりうる。まずはサブサンプリングを検討すること。
  • 統計的安定性:点数が少ないとパーシステンス図は不安定になる。ブートストラップや複数回のサンプリングで安定性を確認すること。
  • クラス間比較:ラベル別に解析する場合、クラス間で点数を揃えるか、点数の違いを考慮した解釈が必要。

基本的な使い方

コード例: 14_ripser_basic.py
python
import numpy as np
from ripser import ripser


def compute_persistence(data, maxdim=1):
    """点群のパーシステントホモロジーを計算

    Args:
        data: 点群 (n_points, n_features)
        maxdim: 計算する最大次元(0=連結成分, 1=ループ, 2=空洞, ...)

    Returns:
        パーシステンス図のリスト(各次元に対して1つ)
    """
    result = ripser(data, maxdim=maxdim)
    return result["dgms"]


# 例1: ノイズ付きの円
np.random.seed(42)
n_points = 100
theta = 2 * np.pi * np.random.rand(n_points)
noise = 0.1 * np.random.randn(n_points, 2)
circle = np.column_stack([np.cos(theta), np.sin(theta)]) + noise

# パーシステンス図の計算
diagrams = compute_persistence(circle, maxdim=1)

print("H0 (連結成分):", diagrams[0].shape[0], "個の特徴")
print("H1 (ループ):", diagrams[1].shape[0], "個の特徴")

# 最も持続性の高いH1特徴(円の「穴」に対応)
h1_persistence = diagrams[1][:, 1] - diagrams[1][:, 0]
print(f"最大持続性: {h1_persistence.max():.3f}")

パーシステンス図の可視化

コード例: 14_visualization.py
python
import matplotlib.pyplot as plt
import numpy as np
from persim import plot_diagrams
from ripser import ripser


def visualize_persistence(data, title="Persistence Diagram"):
    """点群とパーシステンス図を並べて表示"""
    result = ripser(data, maxdim=1)
    diagrams = result["dgms"]

    fig, axes = plt.subplots(1, 2, figsize=(12, 5))

    # 点群の表示
    axes[0].scatter(data[:, 0], data[:, 1], s=20, alpha=0.7)
    axes[0].set_aspect("equal")
    axes[0].set_title("Point Cloud")

    # パーシステンス図の表示
    plot_diagrams(diagrams, ax=axes[1])
    axes[1].set_title(title)

    plt.tight_layout()
    return fig


# 例: 異なる形状の比較
np.random.seed(42)
n = 100

# 円
theta = 2 * np.pi * np.random.rand(n)
circle = np.column_stack([np.cos(theta), np.sin(theta)]) + 0.1 * np.random.randn(n, 2)

# 2つの円(8の字に近い)
theta1 = 2 * np.pi * np.random.rand(n // 2)
theta2 = 2 * np.pi * np.random.rand(n // 2)
two_circles = np.vstack(
    [
        np.column_stack([np.cos(theta1) - 1, np.sin(theta1)]),
        np.column_stack([np.cos(theta2) + 1, np.sin(theta2)]),
    ]
)
two_circles += 0.1 * np.random.randn(n, 2)

# ランダムな点群
random_cloud = np.random.randn(n, 2)

# 可視化(実行時)
# visualize_persistence(circle, "Circle: 1 loop expected")
# visualize_persistence(two_circles, "Two circles: 2 loops expected")
# visualize_persistence(random_cloud, "Random: no persistent loops expected")

表現空間の解析

コード例: 14_representation_analysis.py
python
import numpy as np
from ripser import ripser


def analyze_representation_topology(embeddings, labels, maxdim=1):
    """表現空間のトポロジーをクラスごとに解析

    Args:
        embeddings: 表現ベクトル (n_samples, n_features)
        labels: クラスラベル (n_samples,)
        maxdim: 計算する最大次元

    Returns:
        各クラスのトポロジー的特徴の要約
    """
    results = {}
    unique_labels = np.unique(labels)

    for label in unique_labels:
        mask = labels == label
        class_embeddings = embeddings[mask]

        # パーシステントホモロジー計算
        dgms = ripser(class_embeddings, maxdim=maxdim)["dgms"]

        # 各次元の持続性統計
        stats = {}
        for dim in range(maxdim + 1):
            if len(dgms[dim]) > 0:
                # 無限大の死亡時刻を除外
                finite_mask = np.isfinite(dgms[dim][:, 1])
                if finite_mask.any():
                    persistence = dgms[dim][finite_mask, 1] - dgms[dim][finite_mask, 0]
                    stats[f"H{dim}_count"] = len(persistence)
                    stats[f"H{dim}_max_persistence"] = persistence.max()
                    stats[f"H{dim}_mean_persistence"] = persistence.mean()
                else:
                    stats[f"H{dim}_count"] = 0

        results[label] = stats

    return results


# 使用例(モデルの表現を取得した後)
# embeddings = model.get_embeddings(data)
# topology_stats = analyze_representation_topology(embeddings, labels)
# for label, stats in topology_stats.items():
#     print(f"Class {label}: {stats}")

学習過程のトポロジー追跡

コード例: 14_training_topology.py
python
import numpy as np
from ripser import ripser


def track_topology_during_training(
    model,
    data_loader,
    epochs,
    sample_size=500,
    maxdim=1,
):
    """学習中の表現空間トポロジーを追跡

    Args:
        model: PyTorchモデル(get_embeddingsメソッドを持つ)
        data_loader: データローダー
        epochs: エポック数
        sample_size: 各エポックでサンプリングする点数
        maxdim: 計算する最大次元

    Returns:
        各エポックのトポロジー統計
    """
    topology_history = []

    for epoch in range(epochs):
        # モデルを1エポック学習
        # train_one_epoch(model, data_loader)

        # 表現を取得(サンプリング)
        # embeddings = sample_embeddings(model, data_loader, sample_size)

        # ダミーデータで例示
        embeddings = np.random.randn(sample_size, 64)

        # パーシステントホモロジー計算
        dgms = ripser(embeddings, maxdim=maxdim)["dgms"]

        # H1の持続性統計を記録
        h1_dgm = dgms[1]
        finite_mask = np.isfinite(h1_dgm[:, 1])
        if finite_mask.any():
            h1_persistence = h1_dgm[finite_mask, 1] - h1_dgm[finite_mask, 0]
            epoch_stats = {
                "epoch": epoch,
                "h1_count": len(h1_persistence),
                "h1_max": h1_persistence.max(),
                "h1_mean": h1_persistence.mean(),
                "h1_total": h1_persistence.sum(),
            }
        else:
            epoch_stats = {
                "epoch": epoch,
                "h1_count": 0,
                "h1_max": 0,
                "h1_mean": 0,
                "h1_total": 0,
            }

        topology_history.append(epoch_stats)

    return topology_history

CAUTION

計算コストに注意: パーシステントホモロジーの計算は、単体複体のサイズに依存する。Vietoris-Rips複体では、点の数 n に対して単体数が組合せ爆発的に増加しうるため、高次元や大規模データでは計算が非常に重くなる。実務では、サブサンプリング、次元の制限(maxdim=1程度)、近似手法(利用可能であればRipser++、Approximate Rips等)の使用を検討すること。

参考文献

パーシステントホモロジー(数学的基礎)

  • Edelsbrunner, H., & Harer, J. (2010). Computational Topology: An Introduction. American Mathematical Society. DOI: 10.1090/mbk/069
    • 計算トポロジーの標準的教科書。パーシステントホモロジーの理論的基盤を厳密に扱う。
  • Carlsson, G. (2009). Topology and Data. Bulletin of the American Mathematical Society, 46(2), 255–308. DOI: 10.1090/S0273-0979-09-01249-X
    • TDAの創始者による解説論文。データ解析へのトポロジー応用の動機と基本概念を説明。

深層学習への応用

  • Naitzat, G., Zhitnikov, A., & Lim, L.-H. (2020). Topology of Deep Neural Networks. JMLR, 21(184), 1–40. arXiv: 2004.06093
    • 二値分類データが学習済みネットワークの各層を通るときのトポロジー変化を分析。活性化関数と深さによる差を議論。
  • Gabrielsson, R. B., & Carlsson, G. (2019). Exposition and Interpretation of the Topology of Neural Networks. ICMLA 2019. DOI: 10.1109/ICMLA.2019.00180
    • ニューラルネットワークの活性化空間のトポロジー解析手法を提案。
  • Gabrielsson, R. B., Nelson, B. J., Dwaraknath, A., & Skraba, P. (2020). A Topology Layer for Machine Learning. AISTATS 2020, 1553–1563. https://proceedings.mlr.press/v108/gabrielsson20a.html
    • パーシステントホモロジーを勾配ベースの学習へ組み込む微分可能なトポロジー層を提案。

ソフトウェア

  • Tralie, C., Saul, N., & Bar-On, R. (2018). Ripser.py: A Lean Persistent Homology Library for Python. JOSS, 3(29), 925. DOI: 10.21105/joss.00925
  • GUDHI Project (2025). GUDHI Library. https://gudhi.inria.fr/
    • より包括的なTDAライブラリ。Čech複体、 α 複体など多様な構成法をサポート。
    • gudhi.inria.fr

関連するサーベイ

  • Hensel, F., Moor, M., & Rieck, B. (2021). A Survey of Topological Machine Learning Methods. Frontiers in Artificial Intelligence, 4, 681108. DOI: 10.3389/frai.2021.681108
    • TDAと機械学習の交差点に関する包括的なサーベイ。応用事例と課題を整理。