Gunosyデータ分析ブログ

Gunosyで働くデータエンジニアが知見を共有するブログです。

データ分析部が開発・運用するバッチ アプリケーション事情

はじめに

こんにちは、データ分析部の森本です。
この記事ではGunosyデータ分析部がどのような視点に基づいてバッチアプリケーション(以下、バッチ)を開発・運用しているかしているのかを紹介します。

クライアントアプリ開発やAPI開発と比較してバッチ開発のノウハウなどをまとめたWeb記事の数は少なく感じます。 また、言語に関わらずWebフレームワークの数に対して、バッチフレームワークの数も少数です。
このような点を踏まえると一般的には難易度の高くない(ノウハウを必要としない、フレームワークに頼る必要のない)、もしくはニーズがあまりないなどの印象があるのかもしれません。

一方で我々は日々バッチ開発を行い、数多くの地雷を踏んできました。 これらの経験を踏まえてどのような点に気をつけているのかについて共有します。
理想的には多くの方の経験を共有して、建設的な議論に発展するとうれしいです。

全体像

Gunosyではニュースアプリを開発しています。ニュースアプリ開発には大きく5つの柱があります。

  • iOS, Androidのクライアントアプリ開発
  • クライアントからのリクエストに対応するAPI開発
  • 提携しているメディア様からニュース記事を収集するクローラー開発
  • ニュース記事をプッシュ配信するプッシュ機能開発
  • スコアリングやニュース記事分類などの記事配信アルゴリズム開発

(アドテクノロジーとインフラは別の大きな枠組みであるため、ここでは除外しました)

データ分析部ではデータ分析や機械学習を活用したプロトタイプの実装だけでなく、プロダクションコードの実装、デプロイ、運用まで実施しています。

また、バッチにも複数の種類があると思います。
我々が開発しているバッチは金融機関等の日次、月次処理とは趣が異なります。
ユーザー満足度向上を支えるために機械学習などを活用し、スコアなどを計算するバッチと捉えてください。

開発について

フレームワーク

記事配信アルゴリズムは主にpythonで実装しています。
特に数値計算ライブラリnumpy, pandasや機械学習ライブラリscikit-learn、各種deep learningライブラリの力を借りたいというのがpythonを使用している主な理由です。 一方、バッチフレームワークとしてDjangoを利用しています。
DjangoといえばWebフレームワークに分類されると思いますが、なぜバッチ開発に利用しているのでしょうか。
Djangoをバッチフレームワークと使用するメリットに次のようなものが上げられます。

  • 同期処理/非同期処理を柔軟に実装できる
    • Commandクラスを使用した同期処理、Celeryを使用した非同期処理を用途に応じてDjango上で実装できる
    • Celeryを使用することでmaster/slave形式で分散処理を実現できる
  • MySQL、Redisを始めとした各種データソースへのアクセス処理が充実
    • バッチ開発の基本はInput/Process/Output
    • Input/Outputのデータアクセス層のコードを比較的綺麗かつ隠蔽して書くことができる
  • ロギング処理の充実
  • デバッグが容易
    • python manage.py shell で対話的に実装できる
  • ドキュメントが充実&十分枯れた技術

逆にここがいまいち

  • ORMコードが書きづらい
    • この点は慣れやエンジニアの技術レベルに依存するとは思いますが、Railsと比較するとなかなかシンプルに書けないと感じています(主観)

さて、バッチフレームワークにDjangoを使用していますが、他の候補としてLuigiやAirflow等が挙げられます。 皆様の中にこれらフレームワークをプロダクション環境でガッツリ使用している方がいらっしゃいましたら、ぜひ情報共有したいです。

どこに記事配信アルゴリズムを書くか

いわゆるサービス層のロジックをどこに書くかとも表現できます。
Input/Outputを担う各種データソースへのアクセスコードは各種データソースごとにappディレクトリを作成しています。
記事配信アルゴリズムコードは散らからないように1appディレクトリ内に閉じ込めるように努めています。 一応この方法でコードが散在することは防げますが、より確かな方法を模索中でもあります。

デプロイ環境

デプロイ環境はプロダクション環境、ステージング環境、サンドボックス環境の3種類あります。
新しいアルゴリズム(例えばニュース記事の分類器やクラスタリングロジックなど)をリリースするときはステージング環境で動作検証します。
一方でスコアリングアルゴリズムではアクセスログも使用します。ステージング環境では十分なアクセスログがありません。そこでサンドボックス環境を用意しました。サンドボックス環境ではプロダクション環境と同様のアクセスログを取得でき、スコアリングアルゴリズムの検証を実施できます。このようにステージング環境とサンドボックス環境の2種類の検証環境があり、用途に応じて使い分けてます。

ABテスト

新しいアルゴリズムをリリースする時、ステージング環境、サンドボックス環境で動作確認できても、いきなりプロダクション環境に100%デプロイすることはありません。ABテストを実施してKPIが向上するか(もしくは想定内の減少をするか等)を必ず確認します。

data.gunosy.io

品質

