Gunosyデータ分析ブログ

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

サマーインターンシップ2018開催報告

こんにちは、Gunosyデータ分析部内定者の桾澤と片木です。今年も昨年同様エンジニア向けデータ分析サマーインターンシップを実施しました。
学生に混ざり、メンターアルバイトとして参加したので、その様子や課題に取り組む上での気付きなど実際の写真も交えながら紹介します!

Gunosy Summer Internship 2018 について

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

本年は「データ分析コース」と「サービス開発コース」の2つのコースが実施されました。 本記事で紹介するデータ分析コースでは、Gunosyが普段の業務で取り組んでいる課題に近いものをコンペ形式で取り組んでもらいました。 期間は3日間で講義やコンペを行い、 コンペ優勝者には昨年と同様賞金10万円が、2位3位の人にもお肉のギフトカタログが贈呈されます。

グノシーアプリの実際のニュース記事データを触り、試行錯誤を繰り返しながら精度を競い合うものです。 その狙いとして、派手なイメージがあるデータ分析は実際にはデータの整形や仮説検証の繰り返しなど地味ではあるが重要な作業が多いということを参加者の方に体感してもらうことです。

data.gunosy.io

講義

1日目にはVP of Technologyの小出からGunosyにおけるデータ分析について講義が行われました。

f:id:moyomot:20181009162817j:plain

講義内容は

  • Gunosyはデータに基づく意思決定を行っている
  • プロダクトを改善した人が偉い
  • 失敗を恐れて行動しないより、たくさん失敗したほうがよく、またそのような環境が整っている

といったGunosyの理念が詰まった話でした。

最終日の3日目には共同創業者である吉田から昨年同様に「Gunosyの歩みについて」の講義が行われました。予定されていた時間を超えて質疑応答が活発に行われました。

f:id:moyomot:20181009165706j:plain

課題について

1日目の講義、ランチを終えたあとにインターンの課題発表が行われました。今回のテーマは「グノシーアプリ内で表示される記事のメディア分類」です。

グノシーは「ニュースキュレーションアプリ」であるため、様々なメディアのニュース記事を配信しています。その記事がどのメディアから配信されたものかを本文やタイトル等から分類することが今回の課題です。

この課題はテキスト分類でありがちな「カテゴリ分類」ではなく「メディア分類」であるため、カテゴリ分類でよく使われるLDAやWord2Vecが必ずしも有効ではないというのが特徴になります。

その点に苦戦した人も多くいたようで、結果上位に食い込んだ人の特徴量自体は意外にシンプルなものだったりという結果に自分も含めて驚かされました。データ分析、モデル作成における前処理の重要性を学べる課題だったのではないかなと思います。

f:id:moyomot:20181009163546j:plain

Kaggleのように自分の順位やスコアはダッシュボードで確認できるような仕組みを取り入れています。他人のサブミットに一喜一憂したり、熱い戦いが繰り広げられました。

作業環境

分析、モデル作成の作業はJupyter notebook上で行いました。 その環境をよりセキュアに、より高速に構築するために、Amazon Workspacesを取り入れました。 事前に社員が各種Pythonのライブラリのインストールなどを行ったWorkspacesを用意し、学生は提供された環境で作業を行いました。
メリットとして学生各人が環境構築にかかる時間を短縮でき、セキュアにデータを扱えるという点があります。

ランチ・おやつ

計3日のインターンの中で1日目と3日目はメンターの社員とともに外でランチをとりました。グループごとにそれぞれが各々の食べたいもの等を意見を聞いた上で六本木周辺のお店でごはんを食べつつ、自己紹介や課題への取り組み方など様々な交流を行いました。

2日目は様々な社員と社内で弁当を食べました。データ分析エンジニアだけでなくインフラやサーバーサイドのエンジニアとの交流で、実業務に関する話から、社内での笑い話など様々な話題で盛り上がりました。

また、各日程の中で合間合間におやつタイムを設け、お菓子をかじりながらスキップヒルで社員と交流する時間を設けました。

学生であるうちにはわからないようなことが様々な社員から聞けるいい時間だったと思います。

