学習コースLearn

ネットワーク分析

人・モノ・要素の「つながり」をグラフとして表し、その構造や重要な要素を定量的に読み解く技術を、概要から理論、そして実際に動かせるコードまで、順を追って学ぶモジュールです。各ステップは「概要 → 仕組み(座学)→ コードで動かす」の3層で進みます。ページ内には手を動かせるデモを3つ用意しました。

この教材は日本語のみで提供していますThis learning material is available in Japanese only.

はじめにIntroduction

このモジュールの全体像

ネットワーク分析(network analysis)とは、要素どうしの「つながり」をグラフ(graph)として表し、その構造や、どの要素が重要かを定量的に読み解く技術です。友人関係のような社会ネットワーク、論文の引用、Web のリンク、ソフトウェアの依存関係、道路や鉄道の交通網まで、世の中の多くのものは「つながりの網」として捉えられます。

ネットワーク分析では、要素をノード(頂点)、つながりをエッジ(辺)として表します。この単純な枠組みに、次のような流れ(パイプライン)で数値的な道具を当てていきます。データからグラフを組み立て、指標を計算し、可視化して解釈します。

ネットワーク分析の基本パイプライン

データ Data グラフ構築 Build graph 指標計算 Metrics 可視化・解釈 Interpret ノード・エッジで表現 次数・中心性・経路 コミュニティ・構造

ノードとエッジ

ノード / node エッジ / edge

ネットワークはノード(頂点)と、それらをつなぐエッジ(辺)で表します。この「つながりの構造」そのものを数値で読み解くのがネットワーク分析です。

このモジュールは、上のパイプラインを左から順にたどります。各ステップは次の3層で構成します。

  • 概要:その技術が何のためにあるのか、あらましをつかむ。
  • 仕組み(座学):背後にある理論・定義・式を、ていねいに理解する。
  • コードで動かす:Python の定番ライブラリ NetworkX や、ページ内デモで実際に動かして確かめる。

手を動かす題材には、実在の公開データセット(Zachary の空手クラブ、Les Misérables の共起ネットワークなど)や、ページ内の小さなサンプルグラフだけを使います。特別な環境がなくても、読みながら試せる構成です。

1

ネットワーク分析とは

What is network analysis

概要Overview

ネットワーク分析は「関係」を主役に据える見方です。個々の要素の性質だけでなく、要素どうしがどうつながっているかに注目します。同じデータでも、表の1行ずつを別々に見るのと、行と行の関係を網として見るのとでは、見えてくるものが違います。ネットワークはあらゆる場所に現れます。

  • 社会ネットワーク:人を点、友人関係やフォロー関係を線とする。
  • 引用・参照:論文を点、引用を線とする。Web ページとリンクも同じ形。
  • 依存関係:ソフトウェアのモジュールやパッケージを点、依存を線とする。
  • 協働:開発者を点、同じファイルを一緒に触った関係を線とする。
  • インフラ:駅や交差点を点、路線や道路を線とする。

仕組みHow it works

ノードとエッジという共通の言葉で表すと、分野が違っても同じ道具で分析できるのがネットワーク分析の強みです。このモジュールでは、次のような問いに答える道具を順に手に入れます。

  • どのノードが重要か:つながりの多さや、橋渡しの役割を数値で測る(中心性)。
  • まとまりはあるか:密につながった集団(コミュニティ)を見つける。
  • どれくらい近いか:ノード間の最短経路や、ネットワーク全体の広がりを測る。
  • 全体はどんな形か:スモールワールド性やスケールフリー性といった、大きな構造の特徴を捉える。

これらはすべて、グラフという同じ土台の上で計算できます。まずは、その土台となるグラフの基礎から始めましょう。

この Step のまとめ

ネットワーク分析は「関係」を主役にする見方。要素をノード、つながりをエッジとして表すと、社会・引用・依存・交通など分野をまたいで同じ道具が使えます。「重要なノード・まとまり・近さ・全体の形」を数値で読み解いていきます。

2

グラフの基礎

Graph basics

概要Overview

グラフは、ノードの集合とエッジの集合の組です。とても単純ですが、表し方にいくつかの選択肢があり、そこから分析の第一歩となる基本的な指標が決まります。まずは用語と、もっとも基本的な量である「次数」をおさえます。