品質チェックはステージング環境、サンドボックス環境で十分に行います。また最後の砦としてABテストがあります。
一方恥ずかしながら、記事配信アルゴリズム開発については明文化されたテスト計画はありません。
そのため、テストコードの実装は複雑なロジックに対して重点的に書くなどのエンジニア依存の部分もあります。
また、プルリクエストレビューは必ず実施します。比較的即座にレビューしてくれるのでメンバーには感謝です。

実装&デバッグ

組織ではなく個人の感想になってしまいますが、pdbなどのデバッガを使用するよりも python manage.py shellで対話的に実装して同時にデバッグするほうが生産性が高いと思っています。 また、対話的にすすめることでORMコードのSQLも容易に確認でき、重い処理の把握や改善を即座にできるのがうれしいです。
プロダクション環境でしか発現しない問題の原因追求にも python manage.py shellで実施する場合もあります。
ただしこの方法はおすすめできるものではありません。本来はログより確認すべきで、それをログから確認できない時点でログ実装が不十分といえます。
開発生産性を高めるために皆様がどのように実装しているか知恵を借りたいです。

運用について

デプロイ

Gunosyでは全プロダクトを通して、デプロイは主にAWS OpsWorksを使用しています。ボタンポチでデプロイでき、非常にありがたいです。SREチームに頭が上がりません。

f:id:moyomot:20171010141809j:plain

ロギング&監視

データ分析部が運用するバッチは多数あります。そのためリリース直後を除いてINFOログを定期的に監視するということはしません。問題が発生したときのみタイムリーに気づける仕組みを取っています。

  • アプリケーションにERRORログを実装&必要に応じてリトライ処理
  • ログ監理はpapertrailを使用
  • エラーログはpapertrailを通じてwebhookでSlack通知

f:id:moyomot:20171010142905p:plain

おわりに

我々が日々実施していることを比較的かっこよく書いてみました。一方ではpython2系のスクリプト集合体のバッチ群も現役バリバリで生き残っていたりします。
言うは易く行うは難しであり、泥臭い運用に頼っている点もあります。
ベターなノウハウが共有されて、よりよいバッチ開発ライフを実現できることを祈っています。
(バッチ開発運用Nightとかやりたくなってきた)

参考

qiita.com

エンジニア向けデータ分析サマーインターンシップに参加して

こんにちは、来年度からデータ分析部に所属する山田です。 今はまだ学生です。 一足先にGunosy Summer Internship 2017 データ分析コースのメンターアルバイトとして参加したので、その様子や知見を記していきたいと思います!

Gunosy Summer Internship 2017 について

Gunosy Summer Internship 2017とは、株式会社Gunosyが2017年夏に開催した短期インターンシップです。

の2つのコースが実施されました。

「経営企画・戦略コース」では2日間で講義や新規企画課題などをこなす内容で、 課題の優勝者には豪華ディナーや1次選考免除等の特典がありました。

「データ分析コース」では3日間で講義やデータ分析コンペを行い、 コンペ優勝者には賞金10万円(!!!)、2位3位の人にもお肉のギフトカタログが贈呈されます。

「データ分析コース」の様子

データ分析コースのインターンシップは今年が2年目です。 去年は私も学生として参加しましたが、 その時は2日間・1回のみだったのに比べ今年は3日間・2回(8/30-9/1・9/11-9/13)と、大幅にグレードアップしています!

スケジュールは以下のような感じでした。

時間 内容
1日目 10:00 集合
10:30-11:00 講義①
「データ分析部とプロダクト開発の関わり方」
13:00-13:30 課題発表
13:30-18:30 ワーク
2日目 9:30 集合
9:30-18:30 ワーク
3日目 9:30 集合
9:30-16:30 ワーク
16:30-17:30 講義②
「Gunosyの歩みについて」
17:00-18:00 成績発表等

講義

1日目と3日目には共同創業者である吉田と関から、「データ分析部とプロダクト開発の関わり方」と「Gunosyの歩みについて」の講義がそれぞれ行われました。

私も一聴講者として講義を聴いていましたが、

  • 思い込みでサービスを作るのではなく、まずユーザの行動ログから何が必要とされているのかを分析する
  • 失敗することは当然。賢く失敗すればその後の分析や開発にも活かせる

といったデータ分析やプロダクト開発において重要なことや、 Gunosyがこれまでどのようなことに挑戦してきたのかを学ぶことができ、非常に為になる講義でした!

ランチ・新卒トーク

1日目、3日目はグループごとに六本木のお店でランチを摂りました。

2日目はスキップヒル*1で弁当を食べながら、今年度からデータ分析部で働き始めた米田、荻原が新卒トークをしました。 二人とも入社経緯や、入社してからどのような仕事をしているのかわかりやすく話してくれました!

インターン参加者は全員学生なので、年齢の近い二人の話はとても身近な例として参考になったのではないかと思います。

ワーク

1日目の講義&ランチの後はいよいよ本インターンのメインとなるワークの課題発表です! 今回のテーマは「グノシーアプリ内の広告CTR予測」

