インフラエンジニアからリサーチエンジニアに

中川裕太氏:今日はABEJAで提供しているリピーター推定機能に使っている、特徴量DBのおもしろさみたいなところを喋っていこうかなと思っています。

まず最初に自己紹介をします。ABEJAでリサーチエンジニアをやっている中川と言います。僕は20年ぐらいずっとソフトテニスをやってきているんですけど、そうした中で人間の動きのダイナミックさみたいなところにすごく魅せられて、「どうやったらそれをロボットで再現できるのかな」みたいなところに興味があって、学生時代はロボット工学をやっていました。そういった中で、いわゆる画像処理や機械学習みたいな文脈での研究もいろいろしていて、今につながってきている感じです。

就職してからはNTTデータでインフラエンジニアとして働いて、そこから3年前に新しいことをやりたいと思ってABEJAに入り、今4年目を迎えています。

今日はこれから、まず最初に我々が取り組んでいる特徴量DBの課題に触れさせてもらった上で、それに対して今はどんなアプローチをしているのか。未来にどんな研究をやっていきたいのか、という話をしていきたいと思っています。

特徴量DBとは何か

まず最初は、課題についてです。そもそも課題に入る前に「特徴量DBってなんやねん?」というところがあると思います。

我々は、こういった動画に示しているようなかたちで店舗にカメラを設置させていただいて、そこに写る人の顔をベースに、「その人が何回目の来店なのか」「それが男性なのか女性なのか」「どういった属性をもった方なのか」といった情報を取得することによって、店舗改善に役立てて、しいてはそのエンドユーザさん、実際に店舗を使われるお客様がよりよい購買体験ができるような、そんなベースとなるようなデータを作っていきたいなと思ってやっています。

ワークフローは、こんなかたちです。まず最初にインプットの動画があります。ここから顔を検出して、その顔を時系列に従って解析します。解析した結果、その時系列でトラッキングした、いわゆる特徴量というものを右上にあります球面上のものとマッチングします。溜まっている特徴量とマッチングすることによって、その人が何回目の来店なのかといったような分析を行っています。

そしてこのまさしく右上の、特徴量を溜めておいてさらにそこに対してクエリを掛けていくような、そんな部分を我々は特徴量DBと呼んでいまして、今日はそこら辺の課題について話していこうと思っています。

特徴量DBの速度の課題

今までもかれこれ1年ちょっと、この特徴量DBを運用してきているんですが、そうした中でぶつかってきた課題がこの3つかなと。まず1つ目が速度、2つ目が変更容易性、そして3つ目がトランザクションの競合といったものです。

それぞれ細かく見ていきます。まず最初の速度に関して。こちらは導入8ヶ月間の負荷のグラフです。非常におもしろい特徴として、こういったかたちで、例えばゴールデンウイークやお盆といったところにかなりシーズナルな巨大な負荷がきているところが見て取れるかなと思います。

それこそゴールデンウイークだと一気に負荷が10倍ぐらい掛かったりしていて、こうした急激な負荷にも耐えられるようにどんどん処理を高速化していきたいよねという課題がありました。

変更容易性の課題

ぶっちゃけて言うと、ゴールデンウイークであまりにも負荷が高くなって障害を起こしてお客様に迷惑をかけてしまったたこともあったので、次に負荷が高くなるであろうお盆の前には、なんとかアルゴリズムを改善したいところがありました。じゃあアルゴリズムを改善していこうかと思ったときに出てきた課題が2つ目(の「変更容易性」)です。

結局、アルゴリズムを変えるために、もろもろ変えていかないとならないわけですが、当時は本当に変更容易性が低くて、ここら辺が課題となってきていました。具体的に説明すると、もともとはそもそもサービスが売れるかどうかわからない状況だったので、データとロジックを共存させたようなモノリスで非常に簡単な作りになっていました。

この状況で何が起こるか。アルゴリズムを変更してデプロイします。それこそどんどん高速化するためにアルゴリズムを変えたいんですが、変えると再起動に1日掛かると。

データを読み込まないといけないので、これくらい時間が掛かってしまいまして……。つまりこの1日間は、お客様のシステムの解析を停めてしまうことになります。このフィードバックループを早く回せないのが非常に課題だよねというのが、2個目の変更容易性という課題です。

トランザクションの競合

この2つの課題を解決して、だいたい半年ぐらいですかね。運用してきた中でぶち当たったのが、3つ目のトランザクションの競合という課題です。

こちらに関して言うと、考えてみれば当然と言えば当然なんですけど、中央集権的な特徴量のデータベースがありまして、それに対して複数の機械学習のモデルからアクセスがいって、その特徴量を当てるみたいな構成でやっているんです。

