2.4 チュートリアル: MovieLens データセットを用いた従来型から LLM ベースの推薦への進化の詳解

位置づけ

2.4 は、ここまで説明されてきた従来型推薦と LLM ベース推薦を、実験として比較するチュートリアルである。教科書では MovieLens ml-1m を使い、協調フィルタリングの代表例である SVD と、映画タイトルをプロンプトに入れて LLM に推薦させる方法を比較している。

この節の重要な点は、LLM がすぐに従来型推薦を上回るという話ではない。むしろ、ゼロショットの LLM プロンプティングは意味理解に強みがある一方で、行動ログを使って学習した協調フィルタリングにはまだ精度や速度で負ける、という現実的な結果を示している。

Hulu の動画推薦に読み替えると、このチュートリアルは次の問いに対応する。

  • unique_viewed_series のような視聴ログだけで作る従来型推薦はどこまで強いのか
  • item_information_table のタイトルや説明文を LLM に読ませる推薦はどこまで使えるのか
  • LLM をゼロショットで使うだけで本番推薦に耐えるのか
  • LLM は従来型推薦を置き換えるべきか、それとも補助として使うべきか
  • 精度、多様性、カバレッジ、実行時間をどう比較すべきか

結論から言うと、Hulu のような大規模サービスでは、ゼロショット LLM を直接推薦エンジンにするより、従来型推薦を中心に置き、LLM を特徴量生成、候補補強、自然言語検索、推薦理由生成に使う方が現実的である。

MovieLens ml-1m とは何か

MovieLens ml-1m は、推薦システムの研究や学習でよく使われる映画評価データセットである。ユーザー、映画、評価値、タイムスタンプを含む。

典型的には、次のような情報を持つ。

  • ユーザー ID
  • 映画 ID
  • 映画タイトル
  • ジャンル
  • ユーザーが付けた評価
  • 評価時刻

教科書の実験では、ユーザーが映画に明示的な評価を付けている。この点は Hulu の unique_viewed_series と違う。Hulu の主要なデータは「25% 以上視聴したか」という暗黙的フィードバックであり、星評価ではない。

違いを整理すると次のようになる。

観点 MovieLens Hulu の unique_viewed_series
フィードバック 星評価 25% 以上視聴した事実
明示性 明示的 暗黙的
負例 低評価を負例にしやすい 未視聴は負例とは限らない
アイテム 映画 シリーズ単位の作品
時間情報 評価時刻 last_viewing_date
メタデータ タイトル、ジャンルなど タイトル、ジャンル、タグ、説明文、出演者、mood、fingerprint など

MovieLens はチュートリアルには扱いやすい。しかし、Hulu へ応用する場合は、暗黙的フィードバック、配信期間、SVOD/TVOD、ブラックリスト、キッズ制約、シリーズ構造を考える必要がある。

実験設計の目的

このチュートリアルの目的は、単に SVD と LLM のスコアを比べることではない。推薦システムを比較するときに、何をそろえ、何を測り、どう解釈するべきかを学ぶことである。

実験設計で重要なのは次の点である。

  • 学習データとテストデータを時間で分ける
  • 比較する手法の入力情報を明確にする
  • 推薦候補の範囲を明確にする
  • 評価指標を複数用意する
  • 精度だけでなく、多様性、カバレッジ、実行時間を見る
  • 結果が実務上どういう意味を持つか解釈する

推薦システムでは、オフライン指標だけを見ても不十分である。しかし、オフライン実験はモデル候補をふるい分けるために不可欠である。A/B テストに出す前に、まず過去データで妥当性を確認する必要がある。

時系列分割

教科書では、各ユーザーのインタラクションを時系列で並べ、古い 90% を訓練、最新の 10% をテストにしている。

これは推薦評価では自然な方法である。推薦システムは過去から未来を予測するものだからである。

ユーザー uu のインタラクション履歴を時刻順に次のように表す。

Hu=[(i1,t1),(i2,t2),,(in,tn)]H_u = \left[ (i_1, t_1), (i_2, t_2), \ldots, (i_n, t_n) \right]

ここで t1<t2<<tnt_1 < t_2 < \cdots < t_n である。90% を訓練に使うなら、分割点 mm は次のように置ける。

m=0.9nm = \lfloor 0.9 n \rfloor

訓練履歴とテスト履歴は次のようになる。

Hutrain=[(i1,t1),,(im,tm)]H_u^{\text{train}} = \left[ (i_1, t_1), \ldots, (i_m, t_m) \right]
Hutest=[(im+1,tm+1),,(in,tn)]H_u^{\text{test}} = \left[ (i_{m+1}, t_{m+1}), \ldots, (i_n, t_n) \right]