グノシーアプリ内で広告が表示された時の「ユーザの性別・年齢」や「広告の種類」が与えられるので、その広告がクリックされたかどうかを予測するという課題です!

データ分析インターンでは「データとアルゴリズムの企業」らしく、予測結果に対して「実データによる評価」が行われ、予測精度に基づくスコアを算出します。 Kaggleのコンペ等と似た方式ですね。

また、このインターンでは「できるだけ実務に近い経験」をしてもらいたいので、予測の処理に時間制限を設けています。 というのも、実際の環境では非常に短い時間で予測結果を返すことを要求されるので、 結果を返すまでに何秒もかかってしまうようなプログラムではいくら予測精度が高くても使い物になりません。

つまりこの課題では「予測精度」と「処理時間」の二つの要素が同時に問われることになりますね。

ベンチマークシステム

Gunosyではこれらの要素を計るために、インターン用ベンチマークシステムを開発しています。 インターン生には一人一人AWSインスタンスが与えられているので、 そのインスタンス内でベンチマークプログラムを叩けばいつでもスコアを算出できるので、予測精度や実行時間を見ながら何度でもトライすることができます!

また、実行したベンチマーク結果は自動でダッシュボードに反映され、誰でも確認することができます。

f:id:mtjune:20170929133527p:plain

全員のベストスコア、順位などが確認できるので僕自身も非常にモチベの高まる環境で作業することができました!

作業環境

作業は4つのグループで机を分けて行い、それぞれのグループには社員のメンターが付いているので詰まったところなどがあればすぐに質問できます。

私もメンターとして控えていましたが、忙しい時はずっと誰かしらの相談に乗っている状態だったりで、 それだけ真剣に取り組んでいただけていると思うと非常に嬉しい気持ちになりますね!

結果発表

3日目のワークが終わると、いよいよ結果発表......の前に、社員がインターン生全員のベンチマークを走らせ、最終スコアを算出します。

実はスコア算出用のテストデータは2分割されており、ワーク中のベンチマークではそのうちの片方だけを使ってたんですね。 最終スコアではもう片方のデータを使うので、ワーク中のデータに特化してチューニングして最終スコアでガクンと悪くなってしまった......となる可能性もあり、 実はそこもポイントの一つです。

さて、最終スコアの計算も終わり、発表直前の会場......

f:id:mtjune:20170929143056j:plain

まずメンターの石塚がこの課題の狙いや要点について説明します!

f:id:mtjune:20170929143203j:plain

発表が始まります!

f:id:mtjune:20170929143445j:plain

1位の方には賞金10万円、2位と3位の方にはお肉のギフトカタログが贈られました!

f:id:mtjune:20170929150004j:plain

また、1位〜3位の人がどのような手法を使ったのかを簡単に説明していただきました!

f:id:mtjune:20170929150335j:plain

優秀な上位陣の話は、メンターの私にとっても非常に参考になる話でした。

このインターンでは実データを使って実務に近いタスクをこなしてもらうものでした。 3日間と短い期間ではありましたが、参加者にはぜひこの経験を今後に活かしてほしいと願っています!

インターンでの気付き(メンター山田)

メンターをしていて、重要だと感じたのは

  • データを可視化して傾向を把握すること
  • 手段を選ばないこと
  • 試行回数を増やすこと

あたりで、このへんをちゃんとしている人はどんどんスコアが伸びている印象でした。

今回の場合、とりあえず年代や性別ごとにCTR集計してそれを出すだけでそこそこのスコアにはなるので、 いきなり機械学習に挑戦したが上手くいかずに結局そのスコアを超えられない......という例もあり、 まずは素朴な手法から試すのが良いのではないかと思います。

また、素朴な手法ほどデータをつぶさに観察する必要が出てくるので、結局そのあたりは後に機械学習するにしても役立ちますし無駄になることは少ないでしょう。

試行回数に関しては今回の出力形式(json)が少々扱いづらかったこともあり、それで詰まって時間を消費している人も多かったように感じます。

インターン参加者の感想 第一回

f:id:mtjune:20170929151027j:plain

京都大学大学院 澤田さん

こんにちは。サマーインターンシップに参加した澤田です。ハッカソンでは、優勝という望外の結果を得られ、嬉しく思います。この経験を通して気づいたこと・学んだことをまとめようと思います。

手法について

私が最終的に提出したモデルは、ルールベースによる予測値とロジスティック回帰による予測値を加重平均するという単純なものです。ライブラリの使用に不慣れなため、データの前処理の実装などで苦労したところはありますが、やっていることはごく初歩的なことです。時間があれば、もっとモデルを吟味してスコアを上げる余地はあるだろうと思います。

限られた時間で形にすること

