最適輸送解析ダッシュボード
Optimal Transport Analysis Dashboard

A状態→B状態→C状態 分岐パターン解析
State A → State B → State C Branching Pattern Analysis

📈 最適輸送問題の概要

📐 最適輸送問題の基本的な考え方

ある確率分布に従う質量(あるいは確率)を、別の確率分布に移動させるために必要なコストを最小化するような輸送方法を求める問題です。

🕰️ 最適輸送問題の歴史

1942年 カントロヴィッチ (Kantorovich): ソ連の数学者・経済学者レオニード・カントロヴィッチがモンジュの古典的輸送問題を線形計画法の枠組みで緩和・一般化し、「輸送計画(transport plan)」の概念を導入。
1975年 🏆 ノーベル経済学賞: カントロヴィッチは「資源配分理論への貢献」によりノーベル経済学賞を受賞しました。
1990年代 計算手法の進歩: 計算手法の進歩により、特にコンピュータビジョン領域で「Earth Mover's Distance(EMD)」として実装され、画像検索やテクスチャ解析への応用が始まりました。
2010年代以降 🚀 現代応用: 深層学習分野ではWasserstein GAN(WGAN, 2017)が提案されて生成モデルの安定化に貢献。生物学分野では単一細胞データの発生軌跡推定(Waddington-OT, 2019)など最先端応用が急速に拡大

🧮 最適輸送問題の数学的な基礎

🎯 最適輸送解析の核心的なポイント

「離散的なスナップショットデータから連続的な変化プロセスを推定できる」

実際には時系列ではないデータ(異なる状態の独立したサンプル)に対して、連続性を仮定することで、状態間の滑らかな遷移経路を数学的に復元できます。これにより、観測されていない「中間プロセス」を理論的に推定し、変化のメカニズムを解明できるのが最適輸送解析の革新的な価値です。

⚠️ 仮定と限界

🎬 状態遷移パターン

🎬 動的遷移アニメーション

最適輸送アニメーション

各データポイントが早期状態から中期状態、そして2つの後期状態への最適経路に沿って遷移する様子を示すアニメーション

🔧 アニメーション技術仕様

  • 解像度: 1920×1440ピクセル(高解像度)
  • フレーム数: 各状態15フレーム(滑らかな遷移)
  • 色分け: A(青) → B(緑) → C1(赤)/C2(オレンジ)
  • 透明度: 視認性を保つためのアルファ値調整
  • 軌跡表示: 各データポイントの個別移動経路
  • 統一軸範囲: 密度分布版と同じXY軸範囲で一貫した比較を可能に

📊 密度分布付きアニメーション

密度分布付き最適輸送アニメーション

状態の変化パターンを密度分布と等高線で可視化。データポイントの集中度と分散パターンが明確に表示されます

🎨 密度可視化の特徴

  • 密度等高線: 各状態の分布密度を等高線で表示
  • 固定密度閾値: アニメーション全体で一貫した密度レベル(0.1, 0.3, 0.5, 0.7, 0.9)を使用
  • コンパクトな密度分布: 小さく調整された密度分布でデータポイントの集中度を精密に表現
  • 統一軸範囲: 基本版と同じXY軸範囲(15%拡張)で直接比較を可能に
  • シンプルデザイン: 背景色を排除し、等高線のみで密度パターンを表現
  • 統計的解釈: 分布の形状変化から遷移パターンを定量化
  • クラスター分析: 状態Cでの2つの分岐パターンを明確に可視化

🎯 状態遷移の可視化

📊 状態遷移の模式図

A

初期状態

B

中間状態

C1

最終状態1

C2

最終状態2

🔍 遷移パターンの特徴

  • A → B: 単一方向への集約的遷移(30データポイント全てが同じ中間状態へ)
  • B → C1/C2: 分岐的遷移(中間状態から2つの異なる最終状態への分散)
  • 色分け: A(青) → B(緑) → C1(赤)/C2(オレンジ)で状態を明確に区別
  • 分岐比率: C1とC2への分岐は約50:50の比率で発生

📊 静的図表 (PNG)

State A->State B->State C Overview

State A→State B→State Cの全体的な分岐パターンを示す静的図表(Cluster: A1, B1, C1, C2)

➡️ A→B輸送可視化

📊 静的図表 (PNG)

State A->State B Transport Analysis

State AからState Bへの最適輸送パターンと矢印による移動経路の可視化

💻 A→B輸送の実行コード (R)

# A→B輸送解析のRコード (mvp_simple.Rより)

# PNG 2: A→B Transport using ggplot2
cat("Creating transport_ab.png with ggplot2...\n")

# Prepare A→B data
ab_data <- data.frame(
  PC1 = c(pca_A$data[,1], pca_B$data[,1]),
  PC2 = c(pca_A$data[,2], pca_B$data[,2]),
  State = factor(c(rep("State A", nrow(pca_A$data)), 
                   rep("State B", nrow(pca_B$data))), 
                 levels = c("State A", "State B"))
)