f:id:moyomot:20181009172958j:plain

結果発表

3日目のワークの終了と同時に社員がインターン生の結果を確認します。評価方法はKaggleと同様にpublicとprivateに分けられたデータのうちprivateでのスコアで最終的な順位を決定しました。このことはレギュレーションで触れられていたのですが、それに気付かずpublicでのスコアを追求した結果、privateで最終スコアがガクッと悪くなることもあり得り、そこもポイントの一つであったかなと思います。

f:id:moyomot:20181009172727j:plain

インターン参加者の感想

第一回(9/4~9/6)

杉山さん(優勝)

  • 分析に用いた手法

    様々な試行錯誤の中で、結果が改善したものを以下に列挙することで、最終的な手法の説明とする。

    1.title, contentの全ての文章をmecabで分かち書きし、出現頻度の高い単語上位N個を求めた。 その単語たちで、title, contentの文をそれぞれBoWによるベクトルに変換した。 その2つのベクトルを結合したものを入力とし、scikit learnのLogisticRegressionを用いて分類器を学習した。 ハイパーパラメータは基本的にデフォルトを用いた。 出現頻度上位10000単語を入力とすることで、正答率は90.0%となった。

    2.created_atを、月・日・時・分・秒に分解し、それぞれ単純にonehotベクトル化した。 例えば、月なら(月-1)に1が立っている12次元のベクトルにした。それらを1.の特徴ベクトルに結合したものを入力とした。 結果、正答率は94.3%となった。

    3.LightGBMという手法をLogisticRegressionの代わりに試してみた。 結果、正答率は95.0%となった。

    4.created_atから、何曜日かを求め、onehotベクトル化し入力に加えた。 結果、正答率は95.2%となった。

    5.LogisticRegressionとLGBMを2つ学習した。出力される確率分布を算術平均し、その分布のargmaxを出力のラベルとする、というやり方でアンサンブルした。 結果、正答率は95.9%となった。

    6.文の最初の方の文字が特徴的だと思ったので、文の最初のx文字をy次元のonehotベクトルにして入力に加えた。

    最初の2文字を3000次元のonehotベクトルにすることで、正答率は96.2%となった。 7.確率分布の平均のとり方を算術平均でなく、調和平均にしてみた。 結果、正答率は96.3%となった。この手法がsubmitした中で最善の手法となった。

  • 参加してみての感想

    どのようなモデルを用いるか、よりもデータに含まれる情報をどれだけ活用できるか、というところがデータ分析で結果を出すうえで重要なのだろうだと感じた。

    また、試行錯誤をいかに高速にできるか、という点も重要に感じた。 コンペ形式で、数字を競うというのは非常に面白かった。

    また、インターンシップでgunosyの考え方を学んだり、他の参加者や社員の方と話ができ、有意義だった。

工藤さん

  • 分析に用いた手法

    説明変数を投稿メディア(目的変数)ごとに集計した結果,

    1, 記事の投稿時間・曜日,及び記事のタイトルと本文の文字数の傾向がメディアによって異なること

    2, タイトルと本文が一致する記事を投稿するのはごく限られたメディアであること

    がわかりました.

    上記の特徴量に加え,単語Tf-Idfや文字n-gram(n=1,2,3),さらにfastTextによる文書ベクトルを結合したものを特徴ベクトルとしました.

    分類モデルには線形SVMを選択しました.

  • 参加してみての感想

    短い時間の中で成果を出すためには,サイクルを早く回せる軽量なモデルを選択することに加え,現状のモデルの欠点をしっかり分析することも重要だと感じました.

    実際,混同しているメディアを分析したところ単語レベルの違いはないが改行の仕方に違いがあるとわかり,文字n-gramを導入することで正解率が4〜5%改善しました.

    短い期間でしたが,実務に近い分析タスクという貴重な経験をさせていただいただけでなく,社員の方々の話を沢山伺えて大変充実した3日間でした.

