インターン参加報告:Word2vecによるページ掲載店舗の検索結果とページ生成スケーラビリティの向上

こんにちは。
今年の1月7日から1月18日までの約2週間、Rettyでエンジニアとしてインターンをさせていただきました、ボストン大学3年の小林です。

インターンを終え、大学に戻って約3週間が経ちますが、この冬のRettyでの経験がその後の大学生活に少なからず良い影響を与えていると感じており、また自分自身での振り返り、今後Rettyでのインターンを考えている方への紹介も兼ねて、今回、Retty Tech Blogにインターン体験談を書かせていただきます。

自己紹介

The Social Networkという映画を観たのがきっかけで、現在はFacebookが生まれた地、米国ボストンでコンピューターサイエンスと哲学を勉強しています。ちなみに今学期は、授業としては、関数型言語であるHaskellを入り口としたプログラミング言語の仕組みについての授業、MASONなどを用いたシミュレーションの授業、統計・確率、マクロ経済学倫理学などを取っていて、研究としては自然言語処理機械学習の最適化について、また趣味ではWebサービスやモバイルアプリの開発を行っています。
それ以外に、最近はアートや文学などの芸術方面にも興味が湧いており、将来的にはエンジニアリングやビジネスに留まらず、政治・経済・哲学・文学・芸術など多種多様な領域で動いていきたいと思っています。

なぜRettyなのか

今回インターンに参加した理由としては、Rettyの企業理念である、

食を通じて世界中の人々をHappyに

というビジョンに共感したというところが一番大きいです。日本が世界に誇る文化の一つである"食"という領域を、日本から世界に向けて発信していこうという姿勢は、非常に価値のあるものであると感じます。

また、Rettyの採用ページや過去のインターンに関する記事などを読んだところ、自分のやりたいことや興味のあることに打ち込めるサポート体制が整っており、企業でしか持ち得ない価値のある密なデータをある程度自由に扱うことができる環境であると感じたため、今回短期間ながらもインターンをすることに決めました。

インターン中のタスク

自然言語処理の分野に興味があったので、実際にそれらの技術を使った業務はないかという相談をしました。話し合いの結果、お店まとめサービスである、Rettyテーマページの生成に検索式が必要なのですが、ここにWord2vecが使えそうだ、ということでインターンの方向性が決まりました。

具体的な概要・目的

そもそもなぜこのタスクをやる価値があるのか、ということについてはタスク自体に取り掛かる前に自分の中で明確に言語化しておく必要がありました。今回のタスクの目的を一言でまとめると、

Rettyテーマページ内部の検索式生成の(半)自動化

です。

Rettyテーマページは、以下のようにテーマ (e.g. 渋谷の500円ランチ)とそれに関連するお店のリストから構成されているのですが、このお店のリストを生成するためには検索インデックス(DB)にクエリを投げて条件に合致したデータを取ってくる必要があります。これまではその検索式を手動で書いていたのですが、今後ページ数 (つまりテーマの種類)を増やしていくにあたって、手動では厳しくなりそうということもあり、今回、少なくとも半自動で検索式を生成できる仕組みを考案することになりました。つまり、ページ数を1万から100万にスケールするとなった際に必要となる、スケーラビリティー向上のためのツールであるといえます。

retty.me

今回のタスクの大まかな流れを簡単な図で表すと以下のようになります。

f:id:rettydev:20190218151840p:plain

ツールの選択

手動での検索式生成のもう一つの大きな問題点として、検索したいキーワードがあったとして、検索式を生成する際にはそれに近いキーワードなども推測して含めてあげる必要がありました。
例えば、「和食」というキーワードを考えた際に、それが「寿司」なのか「カツ丼」なのか「懐石料理」なのかといった具合に、そのキーワードの言い換えや具体化をしてあげないと、理想的な検索結果が得られずテーマページ (i.e. まとめページ)の存在価値がなくなってしまいます。
ではどのようにしてそういった近い意味のキーワードを探し出すか、ということ考えたときに一番理想的なのは、ユーザーが言語化できなかったものを補足するようなキーワード群を探すことです。つまり、Rettyが持つ店舗情報やユーザーの口コミを元にそういったキーワード群を推測することが理想的でした。そのため、今回はユーザーからの口コミデータを扱い、周辺語生成のツールとしてWord2vecを用いることにしました。

Word2vecについて

Word2vecは、GoogleのリサーチャーであるTomáš Mikolovらによって開発された単語の分散表現(Word Embeddings)を生成するためのモデル群の名称で、CBOW(Continuous Bag-Of-Words)と呼ばれる周辺語から中心語を予測する(i.e. 類似キーワード群から元のキーワードを見つけ出す)モデルと、skip-gramと呼ばれる中心語から周辺語を予測するモデルの2種類があります。
名前からもわかるように、Word2vecは単語をベクトルとして表現し、重みをニューラルネットワークに学習させていくことで、コサイン類似度の大小などから単語同士の近さを導き出します。また、ベクトルであるため単語同士の足し算や引き算なども可能となり、有名な例だとKing - Man + Woman = Queenなどの計算もできるようになります。