仕組みHow it works

有向グラフと無向グラフ

エッジに向きがないものを無向グラフと呼びます。友人関係のように「たがいに」つながる関係です。いっぽう、向きがあるものを有向グラフと呼びます。フォロー関係や引用のように「AからBへ」という一方向の関係です。エッジに数値(距離・重み・回数など)を付けたものは重み付きグラフです。

隣接行列と隣接リスト

グラフをコンピュータで表す代表的な方法が2つあります。隣接行列は、ノード数を n として n×n の表を作り、ノード i とノード j がつながっていれば 1(重み付きなら重み)を書きます。隣接リストは、各ノードについて「つながっている相手の一覧」を持ちます。エッジが少ない(疎な)グラフでは、隣接リストのほうが省メモリで効率的です。

次数(degree)

あるノードにつながっているエッジの本数を次数と呼びます。無向グラフでは単に本数ですが、有向グラフでは、入ってくるエッジの数を入次数(in-degree)、出ていくエッジの数を出次数(out-degree)と区別します。次数は「そのノードが何本の線を持つか」という、もっとも素朴な重要度の目安になります。

密度(density)

ネットワーク全体が「どれくらい密につながっているか」を表すのが密度です。実際にあるエッジ数を、あり得る最大のエッジ数で割った値で、0(線がまったくない)から 1(すべてのノードが互いにつながる完全グラフ)までの範囲を取ります。無向グラフでは次の式です。

density = 2m / ( n ( n - 1 ) ) m: エッジ数 n: ノード数(無向グラフの場合)
あり得る最大エッジ数 n(n-1)/2 のうち、実際に何本あるかの割合です。
デモ 1Demo 1

グラフと次数

プリセットのグラフを表示します。ノードをクリックすると、そのノードにつながるエッジ(次数)と隣接ノードを強調し、次数中心性を計算します。上のボタンでグラフを切り替えられます。もう一度クリックすると選択が解除されます。

グラフ

コードで動かすRun the code

Python では NetworkX が定番です。ノードとエッジを足していくだけでグラフができ、次数や密度もすぐに取れます。デモと同じ7ノードのグラフ(A から G)を作ってみましょう。

Pythonbuild_graph.py
import networkx as nx

G = nx.Graph()
for u, v in [("A", "B"), ("A", "C"), ("B", "C"), ("C", "D"),
             ("D", "E"), ("D", "F"), ("E", "F"), ("F", "G")]:
    G.add_edge(u, v)

print(G.number_of_nodes(), G.number_of_edges())
print(dict(G.degree()))
print(round(nx.density(G), 3))
出力例 / Output
7 8
{'A': 2, 'B': 2, 'C': 3, 'D': 3, 'E': 2, 'F': 3, 'G': 1}
0.381

有向グラフでは DiGraph を使い、入次数と出次数を区別できます。

Pythondirected.py
# 有向グラフでは入次数と出次数を区別する
D = nx.DiGraph()
D.add_edges_from([("A", "B"), ("B", "C"), ("A", "C")])
print(dict(D.in_degree()))
print(dict(D.out_degree()))
出力例 / Output
{'A': 0, 'B': 1, 'C': 2}
{'A': 2, 'B': 1, 'C': 0}

この Step のまとめ

グラフはノードとエッジの組。有向/無向・重みの有無で表し方が変わり、隣接行列や隣接リストで保持します。もっとも基本の量が次数で、そこから全体の密度もわかります。次はこの上で「どのノードが重要か」を測ります。

3

重要なノードを測る(中心性)

Centrality

概要Overview

ネットワークで「どのノードが重要か」を数値化するのが中心性(centrality)です。ただし「重要」の意味は一通りではありません。つながりの多さが大事な場面もあれば、集団と集団の橋渡しをする役割が大事な場面もあります。目的に応じて指標を使い分けます。代表的な4つを見ていきましょう。

仕組みHow it works

次数中心性(degree centrality)

もっとも単純で、つながっている相手の多さをそのまま重要度とします。比較しやすいよう、次数を「あり得る最大の次数 n-1」で割って 0 から 1 に正規化します。SNS でフォロワーが多い人、といったイメージです。

