Mímisbrunnr知恵の泉

← ネットワーク科学 一覧

🎓 レベル:標準 | 重要度:A(必須)

📎 前提:二部ネットワークと射影リンク予測 | 関連:ランダムウォークと拡散の数理

要点(BLUF)

概念:推薦はネットワーク上のリンク予測

「あなたへのおすすめ」は、ユーザーとアイテムを結ぶ二部ネットワーク(二部ネットワークと射影)の上で、「このユーザーとこのアイテムの間に、将来エッジ(購入・評価)が現れるか」を当てる問題 — つまりリンク予測(リンク予測)です。ネットワーク科学の視点では、推薦は学習アルゴリズムである前に関係構造の問題。その構造を押さえることが土台になります。

協調フィルタリングの構造

**協調フィルタリング(collaborative filtering)**の発想は2つ。

どちらも「共起=関係の強さ」という射影の重みを類似度とみなしています。アイテム i,ji,j の共起は

cooc(i,j)=uBuiBuj\mathrm{cooc}(i,j) = \sum_{u} B_{ui} B_{uj}

「アイテム iijj を両方買ったユーザー数」。これが大きいほど2つは似ているとみなし、ユーザーが片方を買ったらもう片方を薦めます。

コードで確認

import numpy as np

# 5ユーザー × 4アイテム の購買行列(1=購入)
R = np.array([
    [1,1,0,0],
    [1,1,1,0],
    [0,1,1,0],
    [0,0,1,1],
    [1,0,0,1],
])

cooc = R.T @ R                                  # アイテム共起 = 列の内積
print("アイテム共起行列:")
print(cooc)

# ユーザー0(アイテム0,1を購入)への推薦
user = 0
bought = [int(i) for i in np.where(R[user] > 0)[0]]
scores = {item: int(sum(cooc[item, b] for b in bought))
          for item in range(R.shape[1]) if item not in bought}
print(f"ユーザー{user}(購入: {bought})への推薦スコア:", scores)
print("最も推薦すべきアイテム:", max(scores, key=scores.get))

実行結果:

アイテム共起行列:
[[3 2 1 1]
 [2 3 2 0]
 [1 2 3 1]
 [1 0 1 2]]
ユーザー0(購入: [0, 1])への推薦スコア: {2: 3, 3: 1}
最も推薦すべきアイテム: 2

(注:共起行列の対角はアイテムの総購入数。)ユーザー0はアイテム0と1を購入済み。未購入のアイテム2は「0や1と一緒に買われた回数」が3で、アイテム3の1より高い。だってアイテム1と2を一緒に買った人(ユーザー1,2)がいるからです。よってアイテム2を推薦 — 共起という関係構造だけから好みを推定できました。

ネットワークとしての推薦

graph LR
    subgraph 二部ネットワーク
        U["ユーザー"] --- I["アイテム"]
    end
    二部ネットワーク -->|"射影"| Sim["アイテム類似度(共起)"]
    Sim -->|"リンク予測"| Rec["未購入エッジを推薦"]
    二部ネットワーク -.->|"ランダムウォーク"| RW["パーソナライズPageRank"]

ランダムウォーク(ランダムウォークと拡散の数理)の視点も強力で、ユーザーから出発したパーソナライズドPageRankで「たどり着きやすいアイテム」を推薦する手法(例:Pixie)も実用されています。

数式の直観的意味

協調フィルタリングが効くのは、「好みは関係構造に埋め込まれている」からです。あなたが何を好むかを直接知らなくても、「あなたと似た人」「あなたが好きな物と一緒に消費される物」という間接的な関係から推定できる。共起行列 BBB^\top B はその関係の強さを数えたもので、リンク予測の共通近傍スコア(リンク予測)と同じ「共有する相手が多いほど似ている」原理です。ここから先 — 疎な行列を埋める行列分解、非線形な好みを捉える深層学習やGNN — は機械学習のturfで、ネットワーク科学はその構造的土台を提供します。

⚠️ よくある誤解・落とし穴

対応シミュレーション

本文のコードがそのまま検証用です。行列分解・GNN による推薦は機械学習へ(薄リンク)。

関連