谷口さん

  • 分析に用いた手法

    簡単に言うと、「データを見て特徴量を考え、有用な特徴量を全部つなげて、ロジスティック回帰でラベルを判定する」です。

    基本的には、特徴量の抜き差しを行っていました。そこそこ良いモデルが見つかれば、モデルをチューニングするよりも特徴量を抜き差しするほうが効くだろうと考えたからです。

    採用した特徴量の例は、「タイトル・本文それぞれのbag of words」、「タイトル・本文それぞれに含まれるアルファベット・ひらがな・カタカナ・漢字それぞれの割合」などです。

    後者についてですが、データを見る中で、政治的なニュースのタイトルは、漢字の割合が非常に多く、海外セレブのニュースのタイトルには、カタカナの割合が非常に多いといったことに気づいたので採用しました。

    本インターンは個人戦でしたが、一人では思いつかない考えを他の方から得るという場面もありました。

    休憩時間に同じ班のうえむら君から聞いた、「曜日」を使うという考えです。「タイトル」、「本文」にばかり着目していて、「日付」には目を向けていなかったので、なるほどと思いました。 うえむら君、ありがとうございました。

    残り時間が少なくなってからは、ロジスティック回帰で推定されたラベルをルールによって修正していました。

    推定を回す時間がないと判断したのです。例えば「『GIF画像』がタイトルに含まれるときは絶対このメディア」といったルールをできるだけ探して、そのとおりに修正しました。

  • 参加してみての感想

    「データ分析」というものが何なのか漠然としかわかっていなかったので、その一部だけでも触れられたのはよかったです。

    反省点としては、「機械学習の基礎的なやり方でわかっていない部分がある(検証セットを作っていなかった、など)」、

    「bag of wordsを自家製のやり方で作っていたためか、何度もワークスペースを落としてしまった」といったことが挙げられます。

    何度も再起動をしてくださった森本さん、すみませんでした。そしてありがとうございました。

f:id:moyomot:20181009171326j:plain

第二回(9/12~9/14)

濱下さん(優勝)

  • 分析に用いた手法,方針

    今回のインターンシップ第二回に参加した濱下です.

    コンペティションは優勝という始まる前は予想もしていなかった結果になり,非常に嬉しいです.

    今回用いた手法と感想を述べたいと思います.

    私は機械学習のライブラリを使って実装したことがほとんどなく,正しく予測できるか不安だったので,まずサブミットすることを目標にしました.

    最初なのでシンプルに文章を形態素解析し,それぞれの要素がTfidfの疎行列を特徴量にして学習させるという方針で進めました.

    1時間ほど試行錯誤してサブミットしたところ,まともなスコアが確認できたので,それをベースラインと考えて道筋を立てることができました.

    次に様々なモデルを試したいと思い,ライブラリにあるモデルを試していきました.

    その結果LightGBMが良い精度だったので,モデルは主にLightGBMで進めました. 最終的に用いた手法としては,まずタイトルと本文を連結し,それに対して前処理として特徴があるパターンをトークン>化します.

    次にトークン化したものをuni-gramモデル,bi-gramモデル,tri-gramモデルを用いてTfidf値を出し特徴量とし,LightGBMとロジスティック回帰で学習させ,それぞれの出力を加重平均し求めるものでした.

    このような前処理をしようと思ったのはデータを眺めたり,正規表現でマッチしたものをカウントすると,ほとんど同じメディアに割り振られるパターンがあるということがわかったからです.

    そこで,これらのパターンをトークンに置き換えることで精度の向上が計れると考えました.

    MeCabで形態素解析する際に,連続したアルファベットは固有名詞と判定されるということに気づいたので,正規表現でマッチしたものを通常の文章にはないようなアルファベットの羅列に置き換えることで,ユニークなトークンにすることができました.

    この手法はトークン化して,N-gramモデルを用いるため,様々な特徴(連続して改行があるなど)を得ることができ,精度が上がると考えられます.

  • 参加してみての感想

    時間や計算資源が限られている中で,どれだけパフォーマンスを出せるかというのが求められているインターンだと感じました.

    そのため,精度を上げるために行うことを取捨選択しなければいけませんでした.

    今回優勝できたのはその辺りが上手に出来た結果だと思います.

    インターンシップ中や懇親会では,社員の方々と趣味や会社の話など,色々な話を聞くことが出来て非常に楽しかったです!

    また,機械学習を実装するきっかけとして,私のように機械学習の理論を授業や独学で勉強したけれど実装はあまりしてこなかった,という人にはうってつけのインターンシップだと思いました

