PyCon mini OsakaでCharacter-Level CNNについて話してきた。


東京在住ですが、なぜかグランフロント大阪で開催されたPyCon mini Osakaで登壇して来ました。
osaka.pycon.jp

前日から大阪に乗り込んでました。(久しぶりに弊社の大阪オフィスに行った。)

スライド

発表内容は以下のスライドになります。

www.slideshare.net
(画像がぼやけていてすまない・・・)
最初はCNNやTensorFlowの基礎的な説明をして後半からCharacter-Level CNNについて話しました。

Character-Level CNN

Character-Level CNNのところを説明します。

Character-Level CNNとは

文書を文字(Character)単位で区切ってそれをCNNに通してテキスト分類します。 ※単語単位でないのに注意

今回やること

今回は、テキストからネガティブかポジティブかを判断するタスク(いわゆる感情分析のネガポジ)をこなす分類器を作ることを考えます。
結果から言うと、オリジナル論文*1では上手く行かずに、違うアーキテクチャで上手く行きました。

なぜ文字レベルなのか?

文字レベルで自然言語処理をするというのは珍しいと思いますが(大体は単語レベルで区切る)、そのメリットは

  • 前処理がいらない(日本語なら分かち書きが必要ない)
  • タイポやスペルミスが多い文書でも有効(レビュー,チャットなど)
  • 文書じゃない物にも適応できる(URL, Tex, プログラミングコードなど)

などが挙げられます。

論文

上手くいったアーキテクチャですが、
Joshua Saxe, Konstantin Berlin: eXpose:A Character-Level Convolutional Neural Network with Embeddings For Detecting Malicious URLs, File Paths and Registry Keys(https://arxiv.org/abs/1702.08568)
を参考にしました。
内容はCharacter-Level CNNを使って悪意あるURLやファイルパスを検出するという内容です。
かなり丁寧に書かれていてわかりやすい論文でした。

構成・アーキテクチャ

処理の流れとしては

  1. 文字を低次元に埋め込む
  2. カーネルサイズが違う複数のCNNに入れて特徴を出力
  3. 特徴を一つに結合
  4. 全結合層に通して分類

です。


1の埋め込みは、(文字 × 埋め込み次元)行列を埋め込み層として用意して、対応する文字の行ベクトルだけを更新します。

f:id:tdualdir:20180520142008p:plain:w300
図1.埋め込み層


2については論文に書いてる図を借りると次のようになります。

f:id:tdualdir:20180519210753p:plain
図2.CNNの処理
1×2,1×3,1×4,1×5というサイズのフィルターにそれぞれ通します。
様々なWindowで文字のCooccurrence(共起性)を学習してると考えられます。
f:id:tdualdir:20180519211149p:plain
図3.CNN部分の解釈


3.特徴を一つに結合、4.全結合層に通して分類はそのままの意味です。

TensorFlowで実装してTensorboardのグラフに書くと以下のようになります。

f:id:tdualdir:20180519205644p:plain
図4.アーキテクチャ

日本語のデータセット

日本語のデータセットとして最近公表されたばかりのchABSA-dataset*2を使いました。
上場企業の有価証券報告書をベースに作成されたデータセットで、特徴としては「何が」ポジティブ/ネガティブだったのかと言う情報を含んでいます。
これで、「何が」のネガティブとポジティブの数を比べて多い方を文書全体の感情としました。
その結果、訓練データとテストデータを合わせて2830文書が対象となりました。

結果

結果は以下のようになりました。

f:id:tdualdir:20180519212347p:plain
図6.loss
f:id:tdualdir:20180519212339p:plain
図7.accuracy

データセットが少ないので不安でしたがaccuracyも0.9程度にはなりました。

誤字・脱字に対する強さ

面白いのがここからで、わざと誤字・脱字をしてちゃんとネガポジを判定できるか試してみました。
f:id:tdualdir:20180519212917p:plain
「増加傾向」を「加向」とか、「減少傾向」を「減向」にしても問題なく判定できています。

なので、ここでテストデータの文書の文字を適当な文字に変換した際にどのくらい精度が下がるのかグラフを書いてみました。

f:id:tdualdir:20180519213508p:plain
図8.変えた文字数と精度(character-level)

50文字をランダムな文字に置き換えても精度が8割以上あるのは驚きです。(1つの文書は大体300文字程度なので役1/6が適当な文字と言うこと)

これをMecabを使って単語レベルで区切ってCNNで学習させたword-level CNNでも試しました。

f:id:tdualdir:20180519213821p:plain
図9.変えた文字数と精度(word-level)

50文字も変えると精度は0.5なので全く判別出来てないことになります。

結論

Character level CNNは誤字・脱字に強すぎなんじゃwwww
SNSメッセージ、チャット、レビューなど最適と言える。
さらに日本語だと分かち書きが不要と言うのも魅力的。また、単語で区切ったりしないので辞書が要らず、この実装だけであらゆる言語に対応可能。


終わりに

カンファレンスで発表するのは初めてでしたが、発表練習をするのを忘れていたので時間配分がちょっと不安でしたが、まあまあ時間ぴったりに終わったのでよかったです。
カンファレンスは楽しかった。

コードはここに置いてます。
GitHub - Tdual/char_level_cnn: Character level CNN


ツイッターやっているのでフォローお願いします。
↓今すぐフォローすべきキラキラ アカウント

じゃあの。

*1: Xiang Zhang, Junbo Zhao, Yann LeCun: Character-level Convolutional Networks for Text Classification (https://arxiv.org/abs/1509.01626)

*2: https://github.com/chakki-works/chABSA-dataset