CD(v) = deg(v) / ( n - 1 ) deg(v): ノード v の次数 n: ノード数

媒介中心性(betweenness centrality)

ノードがどれだけ「橋渡し」をしているかを測ります。すべてのノード対の最短経路を考え、そのうち何割が自分を通るかを合計します。集団と集団をつなぐ位置にあるノードは、次数が少なくても媒介中心性が高くなります。情報や物の流れの「関所」にあたる重要な役割です。

CB(v) = Σs≠v≠t σst(v) / σst σst: ノード s と t の間の最短経路の数 σst(v): そのうち v を通る本数

近接中心性(closeness centrality)

あるノードから他のすべてのノードへ、どれだけ近いかを測ります。最短距離の合計が小さいほど、ネットワークの「中心」に近いと考えます。全体へ素早く到達できる位置にあるノードほど高くなります。

CC(v) = ( n - 1 ) / Σu d(v, u) d(v, u): ノード v から u への最短距離 合計は v 以外のすべての u について取る

固有ベクトル中心性と PageRank

「重要なノードにつながっているノードは重要」という再帰的な考え方が固有ベクトル中心性です。つながりの数だけでなく、つながる相手の重要度まで考慮します。これを有向グラフ(Web のリンクなど)向けに改良し、実用的にしたのが PageRank です。Google の初期の検索順位づけで有名になりました。多くの重要なページからリンクされるページほど、高いスコアになります。

これらの指標は、同じグラフでも「誰が重要か」の答えが変わります。次のデモで、指標を切り替えながらその違いを体感してみましょう。

デモ 2Demo 2

中心性ランキング

Step 2 と同じ交友グラフ(7ノード)に対して、指標を選ぶと各ノードの中心性スコアを計算し、高い順にランキングします。グラフ上のノードは、色が濃いほどスコアが高いことを表します。指標によって「重要なノード」が入れ替わることに注目してください。

指標

コードで動かすRun the code

NetworkX には主要な中心性がひととおり用意されています。同じグラフに対して4つの指標を計算し、見やすいよう小数第3位で丸めて表示します。

Pythoncentrality.py
import networkx as nx

G = nx.Graph()
G.add_edges_from([("A", "B"), ("A", "C"), ("B", "C"), ("C", "D"),
                  ("D", "E"), ("D", "F"), ("E", "F"), ("F", "G")])

def show(d):
    return {k: round(v, 3) for k, v in d.items()}

print(show(nx.degree_centrality(G)))
print(show(nx.betweenness_centrality(G)))
print(show(nx.closeness_centrality(G)))
print(show(nx.pagerank(G)))
出力例 / Output
{'A': 0.333, 'B': 0.333, 'C': 0.5, 'D': 0.5, 'E': 0.333, 'F': 0.5, 'G': 0.167}
{'A': 0.0, 'B': 0.0, 'C': 0.533, 'D': 0.6, 'E': 0.0, 'F': 0.333, 'G': 0.0}
{'A': 0.429, 'B': 0.429, 'C': 0.6, 'D': 0.667, 'E': 0.5, 'F': 0.545, 'G': 0.375}
{'A': 0.125, 'B': 0.125, 'C': 0.179, 'D': 0.179, 'E': 0.126, 'F': 0.19, 'G': 0.075}

※ NetworkX の betweenness_centrality は既定で正規化され、上の式の合計に 2/((n−1)(n−2)) を掛けた値を返します(n はノード数。この例では n=7 なので D の 9 本 × 2/30 = 0.6)。

結果を見比べると面白いことがわかります。次数では C・D・F が同点ですが、媒介中心性では D が最大(左右の集団をつなぐ橋渡し)、近接中心性でも D が最大(全体の中心)です。いっぽう PageRank では、末端の G から流れ込むぶんだけ F が少し高くなります。「重要さ」は測り方しだいなのです。

この Step のまとめ

中心性は「重要なノード」を数値化する道具。次数は多さ、媒介は橋渡し、近接は全体への近さ、PageRank は重要な相手からのつながりを重く見ます。目的に合った指標を選ぶことが肝心です。

4

まとまりを見つける(コミュニティ検出)

Community detection

概要Overview

