見出し画像

『toridori base』レコメンドシステムのご紹介

はじめに

はじめまして、toridori開発部の大井といいます。

皆さんは、生存していますか?
冬の時代がやってきたということで、ご自身の生存性が怪しくなってきている方も多いと思います。
ぼくも鼻や皮膚の具合が悪くなったり、関節が痛くなったりしております。
状態がよろしくない方々は、ぼくと一緒に適切な医療機関にかかったり筋トレをしたりしながらなんとかこの冬を乗り越えていきましょう。

さて、この note に技術系の記事が上がるのは初めてだと思うのですが、この記事を端緒として今後は技術系の記事も増やしていきたいと考えています。
今回は弊社の『toridori base』というアプリで動いているレコメンドシステムのご紹介をしたいと思います。
ここでレコメンドアルゴリズムの話をされると思った方もいるかもしれませんが、本記事ではあえてレコメンドアルゴリズム自体には触れず、システム全体がどのように作られているかを紹介します。
これは、レコメンドシステム全体にとってレコメンドアルゴリズムはひとつの(しかし、とても重要な)機能にすぎないためです。

そもそも『toridori base』ってなに?

『toridori base』とは、インフルエンサーが広告のお仕事を探すためのアプリです。

画像1

インフルエンサーはこの中から案件を選んで、飲食店や美容系の店舗、あるいは郵送で送られてくる物品のレビューなどを行います。
以下では、インフルエンサーのことをユーザと呼ぶことにします。

『toridori base』アプリ上では、常時数百件の案件が表示されています。
その中には、リアル店舗の案件も含まれるため地域の合う合わないだとか、ユーザによって飲食系の案件しか基本的には受けないなど嗜好に合う合わないという観点で、ユーザにとって見る必要のない案件があります。
そういう状況でなるべくユーザが応募したいと思える案件を優先して表示してあげるために、レコメンドシステムが導入されています。

レコメンドシステム自体の達成すべき要件

それでは、そろそろ本題に入っていきます。
レコメンドシステムを作る理由は前節で解説したわけですが、それを見ると「ユーザ id を引数にとってオススメのアイテム id のリストを出力する関数」を実装すればそれだけでよいというふうに思えます。
しかし、Web サービスを運用したことがあるみなさんならお分かりの通り、それでは不十分です。
なぜならレコメンドシステムというのはいちど作ってしまえば完成というものではなく、サービスの状況が変われば内容の変更を行う必要があるし、また運用を続ける中でブラッシュアップしていくものだからです。
レコメンドシステムが満たすべき要件の一例を、以下に示します。

- 「ユーザ id を引数にとってオススメのアイテム id のリストを出力する」工程をいくつかに分け、それぞれについてひな形がある
    - レコメンドアルゴリズムに入れる前の事前処理、レコメンドアルゴリズム自体、レコメンドアルゴリズムからの出力の加工の 3 工程に分解、など
- それぞれの工程の組み合わせの AB テストが簡単にできる
    - 管理画面で組み合わせ作りと AB テストを一貫にできる仕組みを用意する
- それぞれの工程の追加や、同じ工程複数の組み合わせが簡単にできる
    - たとえば、複数のレコメンドアルゴリズムの結果を簡単に混ぜることができる
- バッチ処理を定期的に実行し、結果をどこかに格納できる
    - ログの集計や機械学習を定期的に行う
- 複数のサービスに対して、同じレコメンドシステムを使うことが出来る

このような要件を満たすレコメンドシステムを作ることによって、継続的にサービスの成長に寄与することができます。

toridoriにおけるレコメンドシステム

toridori のレコメンドシステムは、Python で実装された Batch 処理用のスクリプト(Muninn と呼んでいます)と、Go 言語で実装された gRPC サーバ(Fuginn と呼んでいます)、そして Vue.js で実装された管理画面(Fuginn Manager と呼んでいます)からなります。
Muninn は本番 DB やログ DB からデータを取得し Batch 処理を行って S3 にアップロードするだけのものなので、本記事では後者 2 つについて説明します。

Fuginn では、レコメンド工程を「ユーザ id を入力し、アイテム id 列を返す」アルゴリズムと、「アイテム id 列を入力し、アイテム id 列を返す」事後処理の 2 つに分けて考えています。
例を挙げて説明すると、アルゴリズムは「ユーザが最近評価した n アイテムに近いアイテム id 列を返す」や「ユーザが昔は評価していたが最近はあまり評価していないアイテム id 列を返す」などのことで、事後処理は「アイテム id 列を n 個ずつのチャンクに分け、各チャンク内で人気なもの順に並び替えて返す」とか「アイテム id 列からユーザが既に何回か見たものを除外して返す」などのことです。
また、「実装済みのアルゴリズムを複数組み合わせ、好きな割合で返す」アルゴリズムや、「複数の事後処理を順番に行ってから返す」事後処理も用意しており、複数の組み合わせにも対応しています。
このアルゴリズムや事後処理はインターフェースにのっとって簡単に追加することができるので、サービスの状況の変化に対応しやすい仕組みになっています。

Fuginn Manager では、Fuginn に実装されているアルゴリズムと事後処理を好きに組み合わせて、レコメンドルールを作ることができます。
アルゴリズムや事後処理のパラメータ(閾値や、どの学習済みモデルを用いるかなどのことです)もここで設定します。
各レコメンドルールを適用した場合、特定のユーザ id にはどのような出力が行われるのかの確認ができるので、様子を見ながらルールを調整していきます。

レコメンドルールを複数作ったら、それらをユーザに出し分けて AB テストすることができます。
レコメンドルール id はログまで伝播するような仕組みになっているので、どちらのレコメンドルールが良かったかの判断につながります(厳密にやるなら、AA テストを事前に済ませておくとよさそうです)。
事前にレコメンドルール別に主要 KPI を追いかけられるようなダッシュボードを作っておくといい感じでした。

おわりに

『toridori base』 では、このようなシステムを用いて AB テストを重ねることによってインフルエンサーによりよい案件を届けています。
細かい値の調整はコーディング不要で行えるところが好きで、自分で使っていても使いやすいシステムを作れたなという実感がありました。

前述したとおり、この note では今後も技術系の記事が更新されていく見込みですので、ご期待ください。


現在、開発部では新メンバーを大募集中です!

■アプリ開発(シニア)
■バックエンドエンジニア(シニア)
■フロントエンドエンジニア(シニア)

toridoriにご興味がある方は下記バナーからご応募お待ちしております!

画像2


この記事が気に入ったらサポートをしてみませんか?