この設計により、「過去に見たものから、将来見るものを当てる」という評価になる。

Hulu でも同じ考え方を使える。例えば、unique_viewed_serieslast_viewing_date を使って、プロフィールごとに過去履歴と将来視聴を分ける。

具体例:

  • 学習期間: 2026-01-01 から 2026-03-31
  • 検証期間: 2026-04-01 から 2026-04-30
  • テスト期間: 2026-05-01 から 2026-05-31

学習期間の視聴履歴から推薦を作り、テスト期間に 25% 以上視聴された series_id を正解にする。

ランダム分割ではなく時系列分割を使う理由は、未来情報の漏洩を避けるためである。ランダム分割では、未来に見た作品が学習側に混ざり、現実より簡単な評価になってしまう。

比較対象 1: SVD による協調フィルタリング

教科書の従来型手法は、SVD による行列分解である。これは協調フィルタリングの代表的な方法であり、ユーザーとアイテムの相互作用行列を低次元の潜在表現に分解する。

ユーザー uu のアイテム ii に対する評価を ru,ir_{u,i} とする。行列分解では、これをユーザーベクトル pu\mathbf{p}_u とアイテムベクトル qi\mathbf{q}_i の内積で近似する。

r^u,i=μ+bu+bi+puTqi\hat{r}_{u,i} = \mu + b_u + b_i + \mathbf{p}_u^{\mathsf{T}}\mathbf{q}_i

ここで、μ\mu は全体平均、bub_u はユーザー固有のバイアス、bib_i はアイテム固有のバイアスである。

MovieLens のような星評価データでは、実際の評価 ru,ir_{u,i} と予測評価 r^u,i\hat{r}_{u,i} の誤差を小さくするように学習できる。

L=(u,i)O(ru,ir^u,i)2+λ(pu2+qi2+bu2+bi2)L = \sum_{(u,i) \in \mathcal{O}} \left( r_{u,i} - \hat{r}_{u,i} \right)^2 + \lambda \left( \|\mathbf{p}_u\|^2 + \|\mathbf{q}_i\|^2 + b_u^2 + b_i^2 \right)

ここで O\mathcal{O} は観測された評価集合、λ\lambda は正則化係数である。

SVD の強みは、ユーザーとアイテムの相互作用パターンを直接学習できる点である。あるユーザーがどの映画を高く評価し、似たユーザーが他に何を評価したかを使える。

一方、Hulu の unique_viewed_series では星評価がない。したがって、次のような暗黙的フィードバック向けの変形が必要になる。

