第12回:双曲幾何学 ~負の曲率の世界~
注意事項
- 双曲空間が有効なのは、データに階層的・木構造的な性質がある場合に限られる。
- すべてのデータが双曲空間に適しているわけではない(平坦・球面が適する場合も多い)。
- 「曲率の選択」はタスク依存であり、万能の幾何学は存在しない。
- Mixed-curvature spaces(複合曲率空間)は研究段階であり、標準手法ではない。
- 本回で扱う「ポアンカレ円板」は双曲空間の一つのモデルであり、双曲空間そのものではない(同じ空間の異なる「地図」が複数存在する)。
導入:球面の「外」へ
第3回から第11回まで、私たちは主に正の曲率を持つ空間——球面——を舞台に議論してきた。正規化されたベクトルは単位球面上の点として、コサイン類似度は角度として解釈できた。この枠組みは、意味的な類似性を測る多くのタスクで有効だった。
しかし、世界には球面では表現しきれない構造がある。
WordNetの階層構造を考えてみよう。「動物」という概念の下には「哺乳類」「鳥類」「魚類」……と子概念が広がり、「哺乳類」の下にはさらに「犬」「猫」「人間」……と孫概念が連なる。この構造を球面に埋め込もうとすると、深い階層に行くほど「場所が足りなくなる」。球面の表面積は有限であり、指数関数的に増える子ノードを収容できないのだ。
本回では、この問題を解決する双曲空間(hyperbolic space) を導入する。負の曲率を持つこの空間は、階層構造を自然に表現する能力を持っている。なぜそうなるのかを、幾何学的な直感から理解していこう。
階層構造の埋め込み問題:なぜ球面では足りないのか
木構造の指数的成長
木構造(tree structure)は、自然言語処理、知識グラフ、生物学など、あらゆる分野に現れる基本的なデータ構造である。
その特徴は指数的な成長にある。根ノードから出発し、各ノードが
| 深さ | ノード数( | ノード数( |
|---|---|---|
| 0 | 1 | 1 |
| 1 | 2 | 10 |
| 2 | 4 | 100 |
| 3 | 8 | 1,000 |
| 10 | 1,024 | 10,000,000,000 |
この指数的成長が、埋め込みにおいて問題を引き起こす。
ユークリッド空間での困難
ユークリッド空間
直感的に、親ノードの「周り」に子ノードを配置したい。しかし、ユークリッド空間では、半径
結果として、深い階層を埋め込もうとすると、以下の問題が生じる:
- 歪み(distortion)の増大:ノード間の距離関係が正しく保存されない
- 次元の爆発:歪みを抑えるために必要な次元数が指数的に増加する
- 親子関係の曖昧化:深い階層では、親と子の距離と、兄弟間の距離が区別しにくくなる
NOTE
歪みの定義: 埋め込み
(通常、
球面空間での困難
では、球面
球面は正の曲率を持つ。通常の2次元球面(球の表面、
問題は、
球面は、「対等な関係」(意味的な類似性、クラスタリング)には適しているが、「上下関係」(階層構造)には不向きなのだ。
| 空間 | 曲率 | 測地線円の周囲長(2次元、曲率 | 木構造への適性 |
|---|---|---|---|
| ユークリッド平面 | 0 | 低い(深い階層で容量不足) | |
| 単位球面 | 低い(容量不足) | ||
| 双曲平面 | 高い |
双曲空間:負の曲率の世界
負の曲率とは何か
第0回で、曲率を「三角形の内角の和」で直感的に理解した。正の曲率(球面)では内角の和が180°を超え、負の曲率では180°を下回る。
負の曲率を持つ曲面の最も身近な例は鞍型曲面(saddle surface) である。馬の鞍や、プリングルスのチップスの形を思い浮かべてほしい。この曲面上で三角形を描くと、辺が「内側に引っ張られる」ように曲がり、内角の和は180°より小さくなる。
NOTE
局所的な形状と大域的な構造: 鞍型曲面は負の曲率の「局所的な形状」を示すが、完全な双曲平面(一定負曲率の完備曲面)を3次元ユークリッド空間に等長に埋め込むことはできない(Hilbertの定理)。ここで「完全(complete)」とは距離空間として完備(コーシー列が収束する)であることを意味し、リーマン多様体では Hopf–Rinow の定理により測地線が途中で途切れないという直感と対応する。「等長」とは距離関係を保存することを意味する。局所的な鞍型パッチは作れるが、双曲空間「全体」を歪みなく3次元に実現することはできない。そのため、双曲空間を視覚化するには「モデル」が必要になる。これは、球面を平面の地図で表すときに歪みが生じるのと似ている。
指数的に広がる周囲
双曲空間の最も重要な性質は、周囲長が指数関数的に増大することである。
具体的には、双曲平面
これが木構造の埋め込みに適している理由である:
- 根ノード(中心)から離れるほど、「場所」が指数的に増える
- 深さ
のノード数 を、半径 の位置に自然に配置できる - 親子関係は「中心からの距離」として、兄弟関係は「同じ深さでの角度」として表現される
ユークリッド空間: 双曲空間:
周囲 ∝ r 周囲 ∝ e^r
・・・ ・・・・・・・・・・・・・・
・ ・ ・ ・
・ ・ ・ ・
・ ● ・ ・ ● ・
・ ・ ・ ・
・ ・ ・ ・
・・・ ・・・・・・・・・・・・・・
(多項式的成長) (指数的成長)双曲空間の距離公式
- 三角不等式を満たす
- 中心から離れるほど、同じ座標差でも距離が大きくなる
- 測地線(最短経路)は、モデルによって異なる見え方をする
具体的な距離公式は、次節で紹介するポアンカレ円板モデルで説明する。
ポアンカレ円板モデル:無限を有限に閉じ込める
モデルとは何か
完全な双曲空間は、3次元ユークリッド空間に等長に埋め込めない(前述のHilbertの定理)。そのため、私たちは双曲空間を「見る」ために、何らかのモデル(model) を使う必要がある。
これは、地球(球面)を平面の地図で表すのと同じ状況だ。メルカトル図法、正距方位図法、モルワイデ図法……いずれも同じ球面を表しているが、それぞれ異なる歪み方をする。
双曲空間にも複数のモデルがある:
| モデル | 特徴 | 用途 |
|---|---|---|
| ポアンカレ円板 | 単位円板内に表現、角度を保存(等角) | 可視化、多くの実装 |
| ポアンカレ半平面 | 上半平面に表現、等角 | 理論的解析 |
| ローレンツモデル | 高次元空間内の双曲面として表現 | 数値的安定性 |
| クラインモデル | 単位円板内に表現、測地線が直線 | 特定の幾何学的議論 |
本回では、可視化に優れ、実装例も多いポアンカレ円板モデルを中心に扱う。
ポアンカレ円板の構造
ポアンカレ円板(Poincaré disk) は、2次元の場合、単位円板
このモデルの驚くべき点は、有限の円板内に無限の双曲空間が収まっていることだ。
- 円板の中心が双曲空間の「原点」に対応
- 円板の境界(単位円)は「無限遠」に対応
- 中心から境界へ向かうにつれ、双曲距離は無限大に発散
これを直感的に理解するために、エッシャーの版画「円の極限 (Circle Limit)」シリーズを思い出してほしい。中心から離れるほど図形が小さくなっていくが、双曲空間の「住人」から見ると、すべての図形は同じ大きさである。小さく見えるのは、私たちがユークリッド的な目で見ているからだ。
距離公式
ポアンカレ円板モデルにおける2点
ここで
この式から、いくつかの重要な性質が読み取れる:
境界効果:
または のとき、分母が0に近づき、距離は無限大に発散する。これが「境界は無限遠」の数学的表現である。 中心での近似:
(中心付近)では、双曲距離はユークリッド距離に近似される。中心付近は「ほぼ平坦」に見える。 非対称なスケール:同じユークリッド距離
でも、境界に近い場所ほど双曲距離は大きくなる。
CAUTION
数値的安定性: ポアンカレ円板モデルでは、境界付近(
測地線の形状
ポアンカレ円板モデルにおける測地線(最短経路)は、円板の境界に直交する円弧として描かれる。中心を通る測地線に限り、直線(直径)になる。
これは、ユークリッド空間での直線が、このモデルでは曲がって見えることを意味する。双曲空間の「住人」にとっては真っ直ぐな道が、私たちの目には曲線に見えるのだ。
ポアンカレ円板上の測地線:
┌────────────┐
╱ ╲
│ ╭────╮ │
│ ╱ ╲ │
│ ╱ ● ╲ │ ● = 中心
│ ╲ ╱ │
│ ╲ ╱ │
│ ╰────╯ │
╲ ╱
└────────────┘
(境界に直交する円弧が測地線)階層構造の自然な埋め込み
木構造との対応
双曲空間の構造と木構造の構造には、自然な対応関係がある:
| 木構造の性質 | 双曲空間での対応 |
|---|---|
| 根ノード | 円板の中心付近 |
| 深さ | 中心から双曲距離 |
| 親子関係 | 半径方向の近さ |
| 兄弟関係 | 同じ半径上での角度 |
| ノード数の指数的増加 | 周囲長の指数的増加 |
この対応により、木構造を双曲空間に埋め込むと、以下の利点が得られる:
- 低歪み:親子間の距離と、非隣接ノード間の距離が正しく区別される
- 低次元の可能性:ユークリッド空間では多くの次元を必要とする場合でも、双曲空間では低次元(例:2次元や5次元)で良好な結果が得られることがある。ただし、これはデータの階層性の度合い、損失関数の設計、最適化の成否に依存する。
- スケーラビリティ:深い階層でも「場所が足りなくなる」ことがない
Poincaré Embeddings
Nickel & Kiela (2017) は、双曲空間(ポアンカレ円板モデル)に単語や概念を埋め込むPoincaré Embeddingsを提案した。これは、双曲幾何学を機械学習に応用した先駆的な研究である。
基本的なアイデアは、WordNetのような階層的語彙データベースを、ポアンカレ円板に埋め込むことである。「動物」「哺乳類」「犬」という上位-下位関係を持つ概念は、中心から外側へと配置される。
損失関数は、以下のような形で設計される:
ここで
IMPORTANT
双曲空間での勾配降下: ポアンカレ円板はユークリッド空間ではないため、通常の勾配降下法をそのまま適用できない。リーマン勾配降下法を用いるか、指数写像(exponential map)と対数写像(logarithmic map)を使って「接空間での更新→多様体への射影」という操作を行う必要がある。詳細は実装ノートを参照。
応用例
双曲埋め込みは、以下のような応用で有効性が示されている:
WordNetの埋め込み:語彙の上位-下位関係を低次元で表現。ユークリッド空間の200次元と同等の表現力を、双曲空間の5次元で達成(Nickel & Kiela, 2017)。
知識グラフ:エンティティ間の「is-a」「part-of」などの階層的関係をモデル化。TransEなどのユークリッドベースの手法に対して、階層的関係の予測精度が向上(Balažević et al., 2019)。
社会ネットワーク:影響力の階層構造(インフルエンサー→フォロワー)をモデル化。スケールフリーネットワークの構造を自然に捉える。
系統樹:進化生物学における種の分岐構造。木構造そのものであるため、双曲空間との相性が極めて良い。
| 応用分野 | データ例 | 双曲空間の利点 |
|---|---|---|
| 自然言語処理 | WordNet, ConceptNet | 語彙の上位-下位関係を低次元で表現 |
| 知識グラフ | Freebase, Wikidata | 階層的関係の予測精度向上 |
| ネットワーク分析 | 社会ネットワーク, Webグラフ | スケールフリー構造のモデル化 |
| 生物学 | 系統樹, 遺伝子オントロジー | 木構造の低歪み埋め込み |
球面との対比:正と負の曲率
幾何学的性質の比較
ここで、球面(正曲率)と双曲空間(負曲率)の性質を改めて比較しよう。以下は2次元の場合(単位球面
| 性質 | 球面(正曲率) | 双曲空間(負曲率) |
|---|---|---|
| 三角形の内角和 | > 180° | < 180° |
| 測地線円の周囲長 | ||
| 平行線 | 存在しない(すべて交わる) | 無限に存在する |
| 測地線の収束 | 最終的に交わる | 発散する |
| 全体の「形」 | 閉じている(有限) | 開いている(無限) |
適したデータ構造
この幾何学的な違いは、適したデータ構造の違いに直結する:
球面が適するケース:
- 等価な関係:意味的な類似性、クラスタリング
- 循環的な構造:季節、曜日、色相環
- 正規化が重要:表現のノルムを揃えたい場合
双曲空間が適するケース:
- 階層的関係:木構造、分類体系、組織図
- スケールフリーネットワーク:次数分布がべき乗則に従うグラフ
- 指数的成長:再帰的に分岐する構造
ユークリッド空間が適するケース:
- 平坦な関係:特に強い構造がない場合
- 時系列:線形に進む時間
- 加法的な性質:ベクトルの足し算が意味を持つ場合
NOTE
「適している」の意味: ここでの「適している」は、「低歪みで埋め込める」「少ない次元で表現できる」「下流タスクの精度が向上する」といった経験的な効果を指す。すべてのデータが明確にいずれかのカテゴリに属するわけではなく、実際には複数の構造が混在していることが多い。
曲率の学習
データの構造が事前に分からない場合、曲率自体を学習可能なパラメータとするアプローチもある。
曲率
これは、「幾何学をデータから発見する」という野心的な方向性であり、現在も活発に研究されている(Gu et al., 2019; Bachmann et al., 2020)。
拡張:Mixed-Curvature Spaces
単一曲率の限界
現実のデータは、複数の構造が混在していることが多い。
例えば、商品カタログを考えよう:
- カテゴリ階層:「電子機器 > スマートフォン > iPhone」→ 双曲的
- 類似商品:「iPhone 15」と「iPhone 15 Pro」の類似性 → 球面的
- 価格帯:連続的なスケール → ユークリッド的
すべてを単一の幾何学で表現しようとすると、どこかで無理が生じる。
複合曲率空間
Mixed-curvature spaces(複合曲率空間) は、異なる曲率を持つ部分空間を組み合わせるアプローチである:
ここで
各部分空間が異なる種類の構造を担当することで、より柔軟な表現が可能になる:
- 「意味的類似性」は球面部分で
- 「階層構造」は双曲部分で
- 「連続的なスケール」はユークリッド部分で
CAUTION
研究段階の技術: Mixed-curvature spacesは理論的には魅力的だが、実装の複雑さ、学習の不安定性、解釈の困難さなどの課題がある。標準的な手法として確立されているわけではなく、適用には注意が必要である。
関連研究
複合曲率空間に関する代表的な研究:
- Ultrahyperbolic representations(Law et al., 2021):正と負の曲率を混合した擬リーマン多様体での表現学習
- Product manifolds(Gu et al., 2019):球面・双曲・ユークリッドの直積空間での埋め込み
- Gyrovector spaces:双曲空間におけるベクトル演算の体系化(Ungar, 2008)
Visualization Break IV:ポアンカレ円板を体験する
デモ:木構造の埋め込み比較
以下のデモでは、同じ木構造を(1)ユークリッド空間と(2)ポアンカレ円板に埋め込み、その違いを視覚的に理解する。
木構造(3階層、分岐数2):
0
/ \
1 2
/ \ / \
3 4 5 6ユークリッド空間での埋め込み:
- 深い階層のノードが密集しやすい
- 親子関係と兄弟関係の区別が曖昧になる
- 「場所が足りない」感覚
ポアンカレ円板での埋め込み:
- 根ノードは中心付近
- 深い階層ほど外側(境界に近い)
- 各階層に十分な「部屋」がある
- 親子関係が半径方向、兄弟関係が角度方向に対応
TIP
インタラクティブな体験: ポアンカレ円板の直感を得るには、実際に操作してみるのが一番である。HyperTools や Hyperbolic Embedding Playground などのツールで、双曲空間を体験できる。
まとめ
| 概念 | 定義 | 本回での役割 |
|---|---|---|
| 双曲空間 | 負の曲率を持つ空間 | 階層構造の自然な表現 |
| ポアンカレ円板 | 双曲空間のモデル(単位円板内) | 可視化と実装の基盤 |
| 指数的成長 | 周囲長が | 木構造との対応の鍵 |
| リーマン最適化 | 多様体上での勾配法 | 双曲埋め込みの学習に必須 |
| Mixed-curvature | 複数の曲率を組み合わせ | 複雑なデータ構造への対応 |
本回のポイント
双曲空間は、「負の曲率」という一見奇妙な性質を持つ空間である。しかし、その性質——周囲長の指数的成長——は、木構造や階層構造の本質と深く対応している。
球面が「対等な関係」を表現するのに適しているのに対し、双曲空間は「上下関係」を表現するのに適している。これは、空間の曲率という幾何学的な概念が、データの構造という意味論的な概念と結びついていることを示している。
「どの幾何学を選ぶか」は、データの構造に依存する。万能の幾何学は存在しない。しかし、幾何学という言語を持つことで、「なぜこの設計が有効なのか」を説明し、「どのような構造に適しているのか」を予測できるようになる。
問い
データの「形」を事前に知ることなく、最適な幾何学を発見できるか?
曲率を学習可能にするアプローチ、複合曲率空間、あるいは全く新しい幾何学——この問いへの答えは、まだ探求の途上にある。
次回予告
第13回「高次元の深淵 ~幾何学的な恐怖と祝福~」では、これまで避けてきた高次元空間の「奇妙な性質」に正面から向き合う。
高次元空間では、ランダムに選んだ2つのベクトルがほぼ直交する。距離の区別がつきにくくなる。しかし同時に、指数的に多くの「ほぼ直交した」方向を持つことができる。この性質は、Mixture of Experts(MoE)やスパース表現の設計とどう関係するのか。高次元の「恐怖」と「祝福」を、幾何学的な視点から理解する。
実装ノート
NOTE
以下のコードは PyTorch >= 1.9 を前提とする。再現性のために torch.manual_seed(42) 等でシードを固定することを推奨。双曲幾何学の最適化には、Geoopt ライブラリが有用である。
IMPORTANT
曲率パラメータについて: 以下のコード例はすべて曲率
ポアンカレ円板の距離計算
コード例: 12_poincare_distance.py
import torch
def poincare_distance(u, v, eps=1e-5):
"""ポアンカレ円板モデルにおける双曲距離
Args:
u: 点1 [batch, dim] または [dim]
v: 点2 [batch, dim] または [dim]
eps: 数値安定性のための小さな値
Returns:
双曲距離
"""
# ノルムの2乗
u_norm_sq = torch.clamp(torch.sum(u * u, dim=-1), max=1 - eps)
v_norm_sq = torch.clamp(torch.sum(v * v, dim=-1), max=1 - eps)
diff_norm_sq = torch.sum((u - v) ** 2, dim=-1)
# 距離公式
numerator = 2 * diff_norm_sq
denominator = (1 - u_norm_sq) * (1 - v_norm_sq)
# arcosh(1 + x) = log(1 + x + sqrt(x^2 + 2x)) for numerical stability
x = numerator / (denominator + eps)
return torch.log(1 + x + torch.sqrt(x * x + 2 * x + eps))
# 使用例
u = torch.tensor([0.0, 0.0]) # 中心
v = torch.tensor([0.5, 0.0]) # 中心から離れた点
w = torch.tensor([0.9, 0.0]) # 境界に近い点
print(f"d(center, mid): {poincare_distance(u, v):.4f}")
print(f"d(center, edge): {poincare_distance(u, w):.4f}")
print(f"d(mid, edge): {poincare_distance(v, w):.4f}")
# 期待される結果:
# 境界に近い点への距離が非常に大きくなる指数写像と対数写像
コード例: 12_exp_log_maps.py
import torch
def mobius_add(u, v, eps=1e-5):
"""メビウス加法(双曲空間でのベクトル加法)
ポアンカレ円板モデルにおける「平行移動」に相当する操作
"""
u_norm_sq = torch.sum(u * u, dim=-1, keepdim=True)
v_norm_sq = torch.sum(v * v, dim=-1, keepdim=True)
uv = torch.sum(u * v, dim=-1, keepdim=True)
numerator = (1 + 2 * uv + v_norm_sq) * u + (1 - u_norm_sq) * v
denominator = 1 + 2 * uv + u_norm_sq * v_norm_sq + eps
return numerator / denominator
def exp_map_0(v, eps=1e-5):
"""原点における指数写像
接空間(ユークリッド)のベクトルを、
ポアンカレ円板上の点に写す
Args:
v: 接空間のベクトル [batch, dim]
Returns:
ポアンカレ円板上の点
"""
v_norm = torch.clamp(torch.norm(v, dim=-1, keepdim=True), min=eps)
return torch.tanh(v_norm) * v / v_norm
def log_map_0(y, eps=1e-5):
"""原点における対数写像
ポアンカレ円板上の点を、
接空間(ユークリッド)のベクトルに写す
Args:
y: ポアンカレ円板上の点 [batch, dim]
Returns:
接空間のベクトル
"""
y_norm = torch.clamp(torch.norm(y, dim=-1, keepdim=True), min=eps, max=1 - eps)
return torch.atanh(y_norm) * y / y_norm
def project_to_poincare(x, eps=1e-5):
"""点をポアンカレ円板内に射影
境界を超えた点を、境界内に引き戻す
"""
norm = torch.norm(x, dim=-1, keepdim=True)
max_norm = 1 - eps
cond = norm > max_norm
return torch.where(cond, x / norm * max_norm, x)
# 使用例:リーマン勾配降下法の1ステップ
def riemannian_sgd_step(x, euclidean_grad, lr=0.01):
"""リーマン勾配降下法の1ステップ
1. ユークリッド勾配をリーマン勾配に変換
2. 接空間で更新
3. 多様体に射影
"""
# リーマン計量によるスケーリング
# ポアンカレ円板の計量テンソル: g_x = (2 / (1 - ||x||^2))^2 * I
x_norm_sq = torch.sum(x * x, dim=-1, keepdim=True)
scale = ((1 - x_norm_sq) ** 2) / 4
riemannian_grad = scale * euclidean_grad
# 接空間での更新(対数写像で接空間へ、更新後、指数写像で戻る)
# 簡易版:直接更新して射影
x_new = x - lr * riemannian_grad
x_new = project_to_poincare(x_new)
return x_new
# テスト
x = torch.tensor([[0.3, 0.4]])
grad = torch.tensor([[0.1, 0.1]])
x_new = riemannian_sgd_step(x, grad, lr=0.1)
print(f"Before: {x}, norm={torch.norm(x):.4f}")
print(f"After: {x_new}, norm={torch.norm(x_new):.4f}")簡易的な木構造の埋め込み
コード例: 12_tree_embedding.py
import torch
import torch.nn as nn
import torch.optim as optim
class PoincareEmbedding(nn.Module):
"""ポアンカレ円板への埋め込み"""
def __init__(self, num_nodes, dim, init_scale=0.001):
super().__init__()
# 小さな値で初期化(中心付近からスタート)
self.embeddings = nn.Parameter(torch.randn(num_nodes, dim) * init_scale)
self.eps = 1e-5
def forward(self, indices):
emb = self.embeddings[indices]
# ポアンカレ円板内に射影
return self._project(emb)
def _project(self, x):
norm = torch.norm(x, dim=-1, keepdim=True)
max_norm = 1 - self.eps
return torch.where(norm > max_norm, x / norm * max_norm, x)
def distance(self, u, v):
"""ポアンカレ距離"""
u_norm_sq = torch.clamp(torch.sum(u * u, dim=-1), max=1 - self.eps)
v_norm_sq = torch.clamp(torch.sum(v * v, dim=-1), max=1 - self.eps)
diff_norm_sq = torch.sum((u - v) ** 2, dim=-1)
x = 2 * diff_norm_sq / ((1 - u_norm_sq) * (1 - v_norm_sq) + self.eps)
return torch.log(1 + x + torch.sqrt(x * x + 2 * x + self.eps))
def train_tree_embedding(edges, num_nodes, dim=2, epochs=1000, lr=0.01):
"""木構造をポアンカレ円板に埋め込む
Args:
edges: エッジのリスト [(parent, child), ...]
num_nodes: ノード数
dim: 埋め込み次元
epochs: エポック数
lr: 学習率
Returns:
学習済み埋め込み
"""
model = PoincareEmbedding(num_nodes, dim)
optimizer = optim.Adam(model.parameters(), lr=lr)
edges_tensor = torch.tensor(edges)
for epoch in range(epochs):
optimizer.zero_grad()
# 正例:エッジで接続されたノードペア
pos_u = model(edges_tensor[:, 0])
pos_v = model(edges_tensor[:, 1])
pos_dist = model.distance(pos_u, pos_v)
# 負例:ランダムなノードペア
neg_indices = torch.randint(0, num_nodes, (len(edges) * 5, 2))
neg_u = model(neg_indices[:, 0])
neg_v = model(neg_indices[:, 1])
neg_dist = model.distance(neg_u, neg_v)
# 損失:正例の距離を小さく、負例の距離を大きく
margin = 1.0
loss = torch.mean(torch.relu(pos_dist - neg_dist + margin))
loss.backward()
# 勾配クリップ(双曲空間では重要)
torch.nn.utils.clip_grad_norm_(model.parameters(), max_norm=1.0)
optimizer.step()
# 射影(境界内に保持)
with torch.no_grad():
model.embeddings.data = model._project(model.embeddings.data)
if (epoch + 1) % 200 == 0:
print(f"Epoch {epoch + 1}, Loss: {loss.item():.4f}")
return model
# 使用例:簡単な木構造
# 0 (root)
# ├── 1
# │ ├── 3
# │ └── 4
# └── 2
# ├── 5
# └── 6
edges = [(0, 1), (0, 2), (1, 3), (1, 4), (2, 5), (2, 6)]
num_nodes = 7
model = train_tree_embedding(edges, num_nodes, dim=2, epochs=1000)
# 結果の確認
with torch.no_grad():
embeddings = model(torch.arange(num_nodes))
norms = torch.norm(embeddings, dim=1)
print("\n埋め込み結果:")
for i in range(num_nodes):
print(f" Node {i}: pos={embeddings[i].numpy()}, norm={norms[i]:.4f}")
# 期待される結果:
# - 根ノード(0)は中心に近い
# - 葉ノード(3,4,5,6)は境界に近い
# - 深さに応じてノルムが増加Geooptの利用例
コード例: 12_geoopt_example.py
# pip install geoopt
import geoopt
import torch
def geoopt_poincare_example():
"""Geooptライブラリを使ったポアンカレ球での操作例"""
# ポアンカレ球多様体(デフォルトは曲率-1)
ball = geoopt.PoincareBall()
# ランダムな点を生成(多様体上に)
x = ball.random(2, 5) # [2, 5] の形状
print(f"Points on Poincaré ball:\n{x}")
print(f"Norms: {torch.norm(x, dim=-1)}") # 必ず < 1
# 2点間の距離
y = ball.random(2, 5)
dist = ball.dist(x, y)
print(f"Distances: {dist}")
# 指数写像(接空間 → 多様体)
origin = torch.zeros(5)
v = torch.randn(5) * 0.1 # 接ベクトル
point = ball.expmap(origin, v)
print(f"Exp map result: {point}, norm={torch.norm(point):.4f}")
# 対数写像(多様体 → 接空間)
v_back = ball.logmap(origin, point)
print(f"Log map result: {v_back}")
print(f"Original v: {v}")
# 測地線に沿った補間
t = 0.5
midpoint = ball.geodesic(t, x[0], y[0])
print(f"Midpoint on geodesic: {midpoint}")
def geoopt_optimization_example():
"""Geooptを使ったリーマン最適化の例"""
ball = geoopt.PoincareBall()
# 多様体上のパラメータ
x = geoopt.ManifoldParameter(ball.random(10, 5), manifold=ball)
# リーマン最適化器
optimizer = geoopt.optim.RiemannianAdam([x], lr=0.01)
# ダミーの最適化(中心に向かう)
for i in range(100):
optimizer.zero_grad()
loss = torch.sum(x**2) # 中心(原点)に近づける
loss.backward()
optimizer.step()
if (i + 1) % 20 == 0:
avg_norm = torch.norm(x, dim=-1).mean()
print(f"Step {i + 1}, Loss: {loss.item():.4f}, Avg norm: {avg_norm:.4f}")
if __name__ == "__main__":
print("=== Poincaré Ball Operations ===")
geoopt_poincare_example()
print("\n=== Riemannian Optimization ===")
geoopt_optimization_example()参考文献
双曲埋め込みの基礎
- Nickel, M., & Kiela, D. (2017). Poincaré Embeddings for Learning Hierarchical Representations. NeurIPS 2017. arXiv: arXiv:1705.08039.
- 双曲空間への単語埋め込みを提案した先駆的論文。WordNetでの実験で有効性を実証。
- Nickel, M., & Kiela, D. (2018). Learning Continuous Hierarchies in the Lorentz Model of Hyperbolic Geometry. ICML 2018. arXiv: arXiv:1806.03417.
- 数値的に安定なローレンツモデルでの双曲埋め込み。
理論的背景
- Sarkar, R. (2011). Low Distortion Delaunay Embedding of Trees in Hyperbolic Plane. Graph Drawing 2011. DOI: 10.1007/978-3-642-25878-7_34.
- 木構造の双曲平面(2次元)への低歪み埋め込みを示した理論的研究。双曲空間が木構造に適している理論的根拠を与える。
- Krioukov, D., Papadopoulos, F., Kitsak, M., Vahdat, A., & Boguñá, M. (2010). Hyperbolic Geometry of Complex Networks. Physical Review E, 82(3), 036106. arXiv: arXiv:1006.5169.
- 複雑ネットワークと双曲幾何学の関係を解明した物理学的研究。
知識グラフと双曲空間
- Balažević, I., Allen, C., & Hospedales, T. (2019). Multi-relational Poincaré Graph Embeddings. NeurIPS 2019. arXiv: arXiv:1905.09791.
- 知識グラフの多関係埋め込みへの双曲空間の適用。
- Chami, I., Ying, Z., Ré, C., & Leskovec, J. (2019). Hyperbolic Graph Convolutional Neural Networks. NeurIPS 2019. arXiv: arXiv:1910.12933.
- グラフニューラルネットワークの双曲空間への拡張。
Mixed-Curvature Spaces
- Gu, A., Sala, F., Gunel, B., & Ré, C. (2019). Learning Mixed-Curvature Representations in Product Manifolds. ICLR 2019.
- 球面・双曲・ユークリッドの直積空間での表現学習。
- Bachmann, G., Bécigneul, G., & Ganea, O.-E. (2020). Constant Curvature Graph Convolutional Networks. ICML 2020. arXiv: arXiv:1911.05076.
- 曲率を学習可能にしたグラフネットワーク。
実装とライブラリ
- Kochurov, M., Karimov, R., & Kozlukov, S. (2020). Geoopt: Riemannian Optimization in PyTorch. arXiv: arXiv:2005.02819.
- PyTorchでのリーマン最適化ライブラリ。本講義のコード例でも使用。
- GitHub: https://github.com/geoopt/geoopt
双曲幾何学の教科書
- Cannon, J. W., Floyd, W. J., Kenyon, R., & Parry, W. R. (1997). Hyperbolic Geometry. Flavors of Geometry, MSRI Publications, Vol. 31, 59–115.
- 双曲幾何学の入門的な解説。ポアンカレ円板を含む複数のモデルを扱う。
- PDF: https://www.msri.org/publications/books/Book31/files/cannon.pdf