自然言語処理の分別奮闘記

勉強したこととか

NLP若手の会(YANS)に行ってきた

NLP若手の会、通称YANSに行ってきました。
今回写真を一枚も撮っていなかったのが残念です。部屋にいる時間が少なくて、ほとんど電池が切れてしまっていました。。
Twitterの様子は小町先生がまとめてくださっています。(Togetterまとめ

YANSとは

NLP若手の会 (YANS) は、自然言語処理および関連分野の若手研究者の交流を促進し、若手のアクティビティを高めることを目指したコミュニティです。
(NLP若手の会 第9回シンポジウム)

研究の発表も多々あるのですが、それ以上にNLPの若手な人たちの交流会や親睦会のような役目も大きいようです。特に今年はその色が強かったようで、普段は各々がホテルを取って参加するような形式だったところ、今回は2泊3日の合宿形式でした。様々な方々の協力によって合宿形式の実現ができたそうです。運営委員の方々やスポンサーの方々に感謝です。
特に、ただでさえ安かった参加費が当日に更に安くなっていたことや、交流会の花火代などはスポンサー代によるものだったようです。

なにをしてきたの

正確には公式ページに書いてありますが、大まかには以下のようなことが行われていました。

  • 口頭発表
  • ポスターセッション
  • 招待講演
  • スポンサー発表
  • 国際会議参加報告
  • ハッカソン
  • 交流会企画

この記事では主に

  • 交流会
  • 自分のポスターセッション
  • 印象に残った発表
  • ハッカソン

についてを書きます。(必ずしも時系列順ではないです)

交流会

交流会イベントは数が多く、

  • ビーチバレー
  • 卓球
  • 麻雀
  • カラオケ
  • 花火
  • 懇親会

などなどの企画があり、カラオケ, ハッカソン, 花火, 懇親会に参加しました。ビーチバレーにも参加したかったのですが、ハッカソンに取り組んでいたら参加しそびれてしまいました。フットサルも開催予定だったのですが、ハッカソンと被る時間帯により参加者を集められずやむなく中止に。
何かスポーツもしたかったですが、自然言語処理の方々とカラオケ、花火を楽しみました。(天城越えやばかったです)

今回の交流会企画で一番良かったのが懇親会。懇親会はテレビで見るような宴会場(真ん中に中居さんが通るスペースがあるやつ)で行われました。
席が自由だったので、どこに座ろうかと探していたら丁度社会人参加の二方に挟まれている空席を発見。ここに座るしか無い!と思い座ってみるとビンゴ!以前Twitter上で少し関わったことのある(構造学習について少し教えていただいた)@uchumikさんだったのです!!
ここでお礼をすることもでき、もう一方の隣の@tkngさんとも一緒に企業や経歴の話をしていただいたりしました。なかなか聞くことのできないような話で面白かったです。他にも構造学習の話の流れから他のアルゴリズムの話になったり技術的なお話も聞くことが出来ました。
しばらくお話をしてから席を移動し@unnonounoさんの方へ行き、動的計画法やCFGのtreeが三角形と台形で表せるという、これまた技術的なお話をたくさん聞くことが出来ました。こんな話ばかりで大丈夫かなとおっしゃっていましたがとても面白かったです!
やはりみなさんお酒の席でも技術的な話で盛り上がるのですねw

そんな感じで交流会企画も盛り上がり、個人的には(Twitter上で少し教えていただいただけですが)事前にネットで少し関わった@uchumikさんと実際に会ってお話することができたので良かったです。
後で知ったことなのですが、小町先生曰く@uchumikさんと@unnonounoさんはDPの鬼だそうで、そんなお二方からDPについてのお話を聞けたのは幸運でした。

自分のポスターセッション

YANSでは研究発表も多々あり、自分も 夏休み中に実際に手を動かして作っていたものがあったので、それについて発表しました。
発表内容は「遠距離教師あり学習を用いた複合名詞のアノテーションによる未知語の半自動獲得」です。興味のある方は是非boosterのSlideとポスターのPDFを見ていただけるとありがたいです。(そしてなにかアドバイスをいただけると)
簡単にまとめると、self-trainingのように正解事例を集めるとその集めた正解事例がそのまま語彙として未知語(複合名詞)が獲得できたね。やったぜ。というストーリーです。

ポスター発表をするのは始めてだったのでとても緊張したのですが、若手の会ということなので教えていただく気持ちで発表して気持ちを落ち着かせました。90分のポスターセッションだったのですが必死で説明していたらあっという間に終わってしまっていました。
実際にたくさんの方から意見をいただくことができて、ありがたい限りです。
他にもポスターセッションではどういうところをよく説明するのかわかりましたし、説明してると暑くなってくることも喉が渇くことも体験しましたw思ったよりも体力を使うのですね。
今回の発表内容は実際に手を動かして実験してみたことをまとめていて、Surveyを全くしていなかったので、これからその部分を穴埋めしていこうかなと思います。(distant supervisionって何?self-trainingと何が違うの?と言われても答えられなかった。。)

以下にアドバイスいただいたものをいくつかまとめてみました。ポスターを見ていないとなんのことだかわからないかもしれないです。

  • 全正例を網羅するのが大変ならある程度の量をランダムサンプリングしてアノテーションして実験する方法がある
  • 一回毎の辞書更新に人手介入をするか、人手を介さなくても簡単ないくつかのルールを入れるだけでもノイズはかなり減ることも
  • シード辞書を網羅的なものにするともっと良くなりそう
  • 最終的に形態素解析してみたりして外的評価を試みる(実際に使えるのかどうかわからない)

アドバイス等々を頂き、自分のポスターセッションはとても有益なものになりました。ありがとうございました。

印象に残った発表

印象に残った発表は間違いなく@miorisagaraさんのスポンサー発表なのですが(ぶっちゃけトークがとても面白かったw)、メモに残った(身近に感じた)招待講演の@ta_makinoさんの「研究の現場におけるコードの検証と共有」について箇条書きですがまとめようと思います。
この講演は小町先生もまとめてくださっています。(Togetterまとめ

昔の実験を再現できるか
  • 学生の頃の、あるいはn年前の実験を再現することができますか?
  • できないのであれば、できるようにデータ・コードを管理しましょう
研究室にリポジトリ
  • できるだけ小さな単位で、頻繁にコミットしよう
  • 先生に見てもらうこともできるし、進捗状況もわかる
  • 1ヶ月前の自分は他人、他人にもわかるように共有しておこう
  • 前処理などの小さいスクリプトでも、実験に必要な操作ならばコミット
コードレビューをお願いしよう
  • 一度に大量にお願いするのはやめて
  • 他の人が使う、他の人のを使うときにお願いしたり
  • 下の人に見てもらうのも悪くない、何をやっているのかわかってもらうことができる
  • githubにおいてはpull requestベースでやると自然にコードレビューを組み込める

理想的には論文を査読するように、コードもレビューするような文化になると良い

  • コードレビューをしたことに対する評価があったり
  • コードレビューの経験が実績化したらモチベーションも上がる
  • あいつはコードレビューもいっぱいしてるし、されてるから安心して委託できる
テストコードを書こう
アサーションを出す
  • 仕事では使いづらいが(実際サービス止まったら困る)、研究では積極的に使っていこう
  • 関数・クラスの入り口出口で検査
結合テスト
  • 自明な入力と出力を用意して検査
  • 配布をするなら無効な入力に対してもちゃんとチェックを
  • テストケースをたくさん用意して、まとめて順番にテストする
  • 三角形のプログラムの例のように網羅的にテストケースを用意
  • どういうところをチェックすべきか考えて、必要な部分だけでもチェック
ユニットテスト
  • 関数・クラス単位でチェックする
  • 研究においては特に重要
  • バグが見つかったら再発防止のためにユニットテストをする
  • ユニットテストのライブラリはいっぱいある


  • 上記のようなテストを一発で実行できるようにして、それに通ってからコミットするようにする
  • テストめんどくせー → 既存のコード・ライブラリを使う
  • 良いライブラリはテストコードもちゃんと用意されてる
一般公開リポジトリに登録しよう
  • Readmeに、これをつかうときはこれを引用してねみたいなことを書いておく
  • 人事の人は間違いなく名前で検索する
  • 検索されたときにクオリティーの高いコードが公開されてるとgoodだよね

というようなお話をしていただきました。
これから実践していこうと思います。

ハッカソン

ハッカソンのテーマ

ハッカソンはオープンタスクと共通タスクの2種類があり、共通タスクに参加。 共通タスクではカメリオ*1のログを提供していただきました。
ハッカソンの内容としては、カメリオが表示した記事の中からユーザが実際にクリックする記事を予測して、その精度をチーム同士で競うというものです。具体的には、正解ラベルとして"read"と"show"がついている訓練データから、"read"を正例として学習して、テストデータのラベルを当てにいくというようなタスクです。

自分たちのアプローチ

チーム分けは言語別に、言語によってはバージョン毎に分けれらました。自分はPython2のチーム(4人チーム)になりました。(Python2が多かったのでさらに細分化した)
訓練データ、テストデータを受け取りそれぞれ作業にとりかかりました。きっと素性を考えて分類器を作ることになると思ったので、最初はデータを眺めてどういう傾向があるのかを見ていました。 データを眺めていて疑問に思ったことをカメリオさんに質問していると、showのログはバッチ処理*2で、readのログはリアルタイムにサーバに送っているという情報を得ました。 更に、行動を起こした時間ではなくサーバーに送られてきた時間をログデータにとっているということがわかりました。実際にログデータを見ても、"show"となっている事例はいくつかまとまって同時刻に記録されているのに対して、"read"の事例は時刻が他とずれて記録されていることが確認できました。
これって

で、それなりのPrecision出るんじゃということで、自分はそのコーディングを担当。(実際に運用する上では利用できない素性なので少しずるいですが、、)
他のチームメイトには、

  • 記事のカテゴリがgivenの時のあるユーザーのクリック率を最尤推定で求めるモデル

をデータを見ている間に作ってもらっていました。

最初はテストデータに不備があったとのことで提出できず、他の交流会企画に行くことに。午後は交流会企画のカラオケに参加していたので、ハッカソンの時間がとれず、深夜に同チーム(かつ同研究室)の@Ace12358君と一緒に廊下でハッカソン。昼にやろうと思っていた「時刻ずれてる戦法」を実装して提出しようと思ったら、提出ボタンが行方不明に。。明日提出しようということでその日は寝ることに。
次の日、テストデータの不備を修正したものを受け取ったのですが、テストデータを見てみると気になる点が。なんか正解ラベルのようなものがついているっぽい。しかも全ての事例に"show"のラベルが。。どういうことなのか聞いてみると、テストデータとしては"read"のログは入っていないとのこと。"show"のみのログを見て、最終的にその中から"read"されるものを当ててください、という形式になったとのこと。(readされる記事は必ずその前にshowされている)つまり"read"のログだけ時刻が浮いているという方法はボツに。。。(ここでボツにせずに実行して提出してみればよかった)
2日目から最終日にかけては、当初の予想通りチームメンバー各々が素性を集める作業に。集めた素性は

  • カテゴリID
  • 記事ID
  • はてブ
  • 記事タイトル内の頻出語
  • 記事カテゴリがgivenのときのそのユーザのクリック率
  • カテゴリ毎の人気度

とか色々考えて抽出しました。他にもなんかあったような気がするのですが丁度徹夜して作業してたところなのであんまり覚えてないです。
これらの素性をSVMに突っ込めば分類できるのではというゴリ押し戦法だったのですがSVMが重すぎで学習が終わらず。。最終的には1日目に作ってもらっていた「記事のカテゴリがgivenの時のユーザのクリック率」を適当な閾値で切って閾値以上のものを"read"にするという方法が自分たちのチームのベストスコアになりました。閾値は職人技(提出しては結果を見て考える)で決定してもらいました。
SVMが重すぎたのはどうやらlibsvmというツールを使っていのが原因なようで、liblinearという上位版?を使えば速度はましだったようです。

結果と考察

最終的に結果は4位でした。SVMの方法が提出できていたらどうなっていたのか、ちょっと残念な結果になってしまいました。
しかし、気になる結果が一つ。企業賞を受賞したチームの手法が当初自分たちも考えていた「"read"のログだけ周りと比べて浮いている」というヒューリスティックによるものだったのです。。
ん?なにか気になりますね。だってテストデータにはそもそも"read"のログは存在しないはずなのですから。でも実際に結果の出ているチームがあったのです。恐らく"read"のログが存在しないというのは目眩ましで、本当は"read"のログも存在していて、ラベル名を"show"に書き換えていただけだったのではと推測しています。こっちも提出したらどうなっていたのか、提出すれば良かったです。。

ということで、後悔っぽい終わり方をしてしまいましたが収穫も多かったです。チームメンバーとgithubを使ってコードを共有する経験もできましたし、何より来年から小町研の博士課程に来てくださる@moguranosenshiさんと一緒のチームになって同じタスクに取り組めたことが今回のハッカソンの収穫と言ってもいいですね。

終わりに

色々と書きましたがYANS行って良かったという話です。初めての外部発表もしましたし、NLPな方々とお話できましたし。
ここに書いてあること以外にもたくさん発表がありました。他のブログや公式サイトもチェックしてみてください。

そういえば、写真が一枚もないと思っていたのですが初日に海の見えるマックから撮った写真だけありました。今回三浦海岸で開催されていて海鮮系を食べたかったのですが、どこも混んでいてマックで妥協したのです。。

最後に運営委員の方々、スポンサー企業の方々、本当にありがとうございました。

f:id:uorijuram:20141007033632j:plain

*1:スポンサー企業の白ヤギコーポレーションさんが運営しているキューレーションサービス

*2:ある程度のログが溜まってからサーバに送っている