このように単純な手法ですが、3日間という短期間で、曲がりなりにも優勝するような手法にたどり着いたプロセスにこそ大きな学びがあったと感じます。 初日の失敗談から話しますが、私はいきなりSVMを全データの8割で回そうとして、「全然終わらないな〜」とかやっていました。その時は知らなかったのですが、SVMはデータ数Nに対してO(N2)の時間計算量なので、終わるわけがなかったのです。そんなことがあったので、小さく単純なモデルから始めようと方針を改めました。ほら、「Done is better than perfect.」って言うじゃないですか。 というわけで、性別・年齢によるルールベースのモデルから始めて、少しずつ特徴量を増やしていくとその時点でのリーダーボード上でトップのスコアを取れました。このスコアはのちに更新されるのですが、モデル作成の過程で得られた、データの構造に関する理解や手元でスコアを計算する環境(スコアサーバーに投げると5分もかかる!)なんかは後々とても役に立ちました。 ルールベースでの試行錯誤から、複数の特徴量を複雑に組み合わせずとも、単純なモデルだけでスコアが伸ばせそうだと感じたので、より多くの特徴を使うためにロジスティック回帰に移行しました。最終的には同じようにロジスティック回帰をした参加者と1,2位を競い合うことになったので、悪くない選択だったのかなと思います。2位のモデルとわずかに差が出たのが、ルールベースでの予測値と加重平均をとった分だったとしたら、ルールベースくんこそが影の立役者なのかも?

教訓みたいなもの

じゃあ、なにを学んだのかと言われると - 試行錯誤のサイクルをなるべく短くすること - 簡単・確実なことから一歩ずつ進むこと こんな感じです。今更そんなことかよ、というくらい聞き飽きたことだと思いますが、慣れないタスクについてこれを実践するのは意外と難しいですね。SVMに突っ込んで「全然おわらねェ」とかやりがちです。

以上、3日間でしたがとても充実していて多くを学ぶことができました。社員の方ともよく話すことができて大満足です。ちなみに昼ごはんはしゃぶしゃぶと寿司でした!!

東京大学 原田さん

用いた手法について

私は最初の1日を与えられたデータの素性一つ一つとクリック率との関係を調べていき、どの素性がクリック率に大きな影響を及ぼすのだろうかと探っていました。 ある程度当たりをつけたら計算速度が速くて検証が多くできるだろうという理由からロジスティック回帰を用いました。 モデル生成してテストデータに適用するときにtrainデータに存在していたカテゴリー値がtestデータに無く、エラーを起こしてしまいましたが、one hot dictvectorizerを用いた処理をメンターの方に教えて頂き、無事適用することができました。 もっと色々な特徴量で試してみたかったのですが時間切れになってしまいました。

参加してみての感想

インターン最終日の懇親会で、他の参加者がユーザーに関わる素性に注目しているが広告の素性を吟味した方は少ないように思えたので、1日目にしたデータの特徴を一つ一つ丁寧に見るという作業をこれからも大事にしていきたいです。 大学の授業でデータサイエンス・機械学習について一通り学んでいましたが実践の場は初めてで、自分の知識不足を実感すると同時にやはりデータ分析は面白くもっといい分析ができるようにしたいと思いました。

東京大学 丹羽さん

Gunosyのサマーインターンシップに参加させていただいた丹羽と申します。少し時間が経ちましたが、改めて今回のインターンシップについて振り返りたいと思います。

用いた手法、時間の使い方

課題は広告・ユーザーの様々な種類のデータから広告のCTRを予測するというものでしたが、1日目に大まかにデータの傾向を見た段階で、実はユーザーの属性のみでも十分CTRの傾向を説明できるのではという大胆な仮説を立てました。そこで、2日目は与えられた教師データのうちユーザーの情報のみを使用して様々なモデルを学習させその比較を繰り返し、最終的にはScikit-learnの勾配ブースティングを用いて比較的いいスコアが出せました。ですが、最上位の人のスコアが抜き出ていてやはり広告のデータも用いないと追いつけないと感じたので、最終日の3日目は広告のデータの傾向を再吟味し用いるデータの種類を絞った上で、モデルの学習とファインチューニングを行いスコアを改善させていきました。

学びと感想

終わった後改めて最上位の人の話を聞いたところ、広告の方も多くの種類のデータをしっかり学習させていたようで、自分の仮説は不十分だったようです。初日にもう少しデータの統計量に注目してじっくり考察するべきだったかもしれません。周りの様子を見ているとデータの高度な統計処理や分析結果の可視化を綿密に行っている参加者もいて、その手法などについて見習う部分も多かったです。 一方で、今回は時間も限られていたのでとにかく作ったモデルを試す回数を増やすことを意識して取り組んでいましたが、試行錯誤する中でどのデータが効いているのか見えてきたり学習モデルのどのパラメータが重要なのか気付けたりする部分も多く、泥臭くトライ&エラーを繰り返すことも一つの有効なアプローチであると実感しました。はじめに大胆にデータを絞ったことも、それによって問題を単純化でき見通しを立てやすくなったので、自分にとっては有利に働いたのだと思います。 また、インターンシップ中の参加者や社員の方々との多くの交流は非常に刺激的でした。あっという間の3日間でしたが濃密で有意義な時間を過ごすことができたと感じています。

筑波大学 小林さん

筑波大学の小林です.今回のインターンシップでの分析に用いた手法と感想について述べたいと思います.