大きなネットワークには、内部が密につながった集団がしばしば潜んでいます。友人グループ、研究分野、機能ごとのモジュール群などです。こうしたまとまりを見つけ出すのがコミュニティ検出(community detection)です。全体をいくつかのグループに分け、構造を理解しやすくします。

仕組みHow it works

連結成分

もっとも素朴なまとまりが連結成分(connected component)です。エッジをたどって互いに行き来できるノードの集まりで、グラフが「いくつの島に分かれているか」を表します。まず全体がひとつながりかどうかを確かめるのが出発点です。

モジュラリティ

連結成分よりも細かく「密なまとまり」を見つけるには、分割の良さを測るものさしが要ります。定番がモジュラリティ(modularity)です。コミュニティの内部にエッジが多く、コミュニティ間のエッジが少ないほど値が大きくなります。よい分割ほどモジュラリティが高い、という考え方です。

Q = Σc ( ecc - ac2 ) ecc: コミュニティ c の内部にあるエッジの割合 ac: c につながるエッジ端の割合
実際の内部エッジが、ランダムな場合の期待値をどれだけ上回るかを足し合わせます。

コミュニティ検出の手法

モジュラリティを手がかりに分割を探す代表的な手法があります。ガーバン・ニューマン法は、橋渡しをするエッジ(媒介の高いエッジ)を少しずつ取り除いてコミュニティを浮かび上がらせます。Louvain 法は、モジュラリティが上がるようにノードをまとめていく高速な手法で、大規模なネットワークでもよく使われます。NetworkX の greedy_modularity_communities は、モジュラリティを貪欲に最大化する手法です。

クラスタリング係数

「友達の友達は友達か」という、まとまりやすさの局所的な指標がクラスタリング係数です。あるノードの隣どうしが、実際にどれだけ互いにつながっているかの割合で、社会ネットワークでは高くなりがちです。ネットワーク全体で平均したものを平均クラスタリング係数と呼びます。

コードで動かすRun the code

まず、島が2つに分かれた小さなグラフで連結成分を確かめます。

Pythoncomponents.py
import networkx as nx

H = nx.Graph()
H.add_edges_from([("A", "B"), ("B", "C"), ("D", "E")])
print(nx.number_connected_components(H))
print([sorted(c) for c in nx.connected_components(H)])
出力例 / Output
2
[['A', 'B', 'C'], ['D', 'E']]

次に、実在の公開データ Zachary の空手クラブ(34人の会員と、その交友関係からなる有名なネットワーク)で、コミュニティ検出とクラスタリング係数を試します。NetworkX に内蔵されているので、ダウンロード不要です。

Pythoncommunities.py
G = nx.karate_club_graph()          # 実在の空手クラブ・ネットワーク
print(nx.number_connected_components(G))   # 全体はひとつながり

comms = nx.community.greedy_modularity_communities(G)
print(len(comms))                          # 見つかったコミュニティ数
print(round(nx.community.modularity(G, comms), 4))
print(round(nx.average_clustering(G), 4))
出力例 / Output
1
3
0.411
0.5706

※ モジュラリティの値は NetworkX のバージョンによって変わります(上は NetworkX 3.6 で実行した結果。古い 2.x 系では約 0.38 になります)。

34人のネットワークが3つのコミュニティに分かれ、その分割のモジュラリティは約 0.41、平均クラスタリング係数は約 0.57 でした。空手クラブは実際に2つの派閥に分裂した歴史があり、こうした構造がデータからも読み取れます。

この Step のまとめ

コミュニティ検出は「密なまとまり」を見つける道具。連結成分でまず島の数を数え、モジュラリティを手がかりに Louvain 法などで細かく分割します。クラスタリング係数は「友達の友達は友達か」という局所的なまとまりやすさを表します。

5

経路と全体の構造

Paths & structure

概要Overview

ネットワークの「近さ」や「広がり」は、ノードからノードへたどる経路で測ります。とくに大切なのが、あいだのエッジ数が最小の最短経路です。最短経路がわかると、ネットワーク全体がどれくらいコンパクトか、どんな大きな構造を持つかまで見えてきます。

仕組みHow it works

最短経路(BFS とダイクストラ)

