3

私はRubyonRailsで一種のパーソナライズされた検索エンジンを開発しており、現在、ユーザーのレコードに応じて結果をリアルタイムで並べ替える最良の方法を見つけようとしています。

例:検索されるアイテムにはタグ(IDを持つ個別のエンティティ)を含めることができます。たとえば、アイテムにはtags = [1、5、10、23、45]があります。

一方、ユーザーは、特に関心のあるタグにフラグを付けている可能性があるため、ユーザーがtags = [5、23]を持っているとします。

結果の並べ替えに使用されるスコアは、ユーザーが「見つめている」アイテムのタグの数を考慮に入れる必要があります。たとえば、アイテムのスコアは、アイテムの属性に基づいて50%になり、ユーザーの(見つめられたタグの数)に応じてランクに基づいて50%になります。

一つのアイデアは、これを情報検索システムのソート機能に注入することでした。しかし、おそらく私が使用するSphinxでは、実装するのが非常に厄介です(ユーザーのベクトルが大きい場合)。Lucene / solrについてはわかりませんが、とにかく必要な高度な非テキスト検索機能(距離、日付、時刻など)がないようです。

他のオプションは、IRシステムから中間セットを取得し、それをアプリケーションレベルで処理することです。ただし、100〜1000レコードを順番に処理してから、Railsで並べ替えると非常に時間がかかると確信しています。

一方、並列処理が簡単なタスクのようです。1000レコードをセットに分割し、別々のスレッドで処理してから並べ替えます。

私はいくつかのマップリデュースの実装について読みました。hadoopのようなユニバーサルとskynetのようなレール固有の実装の両方ですが、リアルタイム処理ではなく、大規模なバッチジョブに最適です(私が間違っていない限り)。

これに使用できるメモリ内の軽量MR実装はありますか?それとも、それを処理する方法について他のアイデアがありますか?

(補足:この設定は、「Googleニュースのパーソナライズ:スケーラブルなオンライン協調フィルタリング」の論文から理解できるように、Googleニュースの仕組みに似ていると思います。これらは、一連の候補ストーリーと、ユーザーが属する一連のクラスターをリアルタイムで照合します。パーソナライズされた方法でストーリーを並べ替える(事前に計算された)

4

1 に答える 1

1

Map/Reduce はこの種の処理に最適ですが、中間テーブルを使用して SQL で処理できます。

おそらく、次のようなテーブルが既にあると思います。

ユーザー (id、...)
アイテム (id, ...)
タグ (id、...)
users_tags (user_id、tag_id)
items_tags (item_id、tag_id)

では、次のようなテーブルも維持してみませんか。

users_items_tags (user_id、item_id、tag_id)

ここで、各行は「このユーザーとこのアイテムがこのタグを共有している」ことを意味します。

次に、検索クエリは次のようになります。

  item_id, count(tag_id) をスコアとして選択
    users_items_tags から
   ここで、user_id = <USER_ID>
item_id でグループ化
スコア順

ユーザーがタグを追加すると、次のusers_items_tagsように更新されます。

users_items_tags に挿入 (user_id、item_id、tag_id)
     <USER_ID>、item_id、<TAG_ID> を選択
       アイテムタグから
      ここで、tag_id = <TAG_ID>

アイテムにタグを追加する場合も同様です。タグが削除されたら、タグとユーザー/アイテムを削除するだけです。

このソリューションにはいくつかの問題があります。特定のタグがアイテム間で共通である場合、ユーザーがそのタグを追加すると多くの書き込みが実行され、その逆も同様です。タグがアイテムとユーザーの両方で共通である場合、テーブルは非常に大きくなります。特定のデータセットについて、これらのケースを考慮する必要があります。

于 2008-12-05T07:46:33.527 に答える