用いた手法について

今回のインターンは三日という短い期間で成果を出すことを求められるものでした.その為初日はデータの可視化とそれを元にルールベースを構築することで,ある程度の成果を出すことに専念しました.二日目以降は機械学習モデルの構築を進めながら,裏でルールベースのチューニングと提出を繰り返しを行い,最後にはモデルの構築時に得た知見を追加したルールベースを提出しました.

感想

機械学習での予測が二日かけても初日に作成したルールベースを超えるものにならず,自分の実力不足を実感しました.ルールベースは実装が早く序盤は強いですが最終的には時間をかけて作られた機械学習での予測には勝てないです.しっかりと勉強して地力をあげることが,データコンペで優れた結果を出すには大切だと改めて感じました.

インターン参加者の感想 第二回

f:id:dr_paradi:20170913181000j:plain

大阪大学 中村さん

分析に用いた手法

どの機械学習の手法を用いても精度はほとんど変わらなさそうだったので、深く考えずにGBDTを用いました。ライブラリはxgboostを使用しました。訓練データの期間が1日分のみで、さらにテストデータが未知であったことから過学習が怖かったので、木の本数をクロスバリデーションで選んだものよりも少なくしました。実際、木の本数を少なくすると、スコアが結構良くなったように記憶しています。

手法の選択よりもどんな特徴量を使うかの方が重要だと思ったので、元のデータから様々な特徴量を作りました。例えば、 - いくつかの特徴量を組み合わせて新たな特徴量を作る(例:性別+年齢) - カテゴリカル変数は、カテゴリごとの訓練データ内での広告の表示された回数・クリックされた回数・クリック率を特徴量とする などを行いました。

参加してみての感想

作業時間や計算資源が限られていたため、複雑なことをやるよりも手早く色々なアイデアを試すことが重要だったように感じました。また、機械学習の手法を用いずにルールベースのみでよい結果を残している人もいて、ルールベースも侮れないなと思いました。

長岡技術科学大学大学院 桾澤さん

インターンシップでの気付き

今回の課題で自分は基本的な時間帯等の素性に加えて広告ごとにWord2Vecでベクトル化したを素性として用いることで高い精度の予測ができるのではと考えそれらを素性としたSVMの予測器を実装しました。 提供されたデータにはユーザーのクリックしたデータが少なかったためカテゴリ面ごとにある程度パーソナライズして広告を出し分けていると予想してすべてのデータを時系列順に学習させました。 その結果最終成績として2位になることができました。 今回のインターンシップを通して学ぶことができたデータ分析に対する考え方を書きたいと思います。

機械学習のモデルの気持ちになる

よく言われていることだとは思いますが、このインターンシップを終えて改めてこの感想をいだきました。 今回提供されたユーザーの行動ログは殆どがカテゴリカルなデータであり、それをそのまま機械学習に用いてもあまりいい精度が出ないのは明らかでした。 にも関わらず、基本的な部分の素性の可視化を怠りそのままモデルに学習をさせてしまったためか、最終的な結果としていい精度を出すことができませんでした。

機械学習に対する理解を深めることもそうですが、理解を深めた上でじゃあどうやったら精度を上げることができるのか、どのような形の素性を用いればより高い精度を期待できるのか、という事をしっかりとデータを可視化した上で分析することが重要だと再確認することができました。

早稲田大学大学院 芦川さん

芦川です。今回のインターンで用いた手法や学んだこと・感じたことについてご紹介したいと思います。

用いた手法

私は今回ルールベースを一切用いない代わりに、なるべく多くの素性を基に機械学習手法を用いることで、自動的に予測に寄与する特徴表現が得られるようにすることを目指しました。

機械学習に用いた特徴量はユーザーID以外全ての素性から得たone-hotベクトルとしました。この際、それぞれの素性をone-hotで表現するためにダミー変数に置き換える辞書を自分で定義して、後段の処理で扱いやすい形になるように工夫しました。(例えば、タイムスタンプの時刻は時間の値をそのまま利用してしまうと扱いが難しいので、24時間を6時間ごとに区切り0~3の変数に置き換えるようにしたり、広告固有のIDなどは出現頻度とCTRに相関があることが分かったため、頻出するものだけに変数を与え、他は未知IDとして処理を行うようにしたりしました。)

こうして得られた特徴量を基にニューラルネットワークモデルとロジスティック回帰モデルの学習を行いました。ただし、上記で得られる特徴量は非常にスパースであるため、ロジスティック回帰モデルに与える際はLSIにより次元圧縮をしてから入力しました。

最終的にCTRを予測する際は、2つのモデルの出力を線形補間することで求めました。ニューラルネットは過学習をしやすいため、手元でいいスコアが出ても本番ではいいスコアが出るとは限りません。そこで今回はロジスティック回帰モデルとの線形補間を行うことで少しでも汎化性能を向上させることを試みました。

感想・学んだこと