重みのないグラフでは、幅優先探索(BFS: breadth-first search)で最短経路を求められます。始点から近い順に、波が広がるようにノードを訪れていくので、初めて終点に届いたときの経路が最短です。エッジに重み(距離など)があるグラフでは、ダイクストラ法を使います。次のデモは BFS で、始点から終点までの最短経路をたどります。

直径と平均経路長

すべてのノード対について最短距離を求めると、ネットワーク全体の広がりがわかります。最短距離の最大値を直径(diameter)、平均を平均経路長と呼びます。直径が小さいほど、ネットワークは「どこからどこへも近い」コンパクトな形です。

スモールワールドとスケールフリー

現実の多くのネットワークには、共通する2つの性質が見られます。ひとつはスモールワールド性で、巨大なネットワークでも、ごく少ないステップで任意の2ノードがつながります。「六次の隔たり」で知られる性質です。もうひとつはスケールフリー性で、次数の分布がべき則(power law)に従い、ごく一部の「ハブ」が飛び抜けて多くのつながりを持ちます。SNS や Web、引用ネットワークなどで観察されます。

デモ 3Demo 3

最短経路(BFS)

Step 2 と同じ交友グラフで、始点と終点を選ぶと、BFS(幅優先探索)で最短経路を求め、グラフ上に太い線で示します。始点と終点は濃い緑、経路上のノードは薄い緑で表示します。経路の長さ(エッジの数)が最短距離です。

コードで動かすRun the code

NetworkX なら、最短経路も全体の構造も一行ずつで求まります。デモと同じグラフで確かめましょう。

Pythonpaths.py
import networkx as nx

G = nx.Graph()
G.add_edges_from([("A", "B"), ("A", "C"), ("B", "C"), ("C", "D"),
                  ("D", "E"), ("D", "F"), ("E", "F"), ("F", "G")])

print(nx.shortest_path(G, "A", "G"))
print(nx.shortest_path_length(G, "A", "G"))
print(nx.diameter(G))
print(round(nx.average_shortest_path_length(G), 3))
出力例 / Output
['A', 'C', 'D', 'F', 'G']
4
4
2.048

A から G への最短経路は A → C → D → F → G の4ステップ、ネットワークの直径も4、平均経路長は約2.05でした。橋渡しの役割を担う C と D を必ず通っていることに注目してください。Step 3 で C と D の媒介中心性が高かったのは、まさにこのためです。

この Step のまとめ

ネットワークの「近さ」は最短経路で測り、重みがなければ BFS で求まります。全体の広がりは直径や平均経路長で表します。現実のネットワークには、少ないステップでつながるスモールワールド性と、一部のハブが偏って多くつながるスケールフリー性がよく見られます。

6

可視化とこれから

Visualization & what is next

概要Overview

数値だけでなく、ネットワークは絵にすると理解が一気に進みます。ただし、ノードをどこに置くかで見え方が大きく変わります。よい配置(レイアウト)と、大規模なネットワークをどう扱うかが、可視化の鍵になります。

仕組みHow it works

レイアウト

グラフ描画で広く使われるのが力学モデル(force-directed layout)です。エッジをばね、ノードどうしを反発する電荷に見立て、力がつり合う位置へノードを配置します。密につながったノードは近くに、そうでないノードは遠くに集まるので、コミュニティ構造が自然と見えてきます。

大規模ネットワークと動的ネットワーク

ノードが数万・数百万になると、すべてを描くと「毛玉」のようになり、かえって読み取れません。重要な部分だけを抜き出す、集約する、対話的に拡大縮小するといった工夫が要ります。専用ツールの Gephi や、Python の igraph・graph-tool は大きなグラフに向いています。また、つながりが時間とともに変わる動的ネットワークを扱う研究も進んでいます。

描画のコード

小さなグラフなら、NetworkX と matplotlib で手軽に描けます。レイアウトを計算し、ノード・エッジ・ラベルを重ねて描画します。

Pythondraw_graph.py
import networkx as nx
import matplotlib.pyplot as plt

G = nx.karate_club_graph()
pos = nx.spring_layout(G, seed=42)     # 力学モデル(force-directed)で配置
nx.draw_networkx_nodes(G, pos, node_size=300)
nx.draw_networkx_edges(G, pos, alpha=0.4)
nx.draw_networkx_labels(G, pos, font_size=8)
plt.axis("off")
plt.savefig("karate.png", dpi=150)