今回は上に挙げた目的から、skip-gramモデルにレストラン説明や口コミを教師データとして学習させ、あるキーワードをモデルに与えたときにその周辺語 (i.e. 類似語)を生成できるようにしました。具体的な実装としては、PythonのgensimライブラリでWord2vecを扱い、モデルの学習に必要なハイパーパラメーターは以下のように設定しました。

  • ベクトルの次元数: 200

  • ウィンドウ数 (与えた単語の周辺何語までを"近い"単語とみなすかを決定するパラメーター): 8

  • Negative Sampling ("遠い"とする単語のサンプルをウィンドウ外から何語持ってくるかを指定するパラメーター。計算の高速化に必要): 5

また、その他のWord2vecについての詳しい説明は、以下のスタンフォード大学の講義動画が役に立ちました。

www.youtube.com

MeCabによる形態素解析

上記のモデルに単語の相関性を正しく学習させるには、データの前処理が必要でした。まずは散文を単語ごとに分ける必要があるのですが、日本語は英語やラテン語とは異なり、語尾が活用する膠着語であるため、ただ単純に単語で区切るだけではうまくいきません。そこで日本語の形態素解析で有名なツールであるMeCabを用いて単語分割と品詞付与を行いました。MeCabの内部ではラティスが構築され、コストが最小化されるようなパスを選ぶことで正しい形態素に分けられるようになっており、今回は目的上、名詞と形容詞のみを取り出してモデルに与えることにしました (それのみでは意味を持たない助詞などはモデルの学習の妨げになる可能性があったため除外)。また、"インスタ映え"などの最新の単語も正しく分類できるように、MeCabの辞書はNEologdを使用しました。

検索式の生成

MeCabを用いて口コミデータを形態素解析し、それを使ったモデルの学習が完了すると、次は単なる周辺単語の羅列であるモデルのアウトプットから実際の検索式を生成する必要がありました。これは、

  1. 単純なキーワードとアウトプットの組み合わせ
    e.g.) "和食"がインプット、アウトプットが"懐石料理・日本料理・寿司"とすると、和食&懐石料理 | 和食&日本料理 | 和食&寿司という検索式を生成
  2. キーワードの単純変換
    e.g.) 和食 | わしょく | ワショク | Japanese Cuisine
  3. 含めてはならないフレーズの排除
    e.g.) "中華街"がインプットとすると、"!中華街から遠い | !中華街ではなく"などの検索式を生成

などを考慮し、実装を進めました。
キーワードの変換はgoogletransというPythonライブラリを使い、禁止フレーズはテンプレートを作って与えられたキーワードをそれに当てはめる形にしました。

成果・改善点

上記の実装を経て、具体的な成果としては、例えば"ディナー"というキーワードを与えたときに、以下のような検索式を生成することができるようになりました。

f:id:rettydev:20190218151937p:plain
キーワード「ディナー」で生成される検索式

また、このツールを使うとテーマページに表示されるお店リストの順序が変動し、より検索キーワードに固有のお店のランキングが上がることも確認できました(以下は、検索結果を確認するための社内用ツールで上記の検索式を入力したところ。エリアは倉敷市で指定)。

f:id:rettydev:20190218160729p:plain
キーワード「倉敷」の検索結果

しかし、2週間という時間的制約があったということもあり、インターン期間で出来なかったことやこのツールにおける改善点は多々あります。具体的には以下のような改善点が考えられます。

  1. 作成したモデルの定量的な評価が必要
    今回はモデルのアウトプットとして生成された検索式で実際に検索してみたり、Google検索エンジンの検索レコメンドを真似てみたりと、モデルの性能を定性的にしか評価していませんでした。今後は、このモデル自体の定量的な評価 (+ 最適化)に加えて、このモデルを使って生成されたテーマページ (ちなみにこのモデルはあくまでもテーマページ内部の検索式のみを自動生成するものであり、ページの生成ロジックや見た目に関しては既存のテンプレートがある)によって、PVやクリック数などがどれだけ変化するかなどを数値化・可視化していく必要があると感じました。
  2. 検索式生成アルゴリズムの改善
    現状は、例えばNGワードの除外などはマニュアルで作成したテンプレートにキーワードを当てはめる方式をとっていますが、これは苦肉の策であり、より効率的で正確なアルゴリズムで置き換える必要があるとも感じました。具体的には、"ランチ"というキーワードに対して"ランチから遠い"などといったフレーズが生成されたりするのを防ぐ必要があります。
  3. モデルに与えるキーワードの選定
    上記の成果のサンプルでは、"ディナー"というキーワードを与えていますが、ここでどのようなキーワードを与えるべきか、というのは大きな問題です。あまり検索されないキーワードを与えるよりかは、検索されやすい単語から順に与えていった方がテーマページにとって効果的なのは明らかですが、そういったキーワードの選定までは今回は手が及びませんでした。
  4. Word2vecの代替ツールとの精度の比較
    Word2vecには、与えるデータ量が少ないと精度がイマイチ、という大きな欠点があります。今回の場合は、そこそこのデータ量があったため比較的上手くいきましたが、このツールを他の分野で応用していく際に、十分なデータ量が確保できない可能性もあります。そういった場合にWord2vecを使用するのは最善とはいえず、他の代替ツールを検討する必要が出てくるかもしれないと感じました。例えば、スタンフォードの研究グループが開発したGloVeは、SVDとWord2vecの欠点を相殺し、小さなコーパス (i.e. データ量)からでもパフォーマンスがいいといった特徴があるため、上記の条件を満たすようなツールになり得るかもしれません。

