46.6kデモを予約するログイン無料で始める

MilvusとPaddlePaddleの組み合わせによる推薦システムの候補生成の高速化

Nov 26, 20212 min read

もしあなたがレコメンダー・システムを開発した経験があるなら、少なくとも次のどれかの犠牲になっている可能性が高い:

  • 膨大なデータセットのため、システムが結果を返すのに非常に時間がかかる。
  • 新しく挿入されたデータを検索や問い合わせのためにリアルタイムで処理できない。
  • レコメンダー・システムの導入は困難である。

この記事では、オープンソースのベクトルデータベースMilvusとディープラーニングプラットフォームPaddlePaddleを組み合わせた商品レコメンダーシステムプロジェクトを紹介することで、上記の問題を解決し、何らかのヒントを提供することを目的とする。

この記事では、レコメンダー・システムの最小限のワークフローを簡単に説明する。そして、このプロジェクトの主なコンポーネントと実装の詳細を紹介する。

レコメンダーシステムの基本的なワークフロー

プロジェクト自体に深入りする前に、まずレコメンダーシステムの基本的なワークフローを見てみよう。レコメンダーシステムは、ユーザーの興味やニーズに応じてパーソナライズされた結果を返すことができる。このようなパーソナライズされた推薦を行うために、システムは候補の生成とランキングという2つの段階を経る。

