人々が協調フィルタリングやレコメンデーション エンジンなどにどのようにアプローチしているかを知りたいと思っています。これは、何よりもスクリプトのパフォーマンスの観点からです。私は、Programming Collective Intelligence を読んでいると述べました。これは非常に興味深いものですが、物事のアルゴリズム面により焦点を当てる傾向があります。
現在、ユーザーは 2,000 人しかいませんが、現在のシステムは完全に将来性がなく、サーバーにすでに非常に負担がかかっていることが証明されています。システム全体は、ユーザーへの投稿の推奨に基づいています。私のアプリケーションは PHP/MySQL ですが、協調フィルタリングに MongoDB を使用しています。大規模な Amazon EC2 インスタンスを使用しています。私のセットアップは、実際には 2 ステップのプロセスです。最初にアイテム間の類似性を計算し、次にこの情報を使用してレコメンデーションを作成します。仕組みは次のとおりです。
まず、私のシステムはユーザーの投稿間の類似性を計算します。スクリプトは、各ペアの類似度スコアを返すアルゴリズムを実行します。アルゴリズムは、一般的なタグ、一般的なコメント投稿者、一般的ないいね! などの情報を調べ、類似度スコアを返すことができます。プロセスは次のようになります。
- 投稿が追加されたり、タグが追加されたり、コメントが付けられたり、いいね! が付けられたりするたびに、それをキューに追加します。
- 私はこのキューを cron 経由で (1 日 1 回) 処理し、各投稿の関連情報 (コメント投稿者といいね! の user_id、tag_id など) を見つけます。この情報を次のような構造で MongoDB に保存します: {"post_id":1,"tag_ids":[12,44,67],"commenter_user_ids":[6,18,22],"liker_user_ids":[87, 6]}。これにより、MongoDB コレクションを最終的に構築することができ、類似性を計算しようとするときに、すべての関連情報に簡単かつ迅速にアクセスできます。
- 次に、別の cron スクリプトを実行します (これも 1 日に 1 回ですが、前のスクリプトの後)、再びキューを通過します。今回は、キュー内の各投稿について、MongoDB コレクションからエントリを取得し、それを他のすべてのエントリと比較します。2 つのエントリに一致する情報がある場合は、類似性に関して +1 を付けます。最後に、投稿の各ペアの総合スコアを取得します。次の構造を持つ別の MongoDB コレクションにスコアを保存します: {"post_id":1,"similar":{"23":2,"2":5,"7":2}} ('similar' はpost_id をキー、類似度スコアを値とする key=>value 配列 0 の場合はスコアを保存しません。
5kの投稿があります。したがって、上記のすべてはサーバー上で非常に困難です。大量の読み取りと書き込みを実行する必要があります。さて、これは問題の半分にすぎません。次に、この情報を使用して、特定のユーザーにとってどの投稿が興味深いかを判断します。そのため、1 時間に 1 回、サイトのユーザーごとに 1 つの推奨投稿を計算するスクリプトを実行する cron スクリプトを実行します。プロセスは次のようになります。
- スクリプトは最初に、ユーザーが取得するレコメンデーションのタイプを決定します。1. あなたの投稿の 1 つに似た投稿、または 2. あなたがやり取りした投稿に似た投稿。
- 1 の場合、スクリプトは MySQL からユーザーの post_ids を取得し、それらを使用して MongoDB から同様の投稿を取得します。スクリプトは、最も類似しており、まだユーザーに推奨されていない投稿を取得します。
- 2 の場合、スクリプトは、ユーザーが MySQL からコメントまたはいいね! を付けたすべての投稿を取得し、それらの ID を使用して上記の 1 と同じことを行います。
残念ながら、1 時間ごとの推奨スクリプトはリソースを大量に消費するようになり、完了するまでに時間がかかります... 現在 10 ~ 15 分です。ある時点で、時間ごとの推奨事項を提供できなくなるのではないかと心配しています。
誰かが私がこれにもっとうまくアプローチできると感じているかどうか疑問に思っていますか?