This blog is meant for all those developers who want to learn how to build complex products from scratch. The ones that
Walkthroughs, tutorials, guides, and tips. This story will teach you how to do something new or how to do something better.
レコメンデーション システムは、私たちの生活に不可欠な要素となっています。これらのインテリジェントなアルゴリズムは、私たちのオンライン体験を形成する上で極めて重要であり、私たちが消費するコンテンツ、購入する製品、探索するサービスに影響を与えます。私たちがNetflixなどのプラットフォームでコンテンツをストリーミングしている場合でも、 Spotifyで新しい音楽を発見している場合でも、オンライン ショッピングをしている場合でも、レコメンデーション システムは舞台裏で静かに動作して、私たちのインタラクションをパーソナライズし、強化しています。
これらのレコメンデーション システムのユニークな要素は、過去の行動やユーザー パターンに基づいて私たちの好みを理解し、予測する機能です。これらのシステムは、私たちの過去の選択を分析することで、カスタマイズされた提案を厳選し、私たちの時間と労力を節約しながら、私たちの興味に合ったコンテンツ/製品を紹介します。これにより、ユーザーの満足度が向上し、発見が促進され、他の方法では出会うことのなかった新しく関連性の高い製品が私たちに提供されます。
大まかに言えば、開発者は、これらのアルゴリズムが機械学習および深層学習システム (ニューラル ネットワークとも呼ばれます) によって強化されていることを理解していますが、ニューラル ネットワークを導入するという苦労をせずにレコメンデーション エンジンを構築する方法があると言ったらどうなるでしょうか。ネットそれとも機械学習モデル?
この質問は、モデルをトレーニングするための大量の構造化データを持っていないため、初期および中期のスタートアップのコンテキストに特に関連します。そして、すでにご存知のとおり、ほとんどの機械学習モデルは、適切なトレーニング データがなければ正確な予測を提供できません。
私は最近、基本的なレコメンデーション エンジンを構築してデプロイしました。
私は広範な
大まかに言うと、エンジニアリングの観点から次の要件がありました。
システムは、ユーザーの興味をキーワードの形で捉えることができる必要があります。システムは、ユーザーが特定のキーワードに対して持つ関心のレベルを分類できる必要もあります。
システムは、他のユーザーに対するユーザーの関心を捉えることができなければなりません。別のユーザーが作成したコンテンツに対するユーザーの関心のレベルを分類できる必要があります。
システムは、ユーザーの興味に基づいて高品質の推奨事項を生成できなければなりません。
システムは、ユーザーがすでに表示または拒否した推奨事項が X 日間再表示されないようにする必要があります。
システムには、同じ作成者からの投稿が同じページにグループ化されないようにするロジックが必要です。システムは、ユーザーが 10 件の投稿 (ページ サイズ) を利用する場合、それらすべてが異なる作成者によるものであることを保証するために最善を尽くす必要があります。
システムは高速でなければなりません。 P99 遅延は 150 ミリ秒未満。
高可用性、拡張性、セキュリティ、信頼性、保守性など、他のすべての非機能要件を満たす必要があります。
繰り返しますが、これは問題ステートメントの非常に単純化されたリストです。実際には、このレコメンデーション エンジンを既存のシステムに統合する際に発生する可能性のあるエッジ ケースやコーナー ケースも多数カバーしているため、ドキュメントは 3000 ワード以上の長さになりました。解決策に進みましょう。
問題の解決策を 1 つずつ説明し、その後、システム全体の全体的な動作について説明します。
このために、と呼ばれるものを作成しました。
上の画像からわかるように、インタラクション (いいね!、コメント、シェア) の数やこれらのインタラクションの最新性 (最後に発生した時期) など、多くの情報を 2 人のユーザー間の関係データとして、またユーザー間の関係データとして保存しています。ユーザーと興味。 2 つの異なる関心キーワード間の関係も保存しています。私が使用した
これらの興味のあるキーワードは主に名詞です。投稿内容をこれらのキーワード(名詞)に分解するシステムが整備されています。これはAWS comprehend を利用しています。機械学習を使用してテキストをエンティティやキー フレーズなどに分割する自然言語処理 (NLP) サービス。ここでも、マネージド NLP サービス (いくつか利用可能) を使用して同じことを実行できます。機械学習モデルを学習したりデプロイしたりする必要はありません。機械学習をすでに理解している場合は、確認してください。
次の図は、システムがどのように動作するかを概略的に示したものです。
上記は簡単そうに見えますが、各ステップではさらに多くの処理が行われており、システムが最適に動作するようにこれらのことを慎重に検討し、プログラムする必要があります。
段階的に説明しましょう:
これらの推奨事項を生成するには、まず投稿のコンテンツを次のようなものに変換する必要があります。
ベクター埋め込みを生成するには、ユースケースに応じて、OpenAI 埋め込みモデル、 Amazon titan 、または任意のオープンソーステキスト埋め込みモデルなどの著名な埋め込みモデルを使用できます。手頃な価格設定、パフォーマンス、操作の容易さのため、 Amazon Titanを選択しました。
さて、ここからが興味深いことになります。特定のビジネス ニーズに基づいてクエリを設計する必要があります。たとえば、特定のキーワードやユーザーとのエンゲージメントの数よりも、関心事項をクエリする際のエンゲージメントの最新性を重視します。また、複数の並列クエリを実行して、ユーザーのさまざまな種類の関心 (キーワードや他のユーザー) を見つけます。 1 人のユーザーに対して複数のフィードを生成するため、傾向に応じて特定のトピックを宣伝するクエリも実行します (たとえば、クリスマスが近づくとクリスマス関連の投稿が多く表示され、地震が発生した場合は地震関連の投稿が表示されます)。言うまでもなく、このトピックは、ユーザーが旅行の中でトピックにある程度の関心を示した場合にのみクエリ結果に表示されます。
したがって、ビジネス ユース ケースと推進したい動作に適したロジックを選択し、複数のクエリを実行して、ユーザーの関心事項すべてを含む十分な大きさのリストを取得します。
ベクトル データベースは主に、と呼ばれる特定の種類の検索を実行するために使用されます。
解決する必要がある問題の 1 つは速度であるため、データベースをキャッシュします。特定のユーザーの投稿の一意の ID を保存するために、 redisソート セットを使用しました。ユーザーのフィード内の投稿の順序が重要であるため、redis ソートセットを使用しました。また、解決しなければならないもう 1 つの問題は、「システムには、同じ作成者からの投稿が同じページにグループ化されないようにするロジックが必要である」ということです。同じ作成者からのコンテンツの繰り返しを避けるために、特定の作成者の投稿が特定のユーザーのフィード (並べ替えられたセット) 内の任意の位置に挿入された場合に、同じ作成者からの別の投稿が挿入されないことを保証する単純なアルゴリズムを作成しました。連続する 10 個の位置に対して (エンド ユーザーにフィードを提供する際のページ サイズは 10 なので、複雑さを避けるために静的なままにしました)。
ユーザーの特定の推奨の順序を決定するために、次のことを考慮しました。
このユーザーの特定の関心事 (または別のユーザー) との関係の強さ: ソーシャル グラフからさまざまなデータ ポイントを取得する算術式によって決定されます。これらはすべて、最後に作成された「いいね!」のタイムスタンプ、作成された「いいね!」の数、最後のコメントなどのエンゲージメント データです。ユーザーのエンゲージメント行動は、何かに対するユーザーの関心の指標です。
プラットフォーム上の投稿の人気度:これを決定するために、エンゲージメント、エンゲージメントとインプレッションの比率、エンゲージメントを行ったユニーク ユーザーの数などのさまざまな要素を考慮してエンゲージメント スコアを生成するアルゴリズムを作成しました。プラットフォームレベルで投稿します。
一部のフィードでは人気を優先します。また、ソーシャル グラフを優先する場合もあります。しかし、ほとんどの場合、それらはすべて 2 つの健康的な組み合わせです。
上の図からわかるように、システムは意図的に非常にシンプルに保たれています。システムの仕組みは次のとおりです -
ユーザー A が投稿を作成すると、投稿サービスはその投稿を保存した後、キューへのパブリッシュ/サブスクライブ イベントをトリガーします。このイベントは、候補生成用のバックグラウンド サービスによって受信されます。を使用しております
このバックグラウンド サービスはこれを非同期で受信し、プライバシー チェック、モデレーション チェック、キーワード生成など、前述した機能を実行してから、ベクトル埋め込みを生成してベクトル データベースに保存します。私たちが使用しているのは
メインの NoSQL データベースを更新した後、ユーザーがエンゲージメント (いいね!/コメント/共有など) を行うたびに、ポストサービスによってレコメンデーション エンジン サービスへのパブリッシュ/サブスクライブ イベントがトリガーされます。
このレコメンデーション エンジン サービスは、グラフ データベースを更新し、ANN 検索を実行して Redis データベースを更新することで、ほぼリアルタイムでユーザーの推奨フィードを更新します。したがって、ユーザーが対話すればするほど、フィードの質は向上し続けます。推奨事項が特定のキーワードのリストに偏っていないことを確認するためのチェックがあります。これらのチェックは、Graph データベースにクエリを実行するときに実行されます。このサービスはエンゲージメント スコアも非同期的に更新します。エンゲージメント スコアは、投稿を閲覧しているユーザーについても再計算されます。
上記の手順はすべてバックグラウンドで非同期に実行されるため、これらの計算はエンドユーザー エクスペリエンスに影響を与えません。
フィードは最終的にフィード サービスを通じてエンド ユーザーに提供されます。このサービスは Redis とメインの NoSQL データベースで検索を実行するだけなので (
いくつかのサービスが書かれています
私たちが使用しているのは
を使用しております
ご想像のとおり、これと同じ設定を微調整して、あらゆるユースケースに対応する基本的なレコメンデーション エンジンを構築できます。ただし、私たちのシステムはソーシャル ネットワークであるため、このシステムをより効率的にするために、将来的にはいくつかの調整が必要になります。
ユーザーに最も関連性の高いキーワードとユーザーを予測するには、ソーシャル グラフ レベルで機械学習/深層学習アルゴリズムが必要になります。非常に新しい製品であるため、現時点ではデータセットが小さすぎて何も正確に予測できません。ただし、データが増加するにつれて、現在の単純なクエリと数式を機械学習アルゴリズムの出力に置き換える必要があります。
さまざまなキーワードとユーザーの関係を微調整し、より細かくする必要があります。彼らは今、非常に高いレベルにいます。しかし、さらに深くする必要があるでしょう。まず推奨事項を絞り込むために、グラフ内の 2 次および 3 次の関係を調査する必要があります。
現在、埋め込みモデルの微調整は行っていません。近い将来それを行う必要があるでしょう。
このブログがお役に立てば幸いです。ご質問、疑問、ご提案がございましたら、お気軽にお問い合わせください。
ここでも公開されています。