# Prepare ALL transport arrows (not sampled)
ab_arrows <- data.frame()
if(nrow(transport_AB$plan) > 0) {
  for (i in 1:nrow(transport_AB$plan)) {
    if (transport_AB$plan[i, 3] > 1e-6) {
      ab_arrows <- rbind(ab_arrows, data.frame(
        x = pca_A$data[transport_AB$plan[i, 1], 1],
        y = pca_A$data[transport_AB$plan[i, 1], 2],
        xend = pca_B$data[transport_AB$plan[i, 2], 1],
        yend = pca_B$data[transport_AB$plan[i, 2], 2],
        weight = transport_AB$plan[i, 3]
      ))
    }
  }
}

p2 <- ggplot(ab_data, aes(x = PC1, y = PC2)) +
  geom_segment(data = ab_arrows, aes(x = x, y = y, xend = xend, yend = yend),
               arrow = arrow(length = unit(0.15, "cm")), 
               color = "gray40", linewidth = 0.5, alpha = 0.4) +
  geom_point(aes(color = State), size = 3, shape = 16, alpha = 0.8) +
  scale_color_manual(values = c("State A" = "blue", "State B" = "darkgreen")) +
  labs(title = "State A->State B Transport Analysis\n(Horizontal Movement Pattern)",
       x = "PC1", y = "PC2") +
  annotate("text", x = min(ab_data$PC1), y = max(ab_data$PC2), 
           label = paste("Wasserstein Cost:", round(transport_AB$cost, 4)), 
           hjust = 0, vjust = 1, size = 4, fontface = "bold", color = "darkblue") +
  theme_minimal() +
  theme(
    plot.title = element_text(size = 16, hjust = 0.5, face = "bold"),
    axis.title = element_text(size = 12),
    legend.position = "right",
    legend.title = element_text(size = 11),
    legend.text = element_text(size = 10),
    panel.grid.minor = element_blank()
  ) +
  guides(color = guide_legend(title = "State", override.aes = list(size = 4)))

ggsave("transport_ab.png", plot = p2, width = 10, height = 8, dpi = 150, bg = "white")
cat("✅ Generated: transport_ab.png with ggplot2 (all arrows displayed)\n")

🌿 B→C輸送可視化

📊 静的図表 (PNG)

State B->State C Transport Analysis

State BからState Cへの分岐輸送パターンと色分けされた矢印による移動経路の可視化

💻 B→C輸送の実行コード (R)

# B→C輸送解析のRコード (mvp_simple.Rより)

# PNG 3: B→C Transport using ggplot2
cat("Creating transport_bc.png with ggplot2...\n")

# Create BC_data with cluster information
BC_data <- data.frame(
  PC1 = c(pca_B$data[,1], pca_C$data[,1]),
  PC2 = c(pca_B$data[,2], pca_C$data[,2]),
  State = factor(c(rep("State B", nrow(pca_B$data)), 
                   rep("State C", nrow(pca_C$data))), 
                 levels = c("State B", "State C")),
  Cluster = c(rep("B", nrow(pca_B$data)), 
              rep(paste0("C", pca_C$cluster), nrow(pca_C$data)))
)

# Prepare ALL transport arrows for B→C
bc_arrows <- data.frame()
if(nrow(transport_BC$plan) > 0) {
  for (i in 1:nrow(transport_BC$plan)) {
    if (transport_BC$plan[i, 3] > 1e-6) {
      target_cluster <- pca_C$cluster[transport_BC$plan[i, 2]]
      bc_arrows <- rbind(bc_arrows, data.frame(
        x = pca_B$data[transport_BC$plan[i, 1], 1],
        y = pca_B$data[transport_BC$plan[i, 1], 2],
        xend = pca_C$data[transport_BC$plan[i, 2], 1],
        yend = pca_C$data[transport_BC$plan[i, 2], 2],
        weight = transport_BC$plan[i, 3],
        target_cluster = paste0("C", target_cluster)
      ))
    }
  }
}

p3 <- ggplot(BC_data, aes(x = PC1, y = PC2)) +
  geom_segment(data = bc_arrows, aes(x = x, y = y, xend = xend, yend = yend, color = target_cluster),
               arrow = arrow(length = unit(0.15, "cm")), 
               linewidth = 0.6, alpha = 0.7) +
  geom_point(aes(color = Cluster, shape = State), size = 3, alpha = 0.9) +
  scale_color_manual(values = c("B" = "darkgreen", "C1" = "red", "C2" = "orange")) +
  scale_shape_manual(values = c("State B" = 16, "State C" = 17)) +
  labs(title = "State B->State C Transport Analysis\n(Branching to Two Clusters)",
       x = "PC1", y = "PC2") +
  annotate("text", x = min(BC_data$PC1), y = max(BC_data$PC2), 
           label = paste("Wasserstein Cost:", round(transport_BC$cost, 4)), 
           hjust = 0, vjust = 1, size = 4, fontface = "bold", color = "darkred") +
  theme_minimal() +
  theme(
    plot.title = element_text(size = 16, hjust = 0.5, face = "bold"),
    axis.title = element_text(size = 12),
    legend.position = "right",
    legend.title = element_text(size = 11),
    legend.text = element_text(size = 10),
    panel.grid.minor = element_blank()
  ) +
  guides(
    color = guide_legend(title = "Cluster", override.aes = list(size = 4)),
    shape = guide_legend(title = "State", override.aes = list(size = 4))
  )