宮尾さん

  • 分析に用いた手法,方針

    特徴量としては、ニュース記事のタイトルと内容と、配信日時や曜日を採用しました。

    タイトルと記事内容のベクトル化については、試行錯誤の結果MeCabで分かち書きしてからTF(単語の頻度)を用いることにし、最終的な分類モデルとしてはLightGBMを使用しました。

    終盤は0.1%を争う展開となり、過学習の懸念もありましたが、ハイパーパラメータをチューニングしていくことで少しずつ精度を上げていきました。

    かなり試行錯誤しましたが、振り返ってみれば比較的シンプルなモデルで良い結果を出せたと思います。

  • 参加してみての感想

    個人戦ということで殺伐とした雰囲気になるかと思いきや、グループ分けされていることもあり、楽しく取り組むことができました。(終盤はやはり辛かったですが。笑)

    いわゆるデータコンペに参加するのは初めてだったので、自信はありませんでしたが、これまで身につけたことを総動員できる良い機会であったと思います。

    一緒に参加した仲間達を含め、企画・運営していただいた皆様、この度は大変貴重な経験をさせていただきました。本当にありがとうございました!

松丸さん

  • 分析に用いた手法,方針

    分析には、分類器としてSVMを、特徴量としてSentencePieceとMeCabによって単語分割したものをそれぞれTF-IDFで変換したものと日付情報をone-hotベクトルにしたものを用いました。

    SPを使おうと思ったきっかけは、素朴なモデルのエラー分析をしていて「記号の半角全角の違いなどでしか識別できそうにないメディアがある」ということに気づき、原理的に未知語の存在しないSPならその辺を捉えられるのではと考えたからでした。

  • 参加してみての感想

    実践的なデータ分析(機械学習)をしたことがなかったのでいろいろセオリーやノウハウを知れてよかったな、ということと、実世界の自然言語処理はけっこう泥臭いな、ということです。

    今回自分はルールベースでやることを嫌ってシンプルなモデルを設計しましたが、優勝した人のコードを見せてもらったら正規表現をガリガリ書いていて、今度こういう機会があったら自分ももっとデータと殴り合っていこうと思いました。

    というか、このインターンの直後から研究室で新しく自然言語のデータセットの整備をすることになったのである意味ではさっそく経験が生きています。ありがとうございました。

f:id:moyomot:20181009171333j:plain

メンター総括

メンター(及び解答者)として参加したサマーインターンシップの気づきについて報告し、ブログの締めとさせていただきます。

桾澤

このブログ内ではさもカテゴリ分類の手法よりもシンプルな特徴量が効くと知っていたかのように書いていますが、 実際にはそうではなく自分ももれなくWord2Vecなどが特徴として重要であると考え実装を行いました。 ところが実際にはあまり精度が出ず、それから改めてデータを眺めて特徴を探し始めました。 データ分析において重要なことはやはりEDAであるということを改めて痛感した形となり、 メンターとして参加したにもかかわらずインターン生以上に学ぶことが多いインターンになったのではないかなと思います。 また、実際に用いた特徴量はngramのtfidfやLSA、タイトルの長さや記号の数など様々なものを用いました。

片木

私はメンターとして参加しましたが、夏のインターンシップに参加するのはこれが初めてだったので、一参加者として課題に取り組みました。 メンターとしては参加者の席を回りながら躓いている人をサポートしていきました。 今回は複数の班に分けて作業をしたのですが、個人戦ということもあり躓いたときに班内で質問しあったりしづらかったかなと思いました。 来年度は班でチームを組み、チーム同士で知見を共有しながら精度を競い合うというのも面白いかもしれません。

データ分析、機械学習に興味のある学生はぜひ2019年のサマーインターンシップに参加してください!