この記事は Retty Advent Calendar 2017 25日目です.
昨日は @shinyorke さんの 予約導線をささえるPython製バックエンドをLuigi+pandas+Scrapyで作ったハナシ でした.
みなさん、こんにちは。Retty CTO の樽石です。
昨年は、深層学習が大きく広がり始めた年ということもあり、当社で独自開発した「機械学習基盤」のアーキテクチャについて紹介させていただきました。ご好評いただき誠にありがとうございました。
今年は、深層学習の普及を背景に、 AI というキーワードが社会にも浸透。活用事例も増えていることから、AI によって「今」なにが出来、どう便利になるかを具体的に示すことが、AIを活用するサービス事業者に求められる1年だったと思います。
そこで、今年のカレンダーは、先進性や芸術性、未来感といったセンセーショナルな内容からはいったん離れ、少し現実的に、2017 年の Retty が AI によってどのように進化したかを、実例を用いて紹介させていただければと思います。
※ 記事で引用した写真はRettyユーザーさんの著作物です。
2017 年の Retty の進化
Retty は「食を通じて世界中の人々を Happy に」というビジョンのもと、ユーザーさんに BEST な外食体験を提供できるよう、サービスの開発を行っています。
そんな中、2017年に Retty エンジニアリングチームが最も重視して取り組んできたこと。それは、ユーザーさんが Retty を使ってお店を「探せる」こと、そして、掲載されているお店の良さがユーザーさんに「伝わる」ことです。
「お店が探せる」こと
飲食店の情報はインターネット黎明期から存在し、条件絞り込みやマッチング、統計解析などの成熟したテクノロジーを活用することで、オススメ飲食店の検索システムを実現することが出来ます。昨年まで、Retty Web 上での飲食店検索は、サービス開始初期の頃に作成した簡易的なものしかなく、使い勝手などについてご意見をいただくことが多く、ご不便をおかけしておりました。
そのような状況の中、今年、ついに Web 上における検索機能を大幅にリニューアル、「条件検索」機能が格段に使いやすくなりました。
この検索機能開発の裏側においては、「こちら」の記事をご覧いただければと思いますが、今回の検索機能開発において技術的視点と共に、サービスの操作性にこだわりました。操作性が悪いと、飲食店を探すのが苦痛になり、お店を見つける前にユーザーさんがお店を探すのを諦めてしまうと考えたからです。
そこで、操作性を良くするための、さまざまな UI/UX デザインやプランニングが行われたわけですが、当然要件が増えればそれを実現することは難しくなっていきます。
そのため、Rettyでは複雑な要件をシンプルに開発できるようフロントエンド開発基盤の整備を行いました。具体的には、ViewModel などの開発パターンやフレームワークの Web フロントエンドへの導入、BrowserSync・ホットリロードによる開発生産性の向上、モジュール化することによる再利用性の向上、人間用JS を黒魔術JSに変換する TransCompiler の導入といった、最新のフロントエンド開発技術を積極的に採用しています。
特に、ECMAScript は、コールバック祭り問題を解決する async/await の導入など、大きな変革の時を迎えており、今後が楽しみな領域です。
「お店の良さが伝わる」こと
もうひとつの大きなテーマに、Retty でお店を探しているユーザーさんに、お店の良さをどう伝えるかというものがあります。
私自身も、一見すると入るのがものすごく拒まれるお店がなぜか何年も営業していて、意を決して入ってみたところすごく美味しく、なぜもっと早く挑戦しなかったのだろうと後悔した経験があります。このようにせっかくの良いお店もその良さが伝わらないと、お店が見つかる状態にはなりません。
すなわち「探していたものは実はそもそも既に目の前にあって、ただ気づいていなかっただけ」という状態を解決することが「お店を探す」機能と同様に重要です。ここでは、2017 年にRettyが取り組んだもののうち、3つご紹介したいと思います。
良い写真
Retty には一般ユーザーさんが投稿する数千万枚の写真があり、それをもとに、お店情報を作成しています。ところが、これらの膨大な写真の中からそのお店の良さを伝える写真を見つけ出すことは、容易ではありません。以前は、お店の良さが伝わる写真を、クラウドソーシングやシンプルなユーザー行動の分析によって探しておりましたが、選定スピードや精度が安定せず、サービスの品質の改善にはあまり効果がありませんでした。
そこで、Rettyのエンジニアリングチームは、この問題解決のために立ち上がり、「ユーザーさんが投稿した、膨大で多様な写真から良い写真を見つけるAI」を作り、お店の良さを伝えられるようにしようと開発に取り組みました。その結果がこちらです。
![](https://img.retty.me/img_repo/l/01/2160652.jpg) Photo by 東京カレンダー他にもたくさんの良い写真が見つかりました。ここではその一部をお見せします。
良い写真一覧
写真引用元はこちら: 1
- https://retty.me/area/PRE13/ARE16/SUB1601/100000087246/2646548/
- https://retty.me/area/PRE13/ARE9/SUB901/100000704241/2661305/
- https://retty.me/area/PRE13/ARE20/SUB2001/100000038242/2785116/
- https://retty.me/area/PRE13/ARE2/SUB201/100000881936/2758189/
「良い」の定義は極めて感覚的で、精度検証が難しいのですが、現在は、社内アンケートと、ユーザーさんの行動から精度を判定しています。
赤の線が、AIが見つけた良い写真にユーザーさんがどれぐらい興味を持ったかを示す指標です。 良い写真をお店TOPページなどに公開した日を境に急激に赤の数値が伸びたことがわかります。
キャッチコピー
また、その他にもお店の良さが伝わる様々な工夫をしています。そのひとつ目が、お店キャッチコピーの表示です。
![a19c8891-3ed7-84b4-0758-15cda321eac0.png](https://qiita-image-store.s3.amazonaws.com/0/63371/4c381e3a-d9cd-ddb1-c069-50c166857db4.png)こちらのコンテンツは最新の口コミ分析AIを活用した、 渋谷のおすすめ電源カフェまとめ記事です。ぜひ実際に中身を見て欲しいのですが、こちらのコンテンツはすべてのお店にそのお店がどんなお店かがわかるキャッチコピーが付いています。以下のような感じです。
- 電源ありWi-Fi完備、作業やミーティングに最適なお洒落カフェ
- 渋谷ロフト2F、Wifi 電源 完備に500冊以上の本読み放題の便利カフェ
- 電源・Wifiあり、仕事もサッカー観戦も出来る、素敵なカフェバー
- ...
いかがでしょうか? 渋谷の電源カフェを探している方の文脈にあったキャッチコピーを表示することで、お店の詳細を見なくてもどういったお店なのかを把握できるようになったのではないでしょうか?
もうひとつ別の例をお見せします。こちらは渋谷のワンコインランチのおすすめまとめ記事です。
![ea3874d5-cbbd-7fd9-4e48-d0df7252a160.png](https://qiita-image-store.s3.amazonaws.com/0/63371/986b1063-b70a-4459-a8e6-358435a5b5a7.png)- ワンコインランチも人気の究極の焼き鳥ビストロ
- 美味い、お手頃価格、接客も◎!かなりパーフェクトなお店
- 高級和牛の端肉を使ったボロネーゼがリーズナブルに食べられるパスタ屋さん
- ...
このように、コンテンツのキーワードそのもではないが、その文脈にあった単語がうまく散りばめられており、文章が単調にならず、自然にキャッチコピーが頭に入りやすくなるようになっているのではないでしょうか?
お店ラベル
とはいえ、キャッチコピーのような文章だと、読むこととに時間がかかる欠点もあります。そこで、さらに、もっと簡単にお店の特徴がわかるようにするために、このお店のどんな点をみんなが良かったと口コミしているかを分析し、それをお店ラベルとして、表示しています。このお店の場合、「電源」、「勉強」、「長居」、「ソファ」で「良かった体験」をしていることがわかります。
このように、2017年のRetty は「お店の良さ」が伝わるようなコンテンツ作りを、AI 技術などを活用することで実現してきました。
アプリ
Retty は、iOS アプリを 2017/11 にメジャーバージョンアップ(Retty V4) しておりますが、今回のアプリ・リニューアルにおいても、「お店が探せる」機能、「お店の良さが伝わる」機能が強化されています。
詳細については、実際にアプリを使っていただくのが良いと思いますので、https://itunes.apple.com/jp/app/retty/id473919569 からアプリをインストールして使ってみていただけると幸いです。
さて、このカレンダーはエンジニア向けの記事ですので、ここでは、Retty V4 で採用された面白い技術的試みについて、紹介させていただきます。今回の iPhone リニューアルでは、ステート管理機構の刷新、Swift の全面採用、および API 呼び出しライブラリの自動生成ツールの開発に力を入れました。具体的には、Redux を使って、アプリのステートを巨大なシングルトンオブジェクトで管理するようにしたり、ReactNative を使って、js と Native アプリの共存を行ったり、API呼び出し部分をサーバサイドの JAX-RS アノテーションをパースすることで自動で作成したりするといったことを行っています。これらの詳細については、追々紹介させていただければと思います。
また、お店検索においては、機械学習を使ってリコメンデーションの仕組みを実現しています。
リコメンデーションの仕組みというと協調フィルタリングなどのアルゴリズムが良く知られていますが、今回はdoc2vec を応用した別の仕組みによって実現しております。
コンテンツが「信頼できる」こと
もうひとつ Retty エンジニアリングチームが 2017年に注力した取り組みに、「Rettyの口コミが信頼され続ける」ための技術開発があります。2017年は、コンテンツの信頼性が大きな社会問題に発展したことで、あらためて情報の信頼性が問われた1年だったのではないでしょうか?
Retty は創業当初から、情報の信頼性を重要視してきました。その大きな柱として「口コミが実名であること」を重視しておりますが、その他にも情報の信頼性を保つさまざまな技術や仕組みを構築しています。ここでは、その一部について紹介させていただければと思います。
###「社会的関係における情報発信」
ひとつ目は、投稿者本人の社会的関係を活用し、投稿が責任をもった内容になるように工夫している点です。Retty では、Facebook などのソーシャルアカウントを使った友人・仕事関係や、 Retty での食事イベントなどを通じてお互いが知り合うことによる社会的関係が構築されます。Rettyで投稿をすると、その投稿内容はそれらのつながりのある人たちへのオススメになります。このように、Rettyの飲食店情報投稿を、自分の身近な人にオススメしてもらうことで信頼性の高い投稿になるように促しています。
###「User Happy の連鎖」
もうひとつは、飲食店の「良かった体験」が別の人の「良かった体験」に繋がっているかを分析する AI の開発です。
外食ニーズは非常に多様で、「食の好みによる違い」、「目的の違い」といった様々な理由から「あるひとつの良かった体験」が必ずしも「別のシーンでの良かった体験」に繋がらないことがあります。そこで、Retty では、口コミの文脈と、それがソーシャル上でどのように支持されたのかを解析し、ある口コミがどのような文脈で価値があるか判定できるデータベースを作っています。
もう少し説明します。Retty では、「口コミ」に対して、「行きたい」という宣言をすることが出来ます。そして、行きたいを宣言したユーザーさん自身も、そのお店に対して、口コミ投稿ができるので、これを多く集めると、「口コミ」->「行きたい」->「口コミ」という口コミの連鎖構造を作ることが出来ます。この構造を分析することで、口コミがソーシャル上でどのように支持されているかがわかります。
機械学習基盤の進化
昨年、ご好評いただきました当社の機械学習基盤ですが、その後、どうなったか興味のある方もいらっしゃるかもしれません。そこで、現在の当社の機械学習基盤について簡単にですが、紹介させていただこうと思います。
基本的な構成はそれほど変わっていない
進化とは書きましたが、重要な機能は 2016 年にほぼ作りきったため、基本構成はそれほど変わっていません。Kubernetes による開発用 docker にエンジニアが ssh ログインして使う構成です。
今年はこの構成に大きく以下の変更が加わりました。
- 最新環境への追従
- Tesla 搭載サーバによる機械学習
- Dockerfile による学習
最新環境への追従
最先端の機械学習開発環境は進化が非常に早く、最新のソフトウェアを導入しても、すぐに古くなってしまいます。
Retty の機械学習基盤は apt-get upgrade によるソフトウェアのホットアップデート、およびノードの完全自動再セットアップに対応しているため、最新の状態に毎日追従することが出来ます。
いきなり仕様が変わって(tensorflow で引数の呼び出し順番が変わるなど)、混乱したこともありましたが、一回の仕様変更はそれほど多くなく、対応可能だったため、特に業務上大きな支障につながることはありませんでした。むしろ、最新の便利な機能が使えて喜ばれて(?)いるようです。
Tesla 搭載サーバによる機械学習
NVIDIA 制 Tesla GPU P100 を搭載した Dell のサーバ機 R730 を導入し、利用しています。Xeon 2ソケット搭載、 32 コアにより、CPUをたくさん使う処理も高速に行うことが出来、最近はこのサーバを使って学習を行うことが多くなりました。
Dockerfile による学習・および分類
学習ロジックのパッケージ化に、Dockerfile を使うものが多くなりました。Dockerfile を git に保存すれば、docker build だけで学習できるため、チーム開発の生産性があがりました(ただし、docker build 内では GPU が使えないため、CPU で学習するロジックが大半です。GPUを使いたい場合は dockerfile の外でいったん学習させたあとに学習済みモデルを docker 内に同梱させます)。
Dockerfile をつかった機械学習ロジックのパッケージ化の最大のメリットは学習済みモデルの呼び出し方が他のマイクロサービス群と統一されることで、他のエンジニアが簡単にサービスに活用できるようになる点です。特に、学習後の分類機能は、入力に対して、feed forward で出力を計算すれば良いだけなので、入力毎に分散処理しやすく、マルチコア CPU 環境で処理してもスループットとしてはそれほど性能に問題が出ません。 加えて、Docker + Kubernetes 環境では、大量のCPUコアをつかってコンテナをスケールさせるのが簡単で、コモディティ化している CPUだけのインスタンスでサービス稼働が可能になります(ただし、latency は遅くなるのでリアルタイム処理では注意が必要です)。t2 インスタンスでも稼働できます。
まとめ
以上、簡単ではありますが、AI を活用した 2017 年の Retty の進化について概要を紹介させていただきました。
今年は、「お店の良さが伝わること」という非常に大きなチャレンジに対し、AIを活用することでいくつかの新機能を提供することが出来ました。とはいえ、課題も多く残されています。
例えば良い写真の発見AIを作っていた時、麻婆豆腐の写真が良い写真であるか、そうでないかの議論が発生しました。ある人は「メチャ良い写真!」と答えたのに対し、別の人は「おっ!とはならなかったです」と答えました。
その原因を調べてみたところ、「メチャ良い写真!」と答えた人は辛いものが好きな人で、「おっ!とはならなかったです」と答えた人は辛いものが苦手な人でした。
このように、良い写真かどうかは、その人が写真に映っている料理が好きかどうかも関わっており、一概に良い写真を決めることは難しいことになります。
この機会にみなさんも「良い料理写真」とはなにか?について考えを巡らせてくれたら幸いです。
それでは本年もRettyをご利用くださったみなさまに感謝して、今年のカレンダーを終わりにしたいと思います。