この Step のまとめ

可視化はレイアウトしだいで見え方が変わり、力学モデルはコミュニティ構造を自然に浮かび上がらせます。大規模・動的なネットワークには専用の道具と工夫が必要です。ここまでの「グラフ構築 → 指標 → まとまり → 経路 → 可視化」が、ネットワーク分析の基本の一巡です。

まとめWrap-up

学びの振り返りと、さらに学ぶために

このモジュールでは、つながりを読み解く基本の道具を、パイプラインに沿って順に手に入れました。

  • グラフの基礎:ノードとエッジ、有向/無向・重み、次数と密度。
  • 中心性:次数・媒介・近接・PageRank で「重要なノード」を測る。
  • コミュニティ検出:連結成分とモジュラリティで「密なまとまり」を見つける。
  • 経路と構造:BFS で最短経路を求め、直径や平均経路長で全体の広がりを測る。
  • 可視化:力学モデルで構造を絵にし、大規模・動的なネットワークへ広げる。

次に進むなら、下の道具と資料が役に立ちます。

公開データセット

  • Zachary の空手クラブ:34人の交友ネットワーク。nx.karate_club_graph() で内蔵。
  • Les Misérables 共起ネットワーク:小説の登場人物の共起関係。ネットワーク可視化の定番。
  • SNAP:スタンフォード大学が公開する大規模グラフ集(SNS・道路・引用など)。

ライブラリ

  • NetworkX:Python の定番。学習・中小規模に最適。
  • igraph:C 実装で高速、Python から使える。
  • graph-tool:大規模グラフ向けの高速ライブラリ。
  • Gephi:対話的なネットワーク可視化ツール。

参考書

  • Mark Newman『Networks』(Oxford University Press)
  • Albert-László Barabási『Network Science』(邦訳『ネットワーク科学』)
  • Easley, Kleinberg『Networks, Crowds, and Markets』

次のモジュールへ

おつかれさまでした

ここで学んだ「グラフにする → 指標で測る → まとまりや経路を読む」という流れは、関係を持つあらゆるデータに共通する考え方です。3つのデモのノードやグラフを切り替えたり、始点・終点を変えたりして、値がどう変わるかを確かめてみてください。指標ごとに「重要なノード」が入れ替わる感覚がつかめると、理解がぐっと深まります。

発展トピックBeyond this module

このコースでは扱わない、関係する発展トピック

このモジュールでは、グラフを組み立て、指標で測り、構造を読み解く「基礎の流れ」を扱いました。いっぽうで近年のネットワーク分析は、機械学習や深層学習と結びつき、急速に広がっています。ここでは、このコースでは踏み込まないものの、知っておくと視野が広がる発展的なトピックを、特に近年の主流を中心に紹介します。深掘りは各自の興味に合わせてどうぞ。グラフニューラルネットワーク(GNN)はこのコースの範囲外の発展トピックで、深層学習のモジュールでも名前を挙げるにとどめています。

グラフの表現学習

  • グラフ埋め込み:ノードを密なベクトルに変換し、機械学習に使えるようにする手法(node2vec・DeepWalk)。ランダムウォークと word2vec の考え方を組み合わせます。
  • スペクトラルクラスタリング:グラフのラプラシアン行列の固有ベクトルを使って分割する、数理的なコミュニティ検出。

グラフニューラルネットワーク

  • GNN:隣接ノードの情報を集約しながら学習する深層モデル(GCN・GraphSAGE・GAT)。ノード分類やグラフ分類に強力。このコースの範囲外(発展トピック)。
  • メッセージパッシング:GNN に共通する、近傍から情報を伝え合う枠組み。

予測と動的ネットワーク

  • リンク予測:まだ存在しないつながりを予測する(友人推薦・共著予測など)。
  • 動的・時系列ネットワーク:時間とともに変化するつながりをモデル化し、成長や消滅を捉える。

大規模グラフと拡散

  • 大規模グラフ処理:数億ノード規模を扱う分散処理や近似アルゴリズム(graph-tool・分散グラフ基盤)。
  • 拡散・伝播:情報や感染がネットワーク上をどう広がるかのモデル(感染症モデル・影響最大化)。