今回作成したツールの応用について

上に挙げたように現状の改善点は多々あるものの、今回作成したツールは有用であり、様々な領域での応用が可能ではないかと考えています。例を挙げると、

  • レコメンドシステムへの応用
    Airbnbなどは既にレコメンドシステムにWord2vecを活用しているようです。
    mccormickml.com

  • ターゲット層を絞ったテーマページの生成
    ユーザーログの解析と組み合わせれば、例えば、"20代女性に大人気のレストランまとめ"などのテーマページの生成も可能になり、テーマページ自体の需要も上がるのではないかと考えました。

  • 感情分析を用いたUXの向上

などがあり、Word2vecがいかに有用で革命的なものであるかがわかります。

インターンを終えて

インターンに参加するまでは、機械学習自然言語処理を実践的に扱った経験がなく、Word2vecを使用した経験もありませんでした。そんな中2週間という短期間で成果が出せるのか、という懸念はインターンが始まる前からありましたが、メンターや他のエンジニアの方々のサポートもあり、スピード感を持って業務に取り組むことができ、最終日には無事にエンジニア・プランナーを含めた30名程の社員の前で成果発表プレゼンをすることができました。

業務以外にも、毎日異なる方々とランチに行くことができ、Rettyにおける新しい取り組みや、創業当時の話、研究のアドバイスやビジネスにおけるものの考え方まで、幅広いトピックの話を伺うことができ、インターンが終わってからはよりメタ的な思考で物事を考えるようになりました。特に、Rettyのようなプロダクトベースの企業では、何よりもユーザー体験が第一であり、ユーザーに長く日常的に使ってもらえるプロダクトをつくるためのツールの核として、エンジニアリングというものがあるのだという認識が強くなりました。つまり、ユーザーにとって内部の実装や使われているツールなどは大した問題ではなく、果たしてそれが使いやすくて便利なものかということが最も重要であるということです。今回のタスクはユーザーには直接的には関係のないものでしたが、今度は逆にそういったプロダクトを作るエンジニアの作業効率を上げること、つまり人間がやらなくてもよいことを自動化する、という作る側にとってのメリットが大きいものだったのだと思います。

現在は大学に戻っており、Rettyでの経験をスタート地点として今学期から自然言語処理系の研究を大学教授の元で始めました。今の今でいうと知識やスキルのキャッチアップの要素が強いですが、今後はAuto Summarization (自動要約)や文章のバイアス検知 (例えば、Word2vecのKing - Man + Woman = Queenという式は、Kingが男でなければならないというコンテクストで捉えるとPolitically Incorrectであり、無意識のバイアスがかかっているといえます)に関する研究を進めようと考えています。現在は扱えるデータ量が指数関数的に増加していますが、実際のデータの大半は英語や日本語などの自然言語で書かれているため、機械に自然言語を処理させることの重要性は今後益々高まっていくに違いなく、それが現在の研究をするモチベーションにも繋がっています。

最後に、Rettyでのインターンを考えている方へ

Rettyは、自分でやりたいことや興味のあることが決まっている人にとっては、最高の環境であるといえます。大学の授業や研究室における理論やコンセプトが、私たちが日常的に使うプロダクトに落としこまれるその雰囲気を感じられるというだけでもインターンに行く価値はあると思います。
それに加え、冒頭でも書きましたが、4000万人の月間ユーザーを抱えるRettyが持つ価値のある密なデータ (少なくともAmazonの商品レビューに比べたらデータの密度は大きく扱いやすいといえるのではないでしょうか)を自由に扱えるという点を考えると、データサイエンティスト志向の人にとっても活用しがいのある環境だと思います。
そのような野心のある方はぜひRettyのインターンに応募してみることをオススメします!!

最後になりましたが、インターン期間中にメンターとしてサポートしてくださったアドテクチームエンジニアの堤さん、それからインターンの方向性などを一緒に考えてくださったCTOの樽石さんをはじめとしたRetty社員の皆様にはこの場を借りて御礼申しあげます。ありがとうございました。