yu,i={1プロフィール u がシリーズ i を 25% 以上視聴した場合0未観測の場合y_{u,i} = \begin{cases} 1 & \text{プロフィール } u \text{ がシリーズ } i \text{ を 25\% 以上視聴した場合} \\ 0 & \text{未観測の場合} \end{cases}

ただし、yu,i=0y_{u,i}=0 は「嫌い」を意味しない。未観測であるだけである。この点が MovieLens より難しい。

暗黙的フィードバックでは、BPR や implicit matrix factorization のような手法を使う方が自然である。

比較対象 2: LLM プロンプティング

教科書の LLM 手法は、ユーザーが好きな映画タイトルと嫌いな映画タイトルをプロンプトに入れ、LLM に映画タイトルを推薦させる方法である。

プロンプトの構造は次のようになっている。

You are a helpful movie recommendation assistant.
The user USER_1680 liked the following movies: ...
The user USER_1680 disliked these movies: ...
Please recommend exactly 5 movies that are similar to the liked ones and different from the disliked ones.
Output only the recommended movie titles separated by commas.

この設計の狙いは、LLM が映画タイトルに関する事前知識や意味的関連を使って、好みに合いそうな映画を生成することである。

SVD と大きく違う点は、LLM はこの実験用データで明示的に学習していないことである。つまり、ゼロショットに近い使い方である。LLM は MovieLens の評価行列を学習するのではなく、一般的な映画知識と言語理解を使って推薦する。

この方式の長所は、相互作用データが少なくても使えることである。映画タイトルや説明文があれば、ある程度意味的な推薦ができる。

一方、短所も明確である。

  • カタログに存在しない映画を出す可能性がある
  • ユーザー行動データに最適化されていない
  • 出力形式が崩れることがある
  • 推論コストが高い
  • 同じ入力でも出力が揺れることがある
  • 大量ユーザーへのバッチ推薦には遅い

Hulu で同じことをするなら、プロンプトには series_title_ja、視聴済み作品、未視聴または低反応作品、ジャンル、説明文などを入れられる。ただし、LLM に自由に作品名を生成させるのは危険である。配信中でない作品や Hulu に存在しない作品を出す可能性があるためである。

実務では、LLM には候補集合を渡し、その中から選ばせる方が安全である。

以下の候補 series_id からのみ、ユーザーに合う順に 5 件選ぶ。
候補にない作品名を出してはいけない。

好き・嫌いの作り方

教科書のプロンプトでは、liked movies と disliked movies が出てくる。MovieLens では星評価があるため、例えば高評価を liked、低評価を disliked として作れる。

例えば:

  • 評価 4 以上: liked
  • 評価 2 以下: disliked
  • 評価 3: 中立または除外

Hulu では明示的な disliked がない場合が多い。unique_viewed_series には 25% 以上視聴した作品だけが入る。つまり、liked に相当する正例は作りやすいが、disliked に相当する負例は作りにくい。

Hulu で LLM プロンプトを作るなら、次のように考える必要がある。

プロンプト要素 MovieLens Hulu での候補
liked 高評価映画 25% 以上視聴したシリーズ
disliked 低評価映画 表示されたが視聴されなかった作品、すぐ離脱した作品、非表示作品
neutral 評価 3 視聴したが短時間離脱、または不明
unknown 未評価映画 未表示または未視聴作品

もし Hulu 側にインプレッションログや再生秒数があれば、より良い disliked を作れる。

例えば:

  • 表示されたがクリックされなかった
  • 詳細ページを開いたが再生しなかった
  • 再生したが数分で離脱した
  • 25% 未満で離脱した
  • 非表示や低評価をした

しかし、unique_viewed_series だけでは disliked は作れない。この場合、プロンプトでは disliked を無理に入れず、liked と候補集合だけで推薦する方が安全である。

LLM プロンプト設計のポイント

推薦プロンプトでは、LLM に何をしてほしいかを明確にする必要がある。

重要な要素は次である。

  • 役割
  • ユーザー履歴
  • 好きな作品
  • 避けたい作品
  • 候補集合
  • 推薦件数
  • 出力形式
  • 制約
  • 推薦理由の有無

MovieLens の例では、出力を「映画タイトルをカンマ区切りで 5 件」に制限している。これは評価をしやすくするためである。推薦結果を自動評価するには、出力をパースしやすくしなければならない。

Hulu であれば、タイトルではなく series_id を出させる方がよい。

出力は JSON 配列のみとする。
各要素は {"series_id": 123, "reason": "..."} の形式にする。
候補に含まれない series_id を出してはいけない。

タイトルだけを出させると、同名作品、表記揺れ、邦題と原題の違い、シリーズとエピソードの違いで照合が難しくなる。series_id を使えば評価や表示につなげやすい。

推論モデルの選び方

教科書では、小型で応答性の良い GPT 系モデルを使っている。ここで重要なのは、推薦用途では最も大きいモデルが常に最適とは限らないことである。

推薦で考えるべき観点は次である。

  • 推薦品質
  • 推論レイテンシ
  • 推論コスト
  • 出力形式の安定性
  • 長い履歴を扱えるか
  • 候補集合を正しく守れるか
  • 日本語メタデータを扱えるか
  • 安全性制約を守れるか

Hulu のホーム推薦のように大量リクエストがある場合、大きな LLM をオンラインで毎回呼ぶのは現実的ではない。小型モデル、embedding モデル、蒸留モデル、オフラインバッチ生成を組み合わせる必要がある。

一方、会話型推薦や検索補助のように、ユーザーが明示的に相談している場面では、多少レイテンシが大きくても LLM の価値が出やすい。

評価指標の意味

教科書では、Recall@k、Precision@k、NDCG@k、Catalog Coverage Ratio、Entropy Diversity、Execution Time を使っている。

これは良い組み合わせである。精度だけでなく、推薦がどれだけ広いカタログを使っているか、どれだけ多様か、どれだけ時間がかかるかを同時に見ているからである。

Recall@K

Recall@K は、テスト期間に実際に好まれたアイテムのうち、推薦上位 KK 件でどれだけ拾えたかを測る。

Recall@K=Ru(K)YuYu\text{Recall@K} = \frac{ |\mathcal{R}_u^{(K)} \cap \mathcal{Y}_u| }{ |\mathcal{Y}_u| }

ここで Ru(K)\mathcal{R}_u^{(K)} はユーザー uu への上位 KK 件推薦、Yu\mathcal{Y}_u はテスト期間の正解アイテム集合である。

Hulu なら、Yu\mathcal{Y}_u はテスト期間に 25% 以上視聴された series_id 集合にできる。

Recall@K は、候補検索やランキングが将来視聴をどれだけ漏らさず拾えているかを見る指標である。

Precision@K

Precision@K は、推薦上位 KK 件のうち、正解アイテムがどれだけ含まれているかを見る。

Precision@K=Ru(K)YuK\text{Precision@K} = \frac{ |\mathcal{R}_u^{(K)} \cap \mathcal{Y}_u| }{K}

Recall@K が「正解集合をどれだけ拾ったか」を見るのに対し、Precision@K は「推薦リストがどれだけ当たりで埋まっているか」を見る。

動画配信のホーム画面では、上位の推薦枠が限られるため Precision@K は重要である。ただし、テスト期間に 1 作品しか視聴していないユーザーでは、Precision@10 の最大値は 0.10.1 になる。ユーザーの活動量に左右される点に注意が必要である。

NDCG@K

NDCG@K は、正解アイテムを上位に置けているかを見る指標である。

DCG@K=k=1K2relk1log2(k+1)\text{DCG@K} = \sum_{k=1}^{K} \frac{2^{rel_k}-1}{\log_2(k+1)}
NDCG@K=DCG@KIDCG@K\text{NDCG@K} = \frac{\text{DCG@K}}{\text{IDCG@K}}

ここで relkrel_k は順位 kk のアイテムの関連度である。正解なら 1、不正解なら 0 と置くこともできるし、評価値や視聴深度に応じて段階的に置くこともできる。

Hulu では、例えば次のように関連度を作れる。

行動 関連度 relrel
表示されたが無反応 0
詳細ページ閲覧 1
再生開始 2
25% 以上視聴 3
完走または次エピソード視聴 4

ただし、unique_viewed_series だけを使う場合は 25% 以上視聴したかどうかの二値に近くなる。

Catalog Coverage Ratio

Catalog Coverage Ratio は、推薦システムがカタログ全体のうちどれだけのアイテムを推薦しているかを見る指標である。

Coverage=uURu(K)I\text{Coverage} = \frac{ |\bigcup_{u \in \mathcal{U}} \mathcal{R}_u^{(K)}| }{ |\mathcal{I}| }

ここで I\mathcal{I} は推薦可能な全アイテム集合である。

Coverage が低い場合、人気作品ばかり推薦している可能性がある。Coverage が高い場合、より広い作品が露出されている。

Hulu では、単純な全体カバレッジだけでなく、次の分解が重要である。

  • SVOD 作品の Coverage
  • TVOD 作品の Coverage
  • 新作 Coverage
  • ロングテール作品 Coverage
  • ジャンル別 Coverage
  • コンテンツ提供者別 Coverage
  • キッズ向け作品 Coverage

ただし、Coverage が高ければ高いほど良いわけではない。ユーザーに合わない作品まで無理に推薦すれば、視聴率は下がる。

Entropy Diversity

Entropy Diversity は、推薦がどれだけ多様なアイテムやカテゴリに分散しているかを見る指標である。

エントロピーは、分布が均等であるほど大きく、偏っているほど小さい。

アイテムまたはカテゴリ cc の推薦割合を p(c)p(c) とすると、エントロピーは次のように書ける。

Ent(D)=cCp(c)logp(c)\text{Ent}(D) = - \sum_{c \in \mathcal{C}} p(c) \log p(c)

例えば、推薦がほぼすべてアニメに偏っていればエントロピーは低くなる。アニメ、映画、ドラマ、バラエティ、ドキュメンタリーに適度に分散していれば高くなる。

Hulu では、エントロピーを何の分布で測るかが重要である。

  • アイテム ID 分布
  • genre 分布
  • sub_genre 分布
  • contents_provider_name 分布
  • service_type 分布
  • mood タグ分布

ホーム画面全体では多様性が必要だが、特定の棚ではテーマを絞ることもある。したがって、エントロピーは棚単位、ページ単位、ユーザー単位、サービス全体で分けて見る必要がある。

Execution Time

Execution Time は、推薦生成にかかった時間である。教科書の結果では、LLM プロンプティングは CF より桁違いに遅い。

この指標は実務では非常に重要である。推薦品質が少し高くても、レスポンスが遅すぎれば本番には使えない。

Hulu のホーム推薦では、ユーザーがアプリを開いたときにすぐ表示される必要がある。LLM に毎回長いプロンプトを送って推薦を生成すると、レイテンシとコストが問題になる。

実務では、次のような分離が必要である。

  • オフライン: 作品 embedding、タグ、説明文、類似作品クラスタを生成する
  • 準リアルタイム: ユーザーの最近視聴から短期嗜好を更新する
  • オンライン: 軽量な候補検索とランキングで推薦を返す
  • 限定的オンライン LLM: 会話型推薦や少数候補の再ランキングに使う

結果の読み方

教科書の結果では、CF が Recall、Precision、NDCG で LLM を上回っている。これは自然な結果である。

CF は MovieLens の評価データから、ユーザーと映画の相互作用パターンを直接学習している。一方、LLM は映画タイトルだけを見て、一般知識から推薦している。つまり、CF はこのデータセットの評価傾向に最適化されているが、LLM は最適化されていない。

例えば、あるユーザーが「Fargo」「Run Lola Run」「The Sixth Sense」を高評価しているとして、LLM は意味的に近い映画を出せるかもしれない。しかし、そのユーザーが MovieLens 上で実際に次に評価した映画を当てるには、他ユーザーの評価パターンを学習した CF の方が強い。

これは Hulu でも同じである。LLM が作品説明を読んで「このユーザーに合いそう」と判断しても、実際の Hulu ユーザーが視聴するかは、過去の視聴パターン、人気、UI 露出、配信タイミング、SVOD/TVOD、サムネイル、文脈に左右される。

したがって、LLM の意味理解だけで行動予測を置き換えるのは難しい。

LLM のゼロショット性能をどう評価するか

教科書では、LLM プロンプトベースモデルは CF に負けているが、ゼロショットとしては実用的な推薦品質を出していると解釈している。

この見方は妥当である。LLM は MovieLens のユーザー評価行列を学習していないにもかかわらず、タイトルだけから一定の関連性を持つ映画を出している。これは、LLM が映画タイトルや作品の一般的な意味知識を持っているためである。

ただし、Hulu の実務では「ゼロショットでそこそこ良い」だけでは不十分である。本番推薦では、次の要件がある。

  • カタログ内に存在する作品だけを出す
  • 配信期間内の作品だけを出す
  • is_blacklist=false を守る
  • キッズやレーティング制約を守る
  • SVOD/TVOD の表示方針を守る
  • レイテンシを守る
  • A/B テストで行動指標を改善する

LLM のゼロショット推薦は、研究やプロトタイプとしては価値がある。しかし、本番では制約付き生成、候補集合制限、ランキングモデルとのハイブリッド化が必要である。

カバレッジと多様性の解釈

教科書の結果では、LLM は CF より精度で劣るが、カタログカバレッジや多様性でも極端に悪いわけではないとされている。

これは興味深い点である。LLM は映画タイトルの意味や一般的な映画知識から推薦するため、必ずしも MovieLens 内の人気アイテムだけに集中しない可能性がある。

ただし、LLM には別の偏りもある。

  • 有名作品を出しやすい
  • 学習データでよく言及される作品を出しやすい
  • マイナー作品を知らない、または出しにくい
  • ユーザーの細かい行動傾向より一般的な類似性を優先しやすい
  • 日本ローカル作品や配信サービス固有作品に弱い場合がある

Hulu では、国内ドラマ、バラエティ、アニメ、ライブ、TVOD、独占配信など、一般的な海外映画知識だけでは扱いきれない領域がある。したがって、LLM の一般知識に頼るより、Hulu カタログのメタデータと視聴ログに接続する必要がある。

実行時間の差が意味すること

教科書の表では、CF は約 26 秒、LLM は k=20 で約 2825 秒かかっている。LLM は約 100 倍遅い計算になる。

この差は、実務上かなり大きい。

CF や行列分解は、一度モデルを学習すれば、ユーザーとアイテムの内積や近傍検索で高速に推薦できる。LLM プロンプティングは、ユーザーごとに長い入力を作り、モデル推論で出力を生成する必要がある。

時間の差は、単に「遅い」だけではなく、次の問題につながる。

  • オンライン推薦に使いにくい
  • 大量ユーザーへの日次バッチ推薦でも高コストになる
  • A/B テストの対象ユーザーを増やしにくい
  • 障害時やピーク時の安定性が課題になる
  • 出力形式の検証や再試行も必要になる

このため、LLM を推薦に使う場合は、直接全ユーザーにプロンプト推薦するより、次のような使い方が現実的である。

  • 作品 embedding を事前生成する
  • LLM 生成タグを特徴量化する
  • 少数候補だけを再ランキングする
  • 会話型推薦に限定する
  • 大きな LLM の出力で小さなモデルを蒸留する

先進的手法 1: 長いユーザー履歴への対応

LLM にユーザー履歴を入れる場合、履歴が長くなるほどプロンプトが大きくなる。すべての視聴履歴をそのまま入れるのは非効率である。

Hulu のプロフィールには、数百、数千の視聴済み series_id があるかもしれない。これをすべて LLM に入れると、トークン数、コスト、ノイズが増える。

対策は、履歴を要約することである。

例えば、最近視聴と長期嗜好を分ける。

長期嗜好:
- SF 映画、ミステリー、知的サスペンスをよく視聴
- クリストファー・ノーラン監督作品への反応が強い
- 長尺映画も週末に視聴する

短期嗜好:
- 最近 7 日間は韓国ドラマと恋愛作品を連続視聴
- 平日夜に 45 分程度のシリーズを視聴

このように要約すれば、LLM は履歴全件を読む必要がない。

数式的には、長期嗜好と短期嗜好を分けて表現できる。

u=λulong+(1λ)ushort\mathbf{u} = \lambda \mathbf{u}_{\text{long}} + (1-\lambda)\mathbf{u}_{\text{short}}

ここで ulong\mathbf{u}_{\text{long}} は長期履歴、ushort\mathbf{u}_{\text{short}} は最近履歴、λ\lambda は重みである。

LLM プロンプトでも同じ考え方が使える。履歴を全部渡すのではなく、推薦に効く情報へ圧縮する。

先進的手法 2: 制御生成

LLM が自由に映画タイトルを生成すると、カタログ外の作品が出る可能性がある。MovieLens の実験でも、LLM が出したタイトルをデータセット内の映画と照合する処理が必要になる。

Hulu では、これはさらに重要である。配信していない作品、配信終了した作品、ブラックリスト作品、キッズ不適合作品を推薦してはいけない。

制御生成とは、LLM の出力を制約することである。

実務的には、次の方法がある。

  • 候補 series_id の中から選ばせる
  • JSON スキーマを固定する
  • 出力後に series_id を検証する
  • 候補外の出力は破棄する
  • 配信制約は LLM ではなくシステム側で適用する
  • 関数呼び出しやツール呼び出しで検索結果を取得させる

例:

{
  "recommendations": [
    {"series_id": 500001745, "rank": 1, "reason": "SF と知的サスペンス嗜好に合うため"}
  ]
}

タイトル文字列より series_id を出す設計の方が、評価、表示、ログ保存に向いている。

先進的手法 3: 推薦のための基盤モデル

教科書では、推薦データで事前学習された基盤モデルにも触れている。これは、一般的な LLM をそのまま使うのではなく、ユーザー行動、アイテムメタデータ、レビュー、説明文を大量に使って、推薦向けに事前学習したモデルである。

一般 LLM は言語理解には強いが、特定サービスの行動パターンには最適化されていない。推薦基盤モデルは、次のようなデータを使って学習できる。

  • 視聴系列
  • クリック系列
  • 検索クエリ
  • 作品説明文
  • ジャンル、タグ、キャスト
  • 評価やレビュー
  • 作品間の共起
  • ユーザーとアイテムの時系列相互作用

Hulu なら、unique_viewed_series の視聴系列と item_information_table の作品メタデータを組み合わせることで、推薦向けの表現学習ができる。

例えば、次に視聴される作品を予測する事前学習タスクを作れる。

P(it+1i1,i2,,it)P(i_{t+1} \mid i_1, i_2, \ldots, i_t)

これは、ユーザーの過去視聴系列から次の series_id を予測するタスクである。

さらに、作品説明文と series_id を結び付けるタスクを入れれば、コールドスタートにも強くなる。

先進的手法 4: ドメイン特化ファインチューニング

ゼロショット LLM は便利だが、推薦タスクに最適化されていない。そこで、ドメイン特化データでファインチューニングする方法がある。

MovieLens なら、ユーザー履歴から次に高評価する映画を当てるデータを作れる。

Hulu なら、次のような学習例を作れる。

入力:

プロフィールの過去視聴:
- インターステラー
- TENET
- ダークナイト

候補:
- オッペンハイマー
- 名探偵コナン
- 韓国恋愛ドラマ A
- 世界の果てまでイッテQ

次に 25% 以上視聴される可能性が高い候補を選べ。

出力:

{"series_id": 123456789}

このようなデータを大量に作れば、LLM または小型言語モデルを推薦タスクに寄せられる。

ただし、ファインチューニングには注意が必要である。

  • 表示バイアスを学習してしまう
  • 人気作品に偏る
  • 古いカタログ状態を覚えてしまう
  • 配信終了や権利変更に追従しにくい
  • 個人情報やセンシティブな推測を含めない設計が必要

実務では、LLM 本体を大きくファインチューニングする前に、embedding、reranker、小型モデル、LoRA などから試すのがよい。

先進的手法 5: モデル蒸留

モデル蒸留とは、大きなモデルの判断を小さなモデルに学習させる方法である。

推薦では、大きな LLM を教師として使い、小さなランキングモデルや reranker を学習させることができる。

例えば、大きな LLM に次のようなペア比較をさせる。

このユーザー履歴に対して、候補 A と候補 B のどちらが合うか。

LLM の判断を教師ラベルとして、軽量モデルを学習する。

L=(u,i,j)logσ(sϕ(u,i)sϕ(u,j))L = - \sum_{(u,i,j)} \log \sigma \left( s_\phi(u,i) - s_\phi(u,j) \right)

ここで sϕs_\phi は蒸留先の小さなモデルのスコアである。

蒸留の利点は、オンライン推論を軽くできることである。大きな LLM を毎回呼ぶ代わりに、小さなモデルで高速にランキングする。

ただし、LLM の判断が常に正しいわけではない。蒸留ラベルは、実ユーザー行動ログと併用する必要がある。

先進的手法 6: ハイブリッドモデリング

教科書の結論として最も実務的なのは、CF と LLM のハイブリッドである。

CF は行動ログに強い。LLM は意味理解に強い。両者を組み合わせると、互いの弱点を補える。

ハイブリッドスコアは、例えば次のように表せる。

S(u,i)=wcfScf(u,i)+wllmSllm(u,i)+wpopSpop(i)+wctxSctx(u,i)S(u,i) = w_{\text{cf}} S_{\text{cf}}(u,i) + w_{\text{llm}} S_{\text{llm}}(u,i) + w_{\text{pop}} S_{\text{pop}}(i) + w_{\text{ctx}} S_{\text{ctx}}(u,i)

ここで、ScfS_{\text{cf}} は協調フィルタリングスコア、SllmS_{\text{llm}} は LLM embedding 類似度や LLM reranker スコア、SpopS_{\text{pop}} は人気度、SctxS_{\text{ctx}} は文脈スコアである。

Hulu では、次のような候補ソースを混ぜるのが現実的である。

  • 協調フィルタリング候補
  • 類似作品候補
  • LLM embedding 類似候補
  • avg_fingerprint 類似候補
  • avg_mood_tag 類似候補
  • 人気候補
  • 新作候補
  • 配信終了間近候補

その後、ランキングモデルで統合する。

Hulu に置き換えた実験設計

このチュートリアルを Hulu データで再現するなら、次のような設計になる。

データ

使うテーブル:

  • unique_viewed_series
  • item_information_table

正例:

  • プロフィールが評価期間中に 25% 以上視聴した series_id

候補アイテム:

  • 評価時点で publish_start_at を過ぎている
  • 評価時点で publish_end_at を過ぎていない
  • is_blacklist=false
  • 必要に応じてキッズやレーティング制約を満たす

分割

時系列分割を使う。

例:

  • Train: 2026-01-01 から 2026-03-31
  • Validation: 2026-04-01 から 2026-04-30
  • Test: 2026-05-01 から 2026-05-31

比較手法

比較する手法は次のようにできる。

手法 内容
Popularity 全体人気またはセグメント人気
CF 暗黙的フィードバック行列分解、BPR、item-to-item
Content genresub_genreavg_fingerprint 類似
LLM Prompt 視聴履歴タイトルをプロンプトに入れて候補を選ばせる
LLM Embedding 視聴履歴 embedding と作品 embedding の類似度
Hybrid CF、Content、LLM 由来特徴量をランキングで統合

評価指標

Hulu では、次を使うとよい。

  • Recall@K
  • Precision@K
  • NDCG@K
  • HitRate@K
  • Catalog Coverage
  • Genre Coverage
  • Diversity
  • Novelty
  • Execution Time
  • 推薦可能制約違反率
  • 25% 以上視聴率のオンライン A/B 指標

オフラインでは unique_viewed_series から正解を作り、オンラインでは実際の推薦枠からの視聴を測る。

Hulu 向け LLM プロンプト例

Hulu で LLM プロンプト推薦を試す場合、カタログ外生成を避けるため、候補集合を渡す設計がよい。

あなたは動画配信サービスの推薦補助である。
以下の候補作品だけから、プロフィールに合う順に 5 件選ぶ。
候補にない作品を出してはいけない。
出力は JSON 配列のみとする。

プロフィールの最近の 25% 以上視聴:
- インターステラー
- TENET
- ダークナイト

長期的な傾向:
- 洋画、SF、サスペンスをよく視聴
- 知的で重厚な作品への反応が強い

候補:
[
  {"series_id": 1, "title": "オッペンハイマー", "genre": "洋画", "tags": ["科学者", "重厚", "歴史"]},
  {"series_id": 2, "title": "名探偵コナン", "genre": "アニメ", "tags": ["ミステリー", "家族向け"]},
  {"series_id": 3, "title": "韓国恋愛ドラマ A", "genre": "韓国ドラマ", "tags": ["恋愛"]}
]

出力形式:
[
  {"series_id": 1, "reason": "過去視聴と同じく、知的で重厚な作品傾向に合うため"}
]

このプロンプトでは、LLM に自由に作品名を作らせていない。候補集合の中から選ばせている。これは実務上非常に重要である。

このチュートリアルから得るべき教訓

この節から得るべき教訓は、次の 5 つである。

  1. 従来型 CF はまだ強い
  2. ゼロショット LLM は意味理解により一定の推薦ができる
  3. しかし、精度と実行時間では CF に負けやすい
  4. LLM を本番推薦に使うには制約付き生成、蒸留、ファインチューニング、ハイブリッド化が必要である
  5. 実務では LLM を置き換えではなく補強として使うのが堅実である

特に Hulu のようなサービスでは、推薦は単なる「作品名を 5 件出す」問題ではない。配信期間、権利、SVOD/TVOD、ブラックリスト、キッズ適合性、表示枠、レイテンシ、A/B テスト、長期継続が絡む。

そのため、LLM プロンプティングのチュートリアル結果を、そのまま本番設計に持ち込むべきではない。むしろ、LLM の得意領域と苦手領域を見極めるための基礎実験として読むべきである。

よくある誤解

LLM が CF に負けたので使えない

これは誤解である。ゼロショットのタイトルプロンプトだけで CF に勝てないのは自然である。LLM の価値は、意味理解、コールドスタート、自然言語検索、説明生成、メタデータ拡張にある。

LLM がそこそこ当たるので CF は不要である

これも誤解である。CF は実ユーザーの行動ログを直接学習するため、視聴確率の予測では非常に強い。LLM の一般知識だけでは、サービス固有の嗜好や配信状況を十分に捉えられない。

Precision や Recall だけで判断すればよい

精度指標は重要だが、多様性、カバレッジ、実行時間、制約違反率も重要である。動画配信では、人気作品だけを当てる推薦が短期精度を上げても、長期的な発見性を損なう可能性がある。

LLM にタイトルを出させれば評価できる

タイトル出力は表記揺れが多く、評価が難しい。実務では series_id のような安定した ID で出力させるべきである。

長い履歴を全部入れれば性能が上がる

履歴を増やすと情報も増えるが、ノイズ、トークン数、コストも増える。長期嗜好と短期意図を要約して入れる方が実務的である。

まとめ

2.4 のチュートリアルは、MovieLens を使って、従来型 CF と LLM プロンプティングを比較する実験である。時系列分割により過去から未来を予測する形にし、Recall@K、Precision@K、NDCG@K、Coverage、Entropy Diversity、Execution Time で評価している。

結果として、SVD ベースの CF は精度指標で LLM を上回っている。これは、CF がユーザーと映画の相互作用データに最適化されているためである。一方、LLM は映画タイトルだけのゼロショットプロンプトでも一定の推薦品質を出しており、意味理解の可能性を示している。

ただし、LLM プロンプティングは実行時間が非常に長く、スケーラビリティに課題がある。また、カタログ外生成や出力形式の揺れも問題になる。実務では、制御生成、履歴要約、推薦向けファインチューニング、モデル蒸留、ハイブリッドモデリングが必要である。

Hulu に応用するなら、unique_viewed_series を使った暗黙的フィードバック評価と、item_information_table を使ったコンテンツ理解を組み合わせるべきである。LLM は、直接すべての推薦を生成するより、作品 embedding、タグ生成、候補補強、少数候補の再ランキング、推薦理由生成に使う方が現実的である。

このチュートリアルの本質は、「LLM が従来型推薦をすぐ置き換える」ことではなく、「従来型推薦の強さを確認した上で、LLM の意味理解をどこに足すと価値が出るかを実験で見極める」ことである。