go-active-learningを改良している話(Slackからのアノテーションをサポートなど)

以下の話の続きです、地味に続いています。自分が普段使うツールを改良していくのは楽しいですね。

自分で使ってみて、これは欲しいといったものを追加していってます。社内で紹介したところフィードバックをもらったので、それを踏まえてどうしていきたいか(どうしたか)も書いてみます。

Slackからのアノテーションをサポート

以前はコマンドラインでのアノテーションのみをサポートしていました。Goで書いているので、macでもwindowsでも簡単に動かせるという利点はありましたが、エンジニア以外の人にもアノテーションをしてもらおうと思うとコマンドラインはハードルが高いのも事実です。そこで、slackからもアノテーションできるようにしてみました。もちろん、事例をアノテーションする順番は能動学習で決めています。

使い方はヘルプを見てもらうとよいですが、提示されたURLを見て、pとタイプすると正例としてアノテーション、nとタイプすると負例としてアノテーションされます。リアクションのところについているheavy_plus_sign(プラスのアイコン)やheavy_minus_sign(マイナスのアイコン)は正例/負例として能動学習のモデルに反映されたということを意味しています。slackはURLを投げるとスニペット的なものを表示してくれるので、アノテーションがしやすくなる(ブラウザで開きなおさなくてよい)という効用もありました。

有効な素性の提示

能動学習を使って事例をどんどんアノテーションしていくわけですが、わけも分からずどんどん事例を提示されても「なんでその事例が選ばれてきているんだよ!」という気持ちになってきます。そこで、show-active-featuresオプションを付けて、どういう素性が有効になってその事例が選ばれたのかを表示するようにしました。

% ./go-active-learning annotate cli --input-filename INPUT_FILE --output-filename OUTPUT_FILE --open-url

学習器の出力と正解ラベルが一貫していない事例を見る

数百件以上アノテーションをしていると、「あっ、これと似たような事例、さっき反対側のラベルに付けた気がする…」ということがときどきあります。一貫していない正解データは学習器の精度を落とす原因になるにもなるので、そういう事例はさっとラベルを修正したい。しかし、そういうのをいざ探そうと思うと結構大変です。

こういうのを探す助けになるように、学習器の出力と正解ラベルが一貫していない事例を見るコマンドを作りました。つまり

  • 正解ラベルは1なのに、スコアが負の大きい値
  • 正解ラベルは-1なのに、スコアが正の大きい値

といった事例を表示するということができます。使い方はこんな感じで。不一致の大きい順に出していきます。

下の例では、技術エントリかどうかを判定するためのデータに対して適用しています。facebookがマイナス(技術エントリではない)で出ているけど、正解のラベルは1になっていて、ラベルを付け間違えているっぽい、ということが分かります。

% ./go-active-learning diagnose label-conflict --input-filename INPUT_FILE
Index   Label   Score   URL Title
0   1   -0.400  https://www.facebook.com/   ログイン (日本語)
1   -1  -1.400  http://suumo.jp/town/   SUUMOタウン
2   1   2.000   http://hakobe932.hatenablog.com/    hakobe-blog ♨
3   -1  -2.000  http://r.gnavi.co.jp/g-interview/   ぐるなび みんなのごはん
4   1   32.400  http://www.songmu.jp/riji/  おそらくはそれさえも平凡な日々
5   1   90.000  http://motemen.hatenablog.com/  詩と創作・思索のひろば

もらったフィードバック

最近、go-active-learningを社内で紹介する機会があったので、そこでもらったフィードバックも紹介しておきます。

能動学習で使っている分類器/特徴量抽出器と実際に使う分類器/特徴量抽出器のズレ

go-active-learningでは能動学習をやるために

  • 特徴量抽出にタイトル、本文のBoW
  • 学習器に平均化パーセプトロン

を使用しています。しかし、本番ではもっとリッチな特徴量抽出を使っているかもしれませんし、学習器もSVMやロジステック回帰を使っているかもしれません。こういったズレがある場合、能動学習で提示された順にアノテーションしていっても思ったように効率が上がらないということがありえます(go-active-learningでは難しい事例だと思ったけど、本番の分類器にとっては簡単な事例だった、などなど)。これを防ぐためには、能動学習で使うもろもろと本番で使うもろもろが一緒になっているのが一番ですが、そうすると本番とべったりなツールになってしまいます。色んなところで使える能動学習のツールにしたいなと思うと、完全に一致しないのは仕方ないので、やり方としては

  • 本番に使われていそうな学習器をサポートして、なるべくズレが小さくなるようにする
  • 本番で使われていそうなURLに対する特徴量抽出(キーワードなどのメタデータなどなど)をなるべくサポート、選択できるようにする

などがあるかなと思います。goで数百行程度なので、本番用と一致するように移植するのもそんなに難しくはないとは思います。

ユーザーインターフェイス

便利そうだけど、CLIのみだとエンジニア以外にはハードルが高いという声があったので、今回slackからの入力をサポートしました。tokenの取得の手間はありますが、そこだけエンジニアがやってしまえばアノテーションはslackの画面のみで完結するので、大分ハードルは下げられたのではと思っています。

深層学習による自然言語処理 (機械学習プロフェッショナルシリーズ)

深層学習による自然言語処理 (機械学習プロフェッショナルシリーズ)