図1](https://assets.zilliz.com/2_29e27eb9b1.png)

最初の段階は候補の生成であり、ユーザーのプロフィールに合致する製品やビデオなど、最も関連性の高い、あるいは類似したデータを返す。候補生成の間、システムはユーザーの特徴をデータベースに保存されているデータと比較し、類似したものを検索する。そして、ランキングでは、検索されたデータに点数を付け、並び替える。最後に、リストの上位にある結果がユーザーに表示される。

商品推薦システムの場合、まずユーザープロファイルと在庫商品の特徴を比較し、ユーザーのニーズに合った商品リストをフィルタリングする。次に、システムはユーザープロファイルとの類似性に基づいて製品をスコアリングし、ランク付けし、最終的にトップ10の製品をユーザーに返す。

図2](https://assets.zilliz.com/3_5850ba2c46.png)

システム・アーキテクチャ

本プロジェクトにおける商品推薦システムは、3つのコンポーネントを使用している:MIND、PaddleRec、Milvusである。

MIND

MINDは、「Multi-Interest Network with Dynamic Routing for Recommendation at Tmall」の略で、アリババグループが開発したアルゴリズムである。MINDが提案される以前、推薦のための一般的なAIモデルのほとんどは、ユーザーの多様な興味を表すために単一のベクトルを使用していた。しかし、単一のベクトルでは、ユーザーの興味を正確に表すには不十分である。そこで、MINDアルゴリズムは、ユーザーの複数の興味を複数のベクトルに変換するために提案された。

具体的には、MINDは候補生成段階において、一人のユーザーの複数の興味を処理するために、動的ルーティングを持つ多興味ネットワークを採用する。多関心ネットワークは、カプセルルーティングのメカニズム上に構築された多関心抽出器のレイヤーである。ユーザーの過去の行動と複数の興味を組み合わせることで、正確なユーザープロファイルを提供することができる。

以下の図は、MINDのネットワーク構造を示している。

図3.](https://assets.zilliz.com/4_9e6f284ea2.png)

ユーザーの特徴を表現するために、MINDはユーザー行動とユーザー興味を入力とし、それらを埋め込み層に送り込み、ユーザー興味ベクトルとユーザー行動ベクトルを含むユーザーベクトルを生成する。次に、ユーザー行動ベクトルを多関心抽出層に入力し、ユーザー関心カプセルを生成する。ユーザー関心カプセルをユーザー行動埋め込みと連結し、複数のReLU層を使って変換した後、MINDは複数のユーザー表現ベクトルを出力する。このプロジェクトでは、MINDは最終的に4つのユーザー表現ベクトルを出力すると定義している。

一方、商品特性は埋め込み層を通り、スパースな項目ベクトルに変換される。次に、各項目ベクトルはプーリング層を経て密なベクトルになる。

すべてのデータがベクトルに変換されると、学習プロセスを導くために、ラベルを意識したアテンション層が追加導入される。

PaddleRec

PaddleRecはレコメンデーションのための大規模検索モデルライブラリである。百度PaddlePaddleのエコシステムの一部である。PaddleRecは、簡単かつ迅速にレコメンデーションシステムを構築するための統合ソリューションを開発者に提供することを目的としています。

図4](https://assets.zilliz.com/5_35f7526ea7.png)

冒頭で述べたように、レコメンデーションシステムを開発するエンジニアは、ユーザビリティの低さやシステムの複雑な展開という課題に直面することが多い。しかし、PaddleRecは以下の点で開発者を支援することができます:

  • 使いやすさ:PaddleRecはオープンソースライブラリで、候補生成、ランキング、再ランキング、マルチタスクなど、業界で人気のある様々なモデルをカプセル化しています。PaddleRecを使えば、モデルの有効性を即座にテストし、反復によってその効率を向上させることができます。PaddleRecは分散システム用のモデルを優れたパフォーマンスで簡単にトレーニングする方法を提供します。疎なベクトルの大規模データ処理に最適化されています。PaddleRecは簡単に水平方向に拡張することができ、計算速度を高速化することができます。したがって、PaddleRecを使ってKubernetes上に学習環境を素早く構築することができます。

  • デプロイのサポートPaddleRecはモデルのオンラインデプロイメントソリューションを提供します。柔軟性と高可用性を特徴とし、トレーニング後すぐにモデルを使用することができます。

ミルバス

Milvusは、クラウドネイティブなアーキテクチャを特徴とするベクトルデータベースである。GitHub](https://github.com/milvus-io)でオープンソース化されており、ディープニューラルネットワークやその他の機械学習(ML)モデルによって生成された膨大な埋め込みベクトルの保存、インデックス付け、管理に使用できます。Milvusは、Faiss、NMSLIB、Annoyを含むいくつかのファーストクラスの近似最近傍(ANN)検索ライブラリをカプセル化しています。Milvusはお客様のニーズに応じてスケールアウトすることも可能です。Milvusサービスは可用性が高く、バッチ処理とストリーム処理を統合的にサポートします。Milvusは、非構造化データの管理プロセスを簡素化し、異なる導入環境においても一貫したユーザーエクスペリエンスを提供することをお約束します。以下のような特徴があります:

  • 膨大なデータセットに対してベクトル検索を行う際の高いパフォーマンス。

  • 多言語サポートとツールチェーンを提供する開発者優先のコミュニティ。

  • クラウドスケーラビリティと障害発生時の高い信頼性。

  • スカラーフィルタリングとベクトル類似検索の組み合わせによるハイブリッド検索。

Milvusは、システムの安定性を維持しながら、頻繁なデータ更新の問題を解決できるため、このプロジェクトでは、ベクトル類似性検索とベクトル管理に使用されている。

システム実装

このプロジェクトで商品推薦システムを構築するには、以下のステップを踏む必要がある:

1.データ処理 2.モデルのトレーニング 3.モデルのテスト 4.商品アイテム候補の生成 1.データ保存:学習済みモデルによってアイテム・ベクトルが得られ、Milvusに保存される。 2.データ検索:MINDによって生成された4つのユーザーベクトルがMilvusに入力され、ベクトルの類似性が検索される。 3.データランキング:4つのベクトルはそれぞれtop_k個の類似アイテムベクトルを持ち、4組のtop_k個のベクトルがランク付けされ、最終的にtop_k個の最も類似したベクトルのリストが返される。

このプロジェクトのソースコードはBaidu AI Studioプラットフォームでホストされている。以下はこのプロジェクトのソースコードの詳細である。

ステップ1.データ処理

元のデータセットは、ComiRecが提供するAmazon book datasetから来ている。しかし、このプロジェクトでは、PaddleRecからダウンロードし、PaddleRecで処理したデータを使用する。詳しくはPaddleRecプロジェクトのAmazonBook datasetを参照。

学習用のデータセットは以下のような形式を想定している:

  • Uid`:ユーザーID
  • アイテムID:item_id: ユーザーがクリックした商品のID。
  • Time: クリックされた時間:クリックされたタイムスタンプまたは順番。

テスト用のデータセットは、各列が以下のようなフォーマットで表示される:

  • Uid`:ユーザーID。

  • hist_item:過去のユーザークリックビヘイビアにおける商品アイテムのID。複数のhist_item` が存在する場合は、タイムスタンプ順にソートされる。

  • eval_item`:ユーザーが実際に商品をクリックした順序。

ステップ2.モデルトレーニング

モデル学習では、前ステップで処理されたデータを使用し、PaddleRec上に構築された候補生成モデルMINDを採用する。

1.モデル** 入力 **モデル

dygraph_model.pyにおいて、以下のコードを実行し、データを処理し、モデルの入力とします。この処理では、元データ中の同じユーザがクリックしたアイテムをタイムスタンプに従ってソートし、それらを組み合わせてシーケンスを形成します。そして、そのシーケンスからランダムにitem_idをtarget_itemとして選択し、target_itemより前の 10 個のアイテムをhist_itemとして抽出してモデル入力とする。seq_len には hist_item の実際の長さを指定する。

Python def create_feeds_train(self, batch_data): hist_item = paddle.to_tensor(batch_data[0], dtype="int64") target_item = paddle.to_tensor(batch_data[1], dtype="int64") seq_len = paddle.to_tensor(batch_data[2], dtype="int64") return [hist_item, target_item, seq_len].


元のデータセットを読み込むコードはスクリプト `/home/aistudio/recommend/model/mind/mind_reader.py` を参照してください。

#### 2.**モデルのネットワーキング

以下のコードは `net.py` の抜粋です。class Mind_Capsual_Layer` はインタレストカプセルのルーティングメカニズム上に構築されたマルチインタレストエクストラクタレイヤーを定義する。関数 `label_aware_attention()` はMINDアルゴリズムのラベルを意識したアテンション技術を実装している。クラス MindLayer` の `forward()` 関数はユーザの特徴をモデル化し、対応する重みベクトルを生成する。

パイソン
class Mind_Capsual_Layer(nn.Layer):
    def __init__(self):
        super(Mind_Capsual_Layer, self).__init__()
        self.iters = iters
        self.input_units = input_units
        self.output_units = output_units
        self.maxlen = maxlen
        self.init_std = init_std
        self.k_max = k_max
        self.batch_size = batch_size
        # B2Iルーティング
        self.routing_logits = self.create_parameter(
            shape=[1, self.k_max, self.maxlen]、
            attr=paddle.ParamAttr(
                name="routing_logits", trainable=False)、
            default_initializer=nn.initializer.Normal(
                平均値=0.0, 標準偏差=self.init_std))
        # バイリニアマッピング
        self.bilinear_mapping_matrix = self.create_parameter(
            shape=[self.input_units, self.output_units]、
            attr=paddle.ParamAttr(
                name="bilinear_mapping_matrix", trainable=True)、
            default_initializer=nn.initializer.Normal(
                mean=0.0, std=self.init_std))
                
class MindLayer(nn.Layer):

    def label_aware_attention(self, keys, query):
        weight = paddle.sum(keys * query, axis=-1, keepdim=True)
        weight = paddle.pow(weight, self.pow_p) # [x,k_max,1].
        weight = F.softmax(weight, axis=1)
        output = paddle.sum(keys * weight, axis=1)
        return output, weight

    def forward(self, hist_item, seqlen, labels=None):
        hit_item_emb = self.item_emb(hist_item) # [B, seqlen, embed_dim].
        user_cap, cap_weights, cap_mask = self.capsual_layer(hit_item_emb, seqlen)
        if not self.training:
            return user_cap, cap_weights
        target_emb = self.item_emb(ラベル)
        user_emb, W = self.label_aware_attention(user_cap, target_emb)

        return self.sampled_softmax(
            user_emb, labels, self.item_emb.weight、
            self.embedding_bias), W, user_cap, cap_weights, cap_mask

MINDのネットワーク構造については、スクリプト /home/aistudio/recommend/model/mind/net.py を参照してください。

3.**モデルの最適化

このプロジェクトでは、モデル最適化としてAdam algorithmを使用します。

パイソン def create_optimizer(self, dy_model, config): lr = config.get("hyper_parameters.optimizer.learning_rate", 0.001) optimizer = paddle.optimizer.Adam( learning_rate=lr, parameters=dy_model.parameters()) オプティマイザを返す


さらに、PaddleRecは`config.yaml`にハイパーパラメータを書き込むので、このファイルを修正するだけで、2つのモデルの効果を明確に比較することができ、モデルの効率を向上させることができる。モデルをトレーニングする際、モデルの効果が低いのは、モデルのアンダーフィットやオーバーフィットが原因である可能性があります。したがって、トレーニングのラウンド数を変更することで改善することができます。このプロジェクトでは、`config.yaml`のパラメータepochsを変更するだけで、最適な学習ラウンド数を見つけることができる。さらに、デバッグのためにモデルのオプティマイザや`optimizer.class`、`learning_rate`を変更することもできる。以下に `config.yaml` のパラメータの一部を示す。

YAML
ランナー:
  use_gpu: True
  use_auc: False
  train_batch_size: 128
  エポック数: 20
  プリント間隔: 10
  model_save_path:"output_model_mind"

# ユーザー定義ネットワークのハイパーパラメータ
hyper_parameters:
  # オプティマイザ設定
  オプティマイザ
    クラス:アダム
    learning_rate:0.005

詳しい実装はスクリプト /home/aistudio/recommend/model/mind/dygraph_model.py を参照してください。

4.**モデルのトレーニング

以下のコマンドを実行し、モデルの学習を開始します。

Bash python -u trainer.py -m mind/config.yaml


モデルのトレーニングプロジェクトは `/home/aistudio/recommend/model/trainer.py` を参照してください。

### ステップ 3.モデルのテスト

このステップでは、テストデータセットを使用して、学習したモデルの再現率などの性能を検証します。

モデルのテストでは、全ての項目ベクトルがモデルからロードされ、オープンソースのベクトルデータベースであるMilvusにインポートされる。home/aistudio/recommend/model/mind/mind_infer_reader.py`スクリプトを通してテストデータセットを読み込む。前のステップでモデルをロードし、テストデータセットをモデルに送り込み、ユーザーの4つの関心ベクトルを得る。Milvusで4つの興味ベクトルと最も類似した50のアイテムベクトルを検索する。返された結果をユーザに推薦することができます。

以下のコマンドを実行してモデルをテストする。

```Bash
python -u infer.py -m mind/config.yaml -top_n 50

モデルのテスト時には、Recall@50、NDCG@50、HitRate@50など、モデルの有効性を評価するための指標がいくつか提供されます。この記事では1つのパラメーターの変更のみを紹介します。しかし、あなた自身のアプリケーションシナリオでは、より良いモデル効果を得るために、より多くのエポックを訓練する必要があります。 また、異なるオプティマイザを使用したり、異なる学習レートを設定したり、テストのラウンド数を増やしたりすることで、モデルの効果を向上させることができます。異なる効果を持つ複数のモデルを保存し、最もパフォーマンスが高く、アプリケーションに最適なモデルを選択することをお勧めします。

ステップ4.商品アイテム候補の生成

商品候補生成サービスを構築するために、このプロジェクトでは、前のステップで学習したモデルをMilvusと組み合わせて使用します。候補生成の際には、FASTAPIを使用してインターフェースを提供する。サービスが起動すると、ターミナルで curl を介して直接コマンドを実行することができる。

以下のコマンドを実行して予備候補を生成する。

``Bash uvicorn main:app


このサービスは4種類のインターフェースを提供する:

- 挿入** :以下のコマンドを実行して、モデルからアイテムベクトルを読み込み、Milvusのコレクションに挿入します。

``Nginx
curl -X 'POST'
  'http://127.0.0.1:8000/rec/insert_data' \
  -H 'accept: application/json'  \ -d ''
  -d ''
  • 予備候補を生成する:ユーザーがクリックした商品の順番を入力し、次にクリックする可能性のある商品を調べます。複数のユーザーの商品アイテム候補を一括で生成することもできます。以下のコマンドの hist_item は2次元ベクトルで、各行はユーザーが過去にクリックした商品の列を表します。シーケンスの長さを定義することができる。返される結果も2次元ベクトルの集合であり、各行はユーザーの item id を表します。

``Ada curl -X 'POST' 'http://127.0.0.1:8000/rec/recall'
-H 'accept: application/json' ¦ -H 'Content-Type: application/json -H 'Content-Type: application/json'
-d '{ "top_k":50, "hist_item":[[43,23,65,675,3456,8654,123454,54367,234561],[675,3456,8654,123454,76543,1234,9769,5670,65443,123098,34219,234098]] }'


- 商品アイテムの総数を照会します:以下のコマンドを実行し、Milvus データベースに保存されている商品ベクトルの総数を返します。

``Nginx
curl -X 'POST'
  'http://127.0.0.1:8000/rec/count' \
  -H 'accept: application/json'  \ -d ''
  -d ''
  • 削除以下のコマンドを実行し、Milvusデータベースに保存されているすべてのデータを削除する。

``Nginx curl -X 'POST' 'http://127.0.0.1:8000/qa/drop'
-H 'accept: application/json' \ -d '' -d ''


ローカルサーバーで候補者生成サービスを実行している場合は、`127.0.0.1:8000/docs`で上記のインターフェースにアクセスすることもできる。つのインターフェイスをクリックし、パラメーターの値を入力して遊んでみてください。その後、"Try it out "をクリックすると、推奨結果が表示されます。

図5](https://assets.zilliz.com/6_43e41086f8.png)

図6.](https://assets.zilliz.com/7_f016a3221d.png)


## 総括

本稿では主に推薦システム構築における候補生成の第一段階に焦点を当てた。また、MilvusとMINDアルゴリズムとPaddleRecを組み合わせることで、このプロセスを高速化する解決策を提供し、冒頭で提案した問題に対処している。

膨大なデータセットのために、システムが結果を返すときに極端に遅いとしたら?オープンソースのベクトルデータベースであるMilvusは、数百万、数十億、あるいは数兆のベクトルを含む高密度のベクトルデータセットに対して、驚くほど高速な類似性検索ができるように設計されている。

新しく挿入されたデータが検索やクエリのためにリアルタイムで処理できない場合はどうすればよいでしょうか?Milvusはバッチ処理とストリーム処理を統合的にサポートし、新しく挿入されたデータをリアルタイムで検索、クエリすることができます。また、MINDモデルは新しいユーザーの行動をリアルタイムに変換し、ユーザーベクトルを瞬時にMilvusに挿入することができます。

複雑なデプロイは敷居が高いと感じたら?PaddlePaddleエコシステムに属する強力なライブラリであるPaddleRecは、レコメンデーションシステムやその他のアプリケーションを簡単かつ迅速に展開するための統合ソリューションを提供します。


## 作者について

ZillizのデータエンジニアであるYunmei Liは、華中科技大学でコンピュータサイエンスの学位を取得。Zillizに入社して以来、オープンソースプロジェクトMilvusのソリューションを模索し、ユーザーがMilvusを実世界のシナリオに適用できるよう支援している。主にNLPとレコメンデーションシステムを研究しており、この2つの分野をさらに深めたいと考えている。一人で過ごす時間と読書が好き。


## 他のリソースをお探しですか?

- レコメンダーシステム構築のユーザー事例をもっと見る:
  - VipshopとMilvusによるパーソナライズされた商品推薦システムの構築](https://milvus.io/blog/building-a-personalized-product-recommender-system-with-vipshop-and-milvus.md)
  - Milvusでワードローブと衣装計画アプリを構築する](https://milvus.io/blog/building-a-wardrobe-and-outfit-planning-app-with-milvus.md)
  - 捜狐ニュースアプリ内のインテリジェントなニュース推薦システムの構築](https://milvus.io/blog/building-an-intelligent-news-recommendation-system-inside-sohu-news-app.md)
  - 音楽推薦システムのためのアイテムベース協調フィルタリング](https://milvus.io/blog/music-recommender-system-item-based-collaborative-filtering-milvus.md)
  - Milvusで作る:XiaomiのモバイルブラウザにAIを搭載したニュース推薦](https://milvus.io/blog/Making-with-Milvus-AI-Powered-News-Recommendation-Inside-Xiaomi-Mobile-Browser.md)
- 他コミュニティとのコラボレーションによるMilvusプロジェクトをもっと見る:
  - ONNXとMilvusを用いた画像検索のためのAIモデルの組み合わせ](https://milvus.io/blog/2021-09-26-onnx.md)
  - Milvus、PinSage、DGL、Movielensデータセットによるグラフベースの推薦システムの構築](https://milvus.io/blog/graph-based-recommendation-system-with-milvus.md)
  - JuiceFSに基づくMilvusクラスタの構築](https://milvus.io/blog/building-a-milvus-cluster-based-on-juicefs.md)
- 私たちのオープンソースコミュニティに参加してください:
  - GitHub](https://bit.ly/307b7jC)でMilvusを見つける、または貢献する。
  - フォーラム](https://bit.ly/3qiyTEk) を通じてコミュニティと交流する。
  - ツイッター](https://bit.ly/3ob7kd8)









Updated on Jul 09, 2026