ggsave("transport_bc.png", plot = p3, width = 10, height = 8, dpi = 150, bg = "white")
cat("✅ Generated: transport_bc.png with ggplot2 (branching transport displayed)\n")

📋 データ詳細

基本統計

指標説明
データポイント数30 per state各状態のサンプルサイズ
PC1分散寄与率84%第1主成分の説明力
PC2分散寄与率14%第2主成分の説明力
クラスター分離3.4 unitsC1とC2クラスター中心間の距離

最適輸送解析結果

輸送パスワッサースタイン距離輸送接続数解釈
A→B輸送1.751230水平移動の最適輸送コスト
B→C輸送2.098530分岐輸送の最適コスト
総輸送コスト3.849760A→B→C全体の輸送コスト
分岐コスト増加0.3473-B→C分岐による追加コスト

分岐パターン詳細

分岐先データポイント数分岐比率平均座標 (PC1, PC2)
クラスターC11550.0%(8.2, 3.5)
クラスターC21550.0%(8.1, 0.6)
クラスター間距離--3.4 units
分岐角度--約90°(垂直分岐)

最適輸送コスト詳細解説

🔄 水平移動の最適輸送コスト (A→B: 1.7512)

概念: 状態Aから状態Bへの単純な水平移動に必要な最小エネルギー

  • 移動パターン: 30個のデータポイントが全て同じ方向(水平右方向)に移動
  • 移動距離: PC1軸で約3単位の均等移動(x: 2 → 5)
  • 分散変化: 移動中も分散構造が保持される(構造保存性)
  • 生物学的解釈: 一様な環境変化に対する集団全体の適応反応

わかりやすく言うと:30人の集団が全員同じ方向に3歩分移動する時の「疲労度」の総計

🌿 分岐輸送の最適コスト (B→C: 2.0985)

概念: 中間状態から2つの異なる最終状態への分岐移動に必要な最小エネルギー

  • 分岐パターン: 30個のデータポイントが2つのグループ(C1: 15個、C2: 15個)に分散
  • 移動距離: PC1軸で約3単位 + PC2軸で上下に約1.5単位ずつ分岐
  • 複雑性増加: 水平移動より複雑な軌道のため高いコスト
  • 生物学的解釈: 環境圧力により集団が2つの適応戦略に分化

わかりやすく言うと:30人の集団が道の分岐点で半分ずつ異なる方向に進む時の「移動エネルギー」の総計

🔗 A→B→C全体の輸送コスト (3.8497)

概念: 初期状態から最終状態までの完全な遷移プロセスに必要な総エネルギー

  • 計算式: A→Bコスト (1.7512) + B→Cコスト (2.0985) = 3.8497
  • プロセス全体: 水平移動 → 分岐移動の2段階遷移
  • 累積効果: 各段階のコストが積算された総変化量
  • 生物学的解釈: 初期適応から最終分化までの全エネルギー消費

わかりやすく言うと:30人の集団が出発地から最終目的地まで移動する「総旅行コスト」

➕ B→C分岐による追加コスト (0.3473)

概念: 単純な水平移動と比較した場合の分岐移動による追加エネルギー

  • 計算式: B→Cコスト (2.0985) - A→Bコスト (1.7512) = 0.3473
  • 分岐ペナルティ: 集団が分散することによる追加的な移動コスト
  • 複雑性指標: 単純移動に対する分岐移動の複雑さを数値化
  • 生物学的解釈: 集団分化に伴う追加的な適応コスト

わかりやすく言うと:集団が「一緒に移動」ではなく「別々の道に分かれる」ことで生じる「追加の手間」

📊 コスト比較の重要性

比較項目解釈
分岐コスト / 水平コスト1.20倍分岐移動は水平移動より20%困難
追加コスト / 全体コスト9.0%全体の9%が分岐による追加負担
効率性指標91.0%分岐しても比較的効率的な遷移

📚 リファレンス

📖 主要参考文献・グラフィカルアブストラクト

🧬 単一細胞解析における最適輸送

Geoffrey Schiebinger et al.

"Optimal-Transport Analysis of Single-Cell Gene Expression Identifies Developmental Trajectories in Reprogramming"

Cell, Volume 176, Issue 6, 7 March 2019, Pages 1517

🌟 本研究への影響

この研究は単一細胞遺伝子発現データに最適輸送理論を適用し、細胞の発生軌跡を推定する手法を確立しました。本解析では、この手法を状態データに応用し、状態遷移パターンの解明を行っています。

🎨 グラフィカルアブストラクト

Cell 2019 Graphical Abstract
📊 図の説明

最適輸送理論を用いた単一細胞データの軌跡推定手法の概念図。異なる時点のデータから連続的な発生プロセスを復元し、細胞分化の経路を明らかにする革新的なアプローチを示しています。