私は今回ハンドクラフトなルールベースは信用できないと考え、CTRに関するユーザーの傾向をモデルのみで捉えることに注力しました。この方針でモデルを構築することで途中経過のベンチマークスコアは伸びていったのですが、プライベートデータに対する最終的な評価は残念な結果となってしまいました。この理由はいくつか考えられますが、一番の要因はモデルに頼りすぎた結果過学習をおこし、汎化性能が低下してしまったことだと思います。(そもそも今回与えられたデータ量で頑健なモデルを構築することは厳しかったのかもしれません。)

今回のタスクでは機械学習モデルに頼りすぎず、しっかりデータを分析して素性選択をしたりユーザーの傾向に基づくルールを見出したりした方々が上位にランクインしていたように感じます。モデルをどう構築するか?ということも重要ですが、実データに対してはそれだけでは不十分で、データをしっかりと分析した上で、時には感覚やセンスに頼りながら仮説を立ててアプローチしていくことが重要だったのだと思います。

メンターより

今年のサマーインターンの統括を担当しましたかとうです。

昨年のグノシーにおける記事クリック予測モデルの作成に引き続き、今年は広告のCTR予測モデルの作成を、コンテスト形式で行いました。

コンテストというと一見実務とかけ離れているのでは?と思われますが、課題と期待する成果のみ与えられ、課題を解くというのはGunosyでよく見られる仕事の光景です。
(実際には課題の設定、データの収集なども必要ですが・・・)

モデルの精度だけでなく決められた時間内に全てのレスポンスを返さないとスコアが悪化すること、サーバーのスペックが決まっていること、といった課題の制限についてもリアルな体験をしてもらうためのこだわったポイントです。レスポンスが遅ければ広告は表示されませんし、改善効果以上にコストがかかってしまっては元も子もありません。

制限がある中で現実的な手法を検討し、繰り返し試すというPDCAのサイクルを多く回すことが普段の仕事でも重要です。参加者の感想にもありましたが、実際に試行回数が多い方が高スコアにつながっていたように思います。

ということで今回参加いただいた学生の皆さんには、3日間という短い期間でしたがGunosyのエンジニアとしてリアルな体験をしていただきました。この体験は今後の研究、仕事にも生かされると信じています。
参加者のみなさま、お疲れ様でした!

*1:Gunosy社員の憩いのスペース。ソファや土足禁止スペースがあり、昼食や簡単なミーティング、個人での作業などに活用する人が多い

テキストアナリティクスシンポジウムにて招待講演/研究発表を行いました

データ分析部研究開発チームの関です。 最近は10月のエビ中とBishの対バンイベントに向けて双方の楽曲の予習を行っています。

この度データ分析部では9月7日, 8日に成蹊大学で行われた第11回テキストアナリティクスシンポジウムに参加し, 7日は招待講演とパネルディスカッション、8日には2件の研究発表を行いました。

テキストアナリティクスシンポジウムとは

テキストアナリティクスシンポジウムは電子情報通信学会の言語理解とコミュニケーション研究会(NLC研)が主催するシンポジウムで、 自然言語処理の結果をどのように分析・解釈・活用するかという点に着目した研究会です。 第10回まではテキストマイニングシンポジウムと呼ばれていましたが、業界全体のトレンドを考慮し、今回からテキストアナリティクスシンポジウムと改称されました。 参加者も学生や研究者だけでなく、企業の実務担当者が多かった印象です。 また自然言語処理を専門にする研究者だけでなく、自然言語処理を活用する他分野の研究者の発表も多くありました。

第11回テキストアナリティクス・シンポジウム:参加募集 - 言語理解とコミュニケーション研究会

参加/発表の目的

データ分析部の人数も増え、中期的なビジョンに沿った研究開発を行うことにリソースを使えるようになってきました。 そんななか発足したGunosyのデータ分析部研究開発チームでは研究成果の外部発表に力を入れており、 将来的にトップカンファレンスへacceptされるような研究を行うことを目標にしています。 そのなかでまず業務の中での外部発表を増やしていくために、国内研究会への定期的な発表参加を行っています。

普段業務の中で様々な問題に取り組んでいるものの、研究発表を行うことを目的とした実験やその結果の整理、原稿の執筆を業務の延長線上で行うことはなかなかに難しいのが現状です。 そこで国内研究会での発表を定期的なマイルストーンにして原稿の執筆を行うことで、定期的に実験や結果の整理を行い、 そこでの議論と結果の蓄積をもって、査読付きジャーナルへの投稿や、国際会議のワークショップへの投稿をまずは目指していくという方針を立てています。

テキストアナリティクスシンポジウムは、特に自然言語処理技術の応用にフォーカスしており、 実務での応用を目指した研究開発を行っている当社の試みとも親和性が高いと判断し、 今回以下2件の発表申込をするに至りました。

  • 関 喜史, 潮 旭, 米田 武, 松尾 豊, クリックベイトの特定に向けたユーザ行動分析
  • 米田 武, 久保 光証, 関 喜史, ニュース配信システムにおけるパーソナライズの設計と導入

招待講演

また発表参加とは別に招待講演の依頼を頂き、発表をさせていただきました。

