レコメンドの仕組み(コサイン類似度とベクトル検索)
ユーザーの好みと商品の近さを「ベクトルのなす角」で判定するアルゴリズム
- 1
- レコメンドの仕組み(コサイン類似度とベクトル検索)の本質的な定義と直感的ビジュアルをシミュレーターで体験できる。
- 2
- 公式や証明の背景にある数学的意味と、厳密な導出ステップを解説。
- 3
- 実社会における工学応用(レコメンドエンジンにおけるコサイン類似度計算とTop-Kランキング)のTypeScript実装コードを収録。
なぜこれを学ぶのか? — 現実社会とテクノロジーでの価値
なぜ生まれたのか?
レコメンドの仕組み(コサイン類似度とベクトル検索)の基礎原理を体系化し、抽象的な計算を直感的に扱うために誕生した。
身につく武器・思考力
ユーザーの好みと商品の近さを「ベクトルのなす角」で判定するアルゴリズム。この考え方を身につけることで、複雑な課題を単純化して数理モデルとして解く力が養われる。
実社会・ITでの活躍現場
- •レコメンドエンジンにおけるコサイン類似度計算とTop-Kランキング
- •ITシステム・アルゴリズム実装における論理設計
- •データ分析やシミュレーションにおける数理モデリング
Layer 1 — 直感・シミュレーター
2次元の特徴量空間(横軸: アクション度、縦軸: コメディ度)上で、ユーザーの好みベクトル(青い矢印)をドラッグして動かしてみよう。配置された4本の映画アイテム(アクション映画、コメディ映画、アニメ、SF)のうち、ユーザーの矢印と「角度が最も近い(コサイン類似度 cosθ が 1 に近い)」映画がリアルタイムで最もおすすめとしてハイライトされる。
↑ ベクトルの長さ(絶対値)が違っても、「原点から見た角度(比率)」が近ければコサイン類似度は 1 に近くなります。NetflixやAmazonの推薦システム、LLMのベクトル検索(RAG)は、この内積とコサイン類似度を数百〜数千次元の空間で高速計算しています。
Layer 2 — 定義・受験・証明
定義
2つの多次元ベクトル の類似度を、両者のなす角 の余弦()で評価したものを「コサイン類似度」と呼ぶ。ベクトルの内積とノルム(大きさ)を用いて次のように計算される。
値は (正反対)から (完全一致)の範囲をとり、ベクトルの絶対的な大きさ(評価の多さなど)に左右されず、方向(好みの傾向)だけを比較できる。
公式・数理モデル
証明・導出
高校数学のベクトルの内積の定義式 の両辺を、それぞれのベクトルの長さ で割ることで導かれる。
幾何学的には、ベクトル と をそれぞれ長さ 1 の単位ベクトルに正規化()した上で内積をとることと完全に一致する。方向が一致するとき 、直交して全く無関係なとき となる。
押さえておきたいポイント
- ベクトルの大きさ(長さ)を無視し、「向き(好みの比率)」だけを比較できる指標である
- 動画配信・ECサイト・音楽アプリのレコメンドエンジンのコアアルゴリズムとして広く採用されている
- ChatGPTなどのLLMにおける「RAG(検索拡張生成)」やベクトルデータベース(Pinecone, Qdrant等)の類似文章検索でも、テキストをEmbedding(埋め込みベクトル)に変換してコサイン類似度で類似検索している
- 高校で習うベクトルの内積とノルムの計算が、現代のAIとWebサービスの最前線で直結している好例である
本トピックの内容・数理モデルは、文部科学省学習指導要領(算数・数学・情報)および国際標準カリキュラムに準拠し、エンジニアリング現場の実装事例と照らし合わせてMath World Lab編集部により検証・作成されています。
Layer 3 — 工学応用・現場実装
レコメンドエンジンにおけるコサイン類似度計算とTop-Kランキング
ユーザーの閲覧・購入履歴から生成した特徴量ベクトルと、データベース内の商品ベクトル群とのコサイン類似度をバッチ計算し、類似度スコアが高い上位 件の商品をレコメンド枠に出力する。
1type Vector = number[];23// コサイン類似度の計算4function cosineSimilarity(a: Vector, b: Vector): number {5 let dotProduct = 0;6 let normA = 0;7 let normB = 0;8 for (let i = 0; i < a.length; i++) {9 dotProduct += a[i] * b[i];10 normA += a[i] * a[i];11 normB += b[i] * b[i];12 }13 if (normA === 0 || normB === 0) return 0;14 return dotProduct / (Math.sqrt(normA) * Math.sqrt(normB));15}1617// ユーザーの好み: [アクション: 0.9, コメディ: 0.2]18const userProfile: Vector = [0.9, 0.2];1920const movies = [21 { title: "マッド・マックス", features: [0.95, 0.1] },22 { title: "ハングオーバー", features: [0.1, 0.9] },23 { title: "スパイ・コメディ", features: [0.6, 0.6] },24];2526const recommendations = movies27 .map((m) => ({ ...m, score: cosineSimilarity(userProfile, m.features) }))28 .sort((a, b) => b.score - a.score);2930console.log("最推し映画:", recommendations[0].title, "(類似度:", recommendations[0].score.toFixed(3), ")");
次に学ぶならコレ!おすすめトピック
この単元と深い繋がりを持つ、あわせて学ぶと理解が深まるおすすめ単元