これがマイクロサービスとしてできています。どんどん成長していって並列数が増えていくと、それこそ、国のガイドライン上、特徴量を半年間しか保持することしかできないので、その半年以内のリピーターも考えると、だいたい6割から7割が新規で、残りの3割から4割がリピーターみたいになっていました。当たり前と言えば当たり前です。

前提として、リピーターの問題は非常にwriteが多い系です。サービスが始まった当初はよかったんですけど、データベースだったら別に、普通だったらreadが多いよねというものと比べたらまったく正反対の特性をもっていて、かつ、並列数が高いところもあって、あるモデルから特徴量データベースにwriteが発生したタイミングで、他のモデルがreadしにいって、いわゆるファントムリードとかダーティリードみたいな不整合が生じてしまうみたいな課題が発生していました。

こういった課題をどう解決していったのかという話をここからしていこうと思います。

課題に対するアプローチ

それぞれの特徴量DBの課題に対してザクっとアプローチを言うと、まず最初の速度に関しては特徴量の工夫をしてきました。変更容易性の観点に関してはデータとロジックをきちんと分離することによって、ロジックだけ変更してどんどんフィードバックループを回していけるような状態を作りました。

最後のトランザクション競合に関しては、言ってもリピータのお客様がそんなに多数,頻繁にご来店されるわけではないというのがリピーターのもう1つの特性でもあるので、楽天的なロックで、ここはうまいところ回避してあげましょうみたいなかたちでやってきました。

今日の改善策というところは、最初の特徴量の工夫だけにしていこうかなと思っています。他の登壇者の方を見ていると、わりとシステムパターン寄りの方も多かったり、ちょっとそこら辺のバランスを鑑みて、今日はここを喋っていこうと思います。

もちろん他の2つについてもいろいろ喋れますので、ぜひ気になったところがあったらパネルディスカッションの際にご質問いただければと思います。

精度を下げずに高速化する

この特徴量の工夫に関して言うと、もともとは任意の人に紐づけるような特徴量をたくさんもっていて、それに対してすべて最近傍探索を行うような、とても愚直なアルゴリズムを実装していました。そういった中でこの速度を速めていきましょうといった段階で、リピーターでは非常に検索精度が求められるような前提がありました。

というのも結局、我々が対象にしているサービスは、だいたい10の6乗から7乗オーダーぐらいの母数があるので、それ分の1を当てていかないといけません。なかなかな検索精度が必要だよねという中で、近似を使うのではなくて、なるべくその検索対象を狭めてあげましょうみたいなアプローチを取ることにしました。

そういった中でどう絞っていったかというと、特徴量をvon-Mises Fisher分布に従うように学習させることをやりました。von-Mises Fisher分布では、球面上にマッピングされた特徴量の中で、ある人の特徴量は中心点の周りにある分散をもって分布しているようなものを考えます。

これに従うように学習させることによって、中心点がその人の特徴をまさしく表しているベクトルとなっていくので、これをオンラインで推定しながら使っていくのが精度上も速度上も妥当でしょう。というところで、これにより精度を下げることなく9.8倍の高速化を達することができました。

次なる研究テーマ

次にどんなことをやっていきたいのかという話をしていこうと思います。こちらは時間もないので一言で言うと、構造がなさそうな空間で、どう検索をスケールさせていくのかといったところが、次にやっていきたいおもしろいテーマかなと思っています。

このグラフはカメラの台数に対する必要なCPU数を表したものです。ぶっちゃけて言うと、CPUでぶん殴ればだいたいスケールすることが見えています。とは言えスケールアップには限界があるよねということと、スケールアウトしていったほうがお金も掛かりにくいみたいなところがあるので、ここら辺に取り組んでいきたいなと思っています。

でも、そもそもこの話をしている前提が、いわゆるvon-Mises Fisher分布に従って学習をしているからこそ、ある種、顔特徴量に構造がない状態になってしまっているので、問題なんじゃないか。そこで他の観点で「じゃあ構造って本当にないんだっけ?」というところを見ていくと、顔特徴量がある種、階層型の構造をもっているのではないかを示唆するような論文もあったりします。

例えば本当にこうした階層型の構造を、顔特徴量をもつように学習できるのであれば、それこそ、その階層型クラスタリングでかなり検索速度を速めることもできますし、それこそ、その階層のノードに従ってインフラを配置していくことによって容易にスケールアウトしていけるような構成もできるのかなと思います。

本当にこの特徴量データベースは、今までもいろいろな課題にぶつかってきましたが、これも掘れば掘るほどどんどん研究課題が出てきて、すごくおもしろい分野だと思っています。

それこそ特徴量をどう工夫するか、それに対して検索アルゴリズムをどうがんばるのか。そしてそれを支えるインフラはどうあるべきなのかみたいな、この3点から掘っていける、非常におもしろいテーマだと思っています。

このあとのパネルディスカッションを皮切りに、ぜひいろんな方とディスカッションをしながらここら辺を一緒に研究開発していけたらいいなと思っています。