今回の招待講演のテーマはウェブ企業におけるテキストアナリティクスの活用ということで、 当社以外にInsightTechさん、SanSanさん、メルカリさんの発表がありました。

当社からは「Gunosyにおけるデータドリブンなサービス開発とテキストアナリティクスの活用」と題して発表させていただきました。

f:id:Y_sekky:20170915131648j:plain:w300
招待講演の様子

事例よりもデータドリブンな開発体制の話を中心に話しました。 テキストアナリティクスをサービスに活かすという点においては、 テキストアナリティクスがどのような結果をもたらすかという点ももちろん大事ですが、 その結果を活かせるような会社の意思決定の仕組みが非常に大事だと考えています。

データ活用における組織の重要性については中山ところてんさんの資料でも述べられています。

今回は当社が試行錯誤しながら作り上げてきた組織の仕組みについて発表させていただきました。

参加者の方々からは「徹底的なデータドリブンな開発体制は非常に勉強になった」という声を多くいただきましたが、一方で「もう少し具体的な事例を聞きたかった」という意見もいただきました。 今後の発表に活かして行きたいと思います。

また招待講演終了後、他の招待講演者ともにパネルディスカッションが行われました。 各社の持っているデータや、活用方法はそれぞれ多種多様でしたが、「ゴールの設計をしっかりやること」という点がみなさん一致していたのが興味深かったです。

研究発表

2日目には当社から「クリックベイトなニュース記事の特定に向けたユーザ行動分析」と「ニュース配信システムにおけるパーソナライズの設計と導入」の2件の研究発表を行いました。 まだ研究開発段階のためウェブ上での資料の公開は差し控えますが、活発な議論を行うことができました。

f:id:Y_sekky:20170915133504j:plain:w300
関による研究発表の様子

f:id:Y_sekky:20170908140511j:plain:w300
米田による研究発表の様子

おわりに

これまでスポンサーとしての参加は積極的に行ってきましたが、 今回ははじめてのまとまった研究発表を行う研究会の参加でした。 今後もスポンサーとしての学術コミュニティへの貢献は継続しつつ、 発表者としても参加し、研究者の皆様との議論を深めていきたいと考えています。

【Slack×Re:dash×SpreadSheet】らくらくリアルタイムKPI通知

こんにちは、データ分析部のクボタです。最近はアイドルではsora tob sakanaの『ribbon』とアイドルネッサンスの『前髪』と東京女子流の『鼓動の秘密』を良く聴いています。来年のTIFと@jamが楽しみですね。 www.youtube.com www.youtube.com www.youtube.com

現在Gunosyでは様々なプロダクトを運営・開発していますが、施策等における意思決定においてデータを非常に重要な指標として扱っています。そのため、日常より分析部以外のメンバーも含めたダッシュボードやSlackのリアルタイム通知によるプロダクトの現状把握の場を大事にしています。

GunosyがKDDI株式会社と共同で提供しているアプリのニュースパスでは現在ダッシュボードはRe:dashを用いて作成しています。Re:dashは細かいSQLクエリの更新スケジュール設定や、Slack通知などの便利な機能からデータの可視化ツールとして重宝しています。詳細なRe:dashの特徴やSlackとの連携については、本ブログの以下の記事で紹介されています。 data.gunosy.io

上記の記事に即してニュースパスにおいても同様にslack連携によるリアルタイム通知を行おうとしたのですが、何故かうまくいきません。Re:dashでは右下のチャットツールから開発者のArikさんに英語で質問などを送ることができます。そこで何度かやりとりしたところどうやら1つのRe:dashアカウントには一つのSlackアカウントしか連携できないため現在の環境ではニュースパスのRe:dashアカウントとは連携できないとのことでした。

また、今後の開発のためとのことで複数アカウントに関する以下のような質問をされたので、それに答えて代替策としてSpreadSheetによるSlack通知を行ってきました。 f:id:khirohisa:20170825141104p:plain

すると、最近以下のようなメールが届いたらしく・・・ f:id:khirohisa:20170825141629p:plain 質問への回答が功を奏したのか分かりませんが、複数アカウントで/redashコマンドで投稿できるようになったそうです。

Slack×Re:dash×SpreadSheet

ここからは代替策として行っていたSpreadSheatを経由したSlack通知について説明したいと思います。 Re:dashとSlack連携による投稿に比べて事前準備が必要ですが、SpreadSheet経由のSlack通知は沢山コードを書くこと無く様々なカスタマイズが可能です。ここでは簡単にRe:dashの図を投稿する方法を説明しますが、これを応用して様々なKPI通知等が可能になると思います。 まず、SpreadSheetとSlackの連携のためにincoming Webhooksの設定をする必要があるため以下にアクセスします。 https://my.slack.com/services/new/incoming-webhook/my.slack.com Post to Channelで通知したいSlackのchannelを選んでAdd integrationします。

f:id:khirohisa:20170822165401p:plain

