Learning自然言語処理(NLP)こんにちはAIチームの戸田です自然言語処理でよく扱われるタスクの一つである文書分類、精度を上げる工夫などはよく見られますが、実務ではどうしてその分類になるのか、その判断根拠についての説明が重要になる場面に多く直面します。いう分野で近年注目されており、昨年のKDD2020のチュートリアルでも扱われていました。本記事では文書分類を行う手法として、古典的なCountVectorizerとロジスティック回帰を使った手法と、近年主流となっているBERTのfine-tuningを行う手法の両方の判断根拠の可視化について紹介したいと思います。5572件のSMSのデータセットで、そのうちスパムSMSが747件あります。以下のコードでダウンロードしてzipファイルを解凍します。smsspamcollection.zip読み込みとデータ分割データを読み込み、正解ラベルと対象の文章を学習用とテスト用にデータを分割します。今回は30%をテストデータとしました。stratify=label_ids)ロジスティック回帰まずはロジスティック回帰を使った分類とその判断根拠の可視化を行ってみます。sklearnのCountVectorizerをつかって文章をベクトル化します。vectorizer.transform(test_sentence)ベクトル化された特徴量をつかってロジスティック回帰の学習を行い、テストデータで精度の確認をします。191ロジスティック回帰の予測結果hamは非スパムです。問題が簡単ということもあり、シンプルな手法ですがそんなに悪い結果ではないと思います。このロジスティック回帰の予測結果を解釈する方法の一つに説明変数をみることが挙げられます。今回文章はCountVectorizerでベクトル化されているので各説明変数の重みを見ることで、その単語が予測にどれだけ寄与したかを見ることができるはずです。以下のような可視化を行う関数を作り、テストデータの予測結果を見てみます。'.join(html_outputs)))テストデータのインデックスを入力すると、対象のデータの文章を、説明変数が正、つまりスパムの予測を強める単語は赤、逆に説明変数が負で非スパムの予測を強める単語は青くハイライトして表示します。この関数を使ってスパムと予測されたものの判断根拠を見てみます。guaranteedやreceive、cashがスパム判断の根拠になっているのは納得感があります。逆に非スパムと判断したものの結果を見てみましょう。meやtheのような具体的な会話で出てくる前置詞に青いハイライトが付けられているのがわかります。moneyのような赤くハイライトされる単語もありますが、それ以上に非スパムの予測根拠となる青いハイライトが多いことから非スパムと予測されているのだと思われます。BERT近年主流となっているBERTのfine-tuningを試したいと思います。コードがかなり長くなってしまったので、本記事では参考にした記事との差分を抜粋して記載させていただきたいと思います。全コードはGithubにアップしましたので、気になる方はこちらをご参照いただければと思います。学習結果は以下のようになりました。210BERTの予測結果Attentionさて、BERTの判断根拠の可視化ですが、簡単な方法としてAttentionレイヤーを使うことができます。Attentionが判断根拠を示しているかは諸説ありますが、実装が簡単なので、まず試してみたいと思います。BERTはhuggingfaceの学習済みモデルを利用します。Attentionの出力をするためにはoutput_hidden_statesをTrueに設定する必要があるので、以下のような形でモデルを定義します。aAttentionは最終層のclsトークンのsumをとっています。このクラスで定義されたモデルを学習し、テスト用のDatasetを使って、ロジスティック回帰でやったような、判断根拠となっているトークンをハイライトする関数を定義します。ロジスティック回帰の用に負のハイライトはできないので、スパムであろうと非スパムであろうと、判断根拠となる部分は赤くハイライトされます。'.join(html_outputs)))以下がロジスティック回帰のときと同じサンプルの結果になりますprizeや電話番号などが強く強調されていますが、全体的にハイライトがついてしまい、判断根拠とするには少し弱いかもしれません。Explainations)という手法があります。詳細は元論文を見ていただくと良いですが、手法の流れを簡単に説明しますと、ある予測結果に対して、対象データの周囲をサンプリングしたデータ(テキストの場合特定の単語を削除)の予測を教師データとして、その予測結果に対する単純な線形モデルを作り、そのモデルから本記事の最初にロジスティック回帰で行ったように予測に効く特徴量を見る、となります。LIMEをBERTに適用するためにpredict関数を作る必要があります。predict関数はサンプリングされたテキストリストを受け取り、各テキストの予測確率を出力します。トークナイザと学習済みのモデルを使って以下のように定義しました。probas]).Tすべての例を記事に載せることはできないのでこれまでにテストしたサンプルから1件ずつサンプリングして見てみます。スパムと判定されたサンプルです。FREEといったスパムに含まれそうな単語がハイライトされています。ロジスティック回帰と同様、負の予測も可視化することができます。青のハイライトが多いことがわかります。サンプリング数や落とす単語数などで結果は若干変わると思いますが、LIMEは比較的直感的な結果を可視化できていると思います。Mapping)という手法を試します。Networkが注目している箇所を可視化する手法です。こちらも詳細は元論文を読んでいただければと思います。得られた重みを以下のコードで可視化します。0.035)plt.show()全体的に高く出てしまうようで、もともとCNNの説明を行う手法ということもあり、あまりうまく判断根拠を可視化できていないように見えます。おわりに本記事では文書分類の判断根拠の可視化手法を比較してみました。Tool)というモデルの可視化をインタラクティブに行うことのできるツールもあるようです。こちらも機会があれば試してみたいと思います。