🎓 レベル:標準 | 重要度:A(必須)
📎 前提:特殊なグラフ | 関連:推薦システムとネットワーク・リンク予測
要点(BLUF)
- 二部ネットワーク:ノードが2種類(ユーザーとアイテム、著者と論文)に分かれ、エッジは必ず異種間を結ぶ。
- 射影(projection):片側のノードだけのグラフに変換する。「共通の相手を持つ」ノードどうしを結び、重みは共通数。
- 協調フィルタリング・共著ネットワーク・推薦の構造的な土台。射影は情報を失うので、元の二部構造を保つのが原則。
概念:2種類のノードからなるネットワーク
ユーザーと商品、著者と論文、俳優と映画 — 多くの現実データは2種類の対象の関係です。ユーザーは商品に「買う」で繋がり、ユーザー同士・商品同士は直接繋がらない。これが二部ネットワーク(特殊なグラフ の二部グラフ)。推薦システム(推薦システムとネットワーク)はこの構造の上に立っています。
数式:二部構造と射影
二部ネットワークはノード集合が ()に分かれ、すべてのエッジが と をまたぎます。バイアジャセンシ行列 (、 ならユーザー がアイテム に接続)で表せます。
片側射影は、共通の相手を持つ同種ノードを結びます。ユーザー側射影の隣接行列は
は「ユーザー が共通して接続するアイテム数」。これを重みとしたユーザー同士のグラフが得られます。アイテム側射影は 。
コードで確認
import networkx as nx
from networkx.algorithms import bipartite
B = nx.Graph()
users = ['u1','u2','u3']; items = ['a','b','c']
B.add_nodes_from(users, bipartite=0)
B.add_nodes_from(items, bipartite=1)
B.add_edges_from([('u1','a'),('u1','b'),('u2','b'),('u2','c'),('u3','a'),('u3','c')])
print("二部か:", nx.is_bipartite(B))
# ユーザー側射影(重み = 共通アイテム数)
Pu = bipartite.weighted_projected_graph(B, users)
print("ユーザー射影:", [(u,v,d['weight']) for u,v,d in Pu.edges(data=True)])
# アイテム側射影(重み = 共通ユーザー数)
Pi = bipartite.weighted_projected_graph(B, items)
print("アイテム射影:", [(u,v,d['weight']) for u,v,d in Pi.edges(data=True)])
実行結果:
二部か: True
ユーザー射影: [('u1', 'u2', 1), ('u1', 'u3', 1), ('u2', 'u3', 1)]
アイテム射影: [('a', 'b', 1), ('a', 'c', 1), ('b', 'c', 1)]
u1とu2はアイテムbを共有するので重み1のエッジで結ばれます。アイテム側では、aとbを両方買ったユーザー(u1)がいるのでa-bが重み1で結ばれる。**「同じ商品を買った人は似ている」「一緒に買われる商品は関連する」**という協調フィルタリングの発想が、まさに射影として現れています。
二部構造と射影の図解
graph TD
subgraph 二部ネットワーク
u1((u1)) --- a(("a"))
u1 --- b(("b"))
u2((u2)) --- b
u2 --- c(("c"))
u3((u3)) --- a
u3 --- c
end
数式の直観的意味
射影 は「共通の相手を何人/何個共有するか」という類似度行列です。これは推薦の核心 — 「あなたと似た購買履歴の人が買った物を薦める(ユーザーベース)」「この商品とよく一緒に買われる物を薦める(アイテムベース)」がそれぞれユーザー射影・アイテム射影に対応します。ただし射影には代償があります。元の二部ネットワークから射影を作ると、どのアイテムを介して繋がったかの情報が潰れ、しかもエッジ数が大きく膨らむ(人気アイテムが多数のユーザーを互いに結ぶ)。だから現代の推薦は射影せず、二部構造のまま行列分解やグラフ手法で扱うのが主流です。リンク予測(リンク予測)も二部グラフ上で「将来どのエッジが現れるか」を問います。
⚠️ よくある誤解・落とし穴
- 射影は情報を失う:二部 → 片側で「介在する相手」が消える。可能なら元の二部構造を保つこと。
- 人気ノードが射影を密にする:超人気アイテムは、それを買った全ユーザーを互いに結び、巨大なクリークを作って射影を無意味に密にします。重みの正規化が必要。
- 二部グラフのクラスタ係数はゼロ:奇数閉路(三角形)がないので通常のクラスタ係数(クラスタ係数と推移性)は使えない。二部専用の指標を使います。
対応シミュレーション
本文のコードがそのまま検証用です。推薦への展開は 推薦システムとネットワーク(ML へリンク)。
関連
- 前提:特殊なグラフ
- 推薦システム:推薦システムとネットワーク
- リンク予測:リンク予測
- 上位ハブ:時間・多層・二部ネットワーク 目次