選んだSlackのchannelで以下のような投稿がされていれば準備完了です。 f:id:khirohisa:20170822165718p:plain 次に、SpreadSheetの設定に移ります。 まず、分かりやすいslack通知などの名前で以下のようにSpreadSheetを作ります。その際にシートの名前はchannelごとに通知を分けるためにSlackのchannel名などにすると便利だと思います。複数シートを作れば複数のchannelに通知を打ち分けることも出来ます。

f:id:khirohisa:20170825132234p:plain

次に、このSpreadSheetの各列について説明していきます。A列はどのKPIを通知するかを記載します(なくても良いが整理のため)。B列はre:dashのchartの左下にあるEmbedから得られるurl情報を記載します。かつてはこの情報をSlackに投稿すると図が展開されていたのですが、現在はそのままでは展開されないので少し修正が必要です。Embedには以下のようなurlがあると思います。

https://app.redash.io/アカウント名/embed/query/数値1/visualization/数値2?api_key=文字列

これを以下のように変形してB列に入れます。

https://snap.redash.io/p/アカウント名/数値1/数値2/文字列.png

次に、Slack投稿用のスクリプトを準備します。 スクリプトも好きなように書けば良いのですが例えば以下のようにすると、選んだチャンネルに複数の図を投稿することができます。

function postSlack() {
  var sheet    = SpreadsheetApp.openById('SpredSheetの/d/と/edit#の間の文字列を代入');
  
  for (var i=2; i<投稿する図の数; i++ ) {
  
    var sentence = sheet.getSheetByName('sheet名').getRange(i,2).getValue();
   
    var payload  = {
      'text'      : sentence,
    };
 
    var options = {
      'method'      : 'post'                 ,
      'contentType' : 'application/json'     ,
      'payload'     : JSON.stringify(payload),
    };
 
    var url = 'incoming Webhooksの設定で得られるWebhookURLを代入';
    UrlFetchApp.fetch(url, options);
  } 
}

最後に自動投稿の時間指定についてです。時間指定は編集>現在のプロジェクトトリガーを選択すると 以下のような画面で毎分時日週月で自動投稿を設定することができます。 f:id:khirohisa:20170825135228p:plain 例えば、毎日9時~10時などに定時投稿すると朝の数値チェック等に便利そうです。

簡単な説明になりましたが、SpreadSheetによるSlack投稿の利点は簡単なスクリプト程度で様々なカスタマイズができることだと思うので慣れてきたらやっていくと良さそうです。 参考になるページを貼ります。 www.minemura-coffee.com

箱根でデータ分析部開発合宿をしました(小田原・箱根おすすめグルメ情報付き)

こんにちは、データ分析部の久保です。 データ分析部では四半期に一度ぐらい開発合宿を行っています。 参加は任意でもちろん業務としてカウントされます。

合宿編

今回の合宿場所は以前も使用したAirbnbのこちらの部屋を使いました。

www.airbnb.jp

ホストのErikoさんも丁寧に対応してくれるし、部屋はとてもきれいで8~10人の宿泊にはかなり快適です。 ただ1点備え付けのwifiにつながりにくいという欠点があったので、今回は予めwifiレンタルをしていくことにしました。

【国内用】当日発送で高速WiFiをレンタル | WiFi東京RENTALSHOP

初日のチェックイン時刻までは途中小田原に立ち寄って、小田原の商工会議所の会議室を借りて各自作業しました。 f:id:beatinaniwa:20170722144653j:plain

今回各自が取り組んだテーマはいくつか例をあげると下のようなものでした

- 「テキストアナリティクスシンポジウムでの発表に向けた実験データの整理と再実験」
- 「ログデータの異常値検出」
- 「広告CTR予測モデルの作成」

合宿中には異常検知の手法についてディスカッションしていたときに確率分布の話題になり、こんな名言(?)も出ていました。

夜には箱根湯寮で温泉を楽しみ、晩御飯を食べながらメンバーの親交を深めました。

www.hakoneyuryo.jp

グルメ編

さて開発合宿の楽しみといえば現地でのおいしい食事があります。 初日のお昼は小田原の海鮮料理を食べました。

サカナキュイジーヌ・リョウ (SAKANA CUISINE RYO)

海鮮ちらし、とくに生しらすは絶品でした。 f:id:beatinaniwa:20170724155734j:plainf:id:beatinaniwa:20170724155755j:plain

また2日目は箱根から小田原に向かう途中に風祭で途中下車し、うなぎを食べに行きました。

うなぎ亭 友栄

友栄は食べログのうなぎランキング全国3位(7/24現在)にもなっていて、行く前から相当期待が高まっていましたがその期待をまったく裏切ることない味で最高でした。箱根近辺に行った際にはぜひ立ち寄ることをおすすめします。 今まで食べたうなぎの中でも個人的には相当上位でした。

(時間帯によるかもしれませんが30~1時間ぐらいは待つ覚悟をしていったほうが良い気がします)

f:id:beatinaniwa:20170724155811j:plain

開発合宿は日頃なかなか手を付けられない中長期的なタスクに取り掛かるのにはとても良い方法だと思います。 次の開発合宿をどこでやるか、今から楽しみにしています。