教師なし学習による類似文章の収集

2020/06/25

機械学習 自然言語処理

t f B! P L

類似文の自動収集について。
ノートブックはこちら(GitLab)

ある文に似た文を収集したいする。
 
これを通常の2値分類で解こうとすると、

  • 興味のある文に似たセンテンス
  • それ以外のセンテンス

の分類になるが、

  • 教師ラベルが必要
  • それ以外のデータ(興味のないデータ)にラベル付けするのはめんどう
  • それ以外のデータの特徴量は分散が大きい
  • ラベルを分けると、それ以外のデータのラベル数が膨大で現実的に網羅しきれない

などなどの色々と問題がある。
 
現実問題として、自分の興味のあるセンテンスの集合だけが手元にあり、それ以外のデータについては教師ラベルはおろか、データそのものすら手元にない、というケースは結構ある。
 
自分の興味のあるセンテンス集合については、明示的にラベルを振っていなくても、その集合が特定のカテゴリーのセンテンスからなることを保証できれば、カテゴリー自体をそのセンテンス群のラベルと見なせる。
 
「それ以外のデータ」のラベルを用いない方法として、以下の2つのアプローチがある。

  • ベクトル空間法
  • 教師なし学習(OneClassSVMなど)

どちらも、手持ちデータを何らかの手法でベクトル化、つまりセンテンスの分散表現に変換しておく必要がある。
 
ここの選択はハイパーパラメータなので、TF-IDFでも、LDAでも、Word2vecの平均でもよい。
 
今回はGiNZAの文ベクトル(トークンベクトルの平均)を使用した。

ベクトル空間法

こちらはイメージが簡単。

  1. 手持ちデータの分散表現の平均を求める
  2. 未知データを分散表現に変換する
  3. 手順1と2で求めた分散表現同士のコサイン類似度を計算する
  4. 適当なしきい値を設け、コサイン類似度>しきい値(例えば+0.5)なら類似文とする

OneClassSVM

教師なし学習であるOneClassSVMを用いる方法。
 
OneClassSVMはSVMを改造して、学習データとそれ以外を分類できるようにした学習器。
 
OneClassの名の通り、学習データには分類したいカテゴリーのデータだけで用意すればよく、それ以外のデータを必要としない。
 
OneClassSVMはsklearnに実装されている。

実験

日本語のテキスト分類ベンチマークとしてよく用いられるライブドアニュースコーパスを使う。
 
教師ラベルついてるじゃん、と思うかもしれないが以下のような設定にする。

  1. データを学習データ、評価データに分ける(1:1)
  2. 9クラス(IT、映画、スポーツなど)から1クラスを選ぶ
  3. 選んだ1クラスの学習データで学習する
  4. 9クラスのすべての評価データで評価する
  5. 9クラス分類ではなく、9クラスの各データが、手順2で選んだクラスか、それ以外かを識別する
  6. 最終的な出力は2値分類と同じなのでF値で評価する
  7. 手順2で選ばなかった8クラスの学習データは使用していない
  8. 手順2に戻り、最終的には9クラスすべてで繰り返す
     
    また、ベースラインとして、通常のSVMによる多クラス分類も行う。

結果

9クラスすべてについて実験しているが、長いのでdokujo-tsushinの結果のみ貼る。

ふつうのSVM

対象の1クラス VS それ以外の2値分類を9回(9クラス分)やる。実質的にOne-vs-Restという古典的な多クラス分類のやり方に相当。

dokujo-tsushin
              precision    recall  f1-score   support

          -1       0.96      0.99      0.97      3238
           1       0.91      0.68      0.78       446

    accuracy                           0.95      3684
   macro avg       0.93      0.84      0.88      3684
weighted avg       0.95      0.95      0.95      3684

結構いいやんけ!!
 
ここの精度計算に使ったテストデータは、本番運用ではノイズ入りでラベルなしというとんでもないデータ。
 
そのため、学習データの正例と同じクラス(上でクラス1)と分類されたデータの純度が高ければよいので、クラス1のprecision(適合率)が高いほどよい。
 
recall(再現率)は低いため漏れはあるものの、元のデータがノイジーなだけに、用途を考えるとprecisionが高いことに価値がある。

ただし、以下の2つと異なり、学習データに「それ以外」のクラスに分類されるデータも必要になる。

ベクトル空間法

対象クラスの学習データだけを取り出し、特徴量ベクトルの平均を計算する。
テストデータ1件ごとに、平均ベクトルとのコサイン類似度を計算し、しきい値以上だと、対象クラスと同じクラス、以下の場合はそれ以外と判定する。
 
今回はしきい値を0.85とした。

dokujo-tsushin
              precision    recall  f1-score   support

          -1       1.00      0.28      0.44      3238
           1       0.16      1.00      0.28       446

    accuracy                           0.37      3684
   macro avg       0.58      0.64      0.36      3684
weighted avg       0.90      0.37      0.42      3684

こちらは当該データのrecall(再現率)が高く、precisionが低い。つまり、クラス1と分類されたテストデータの中にまだノイズが残ってしまっているということになる。

しきい値は人手で調整が必要。

OneClassSVM

こちらも使っているデータはベクトル空間法と同じ。ただし、しきい値は設定する必要がない。
 
このモデルではサポートベクトルがしきい値に相当し、データから自動で学習される。
 
ハイパーパラメータとして学習データに異常データ(それ以外のデータ)が含まれている割合をしてする必要がある(sklearnではnu)。
今回は学習データに、異なるクラスのデータは混入していないので、nuは小さい値(0.05)にした。

dokujo-tsushin
              precision    recall  f1-score   support

          -1       0.99      0.24      0.38      3238
           1       0.15      0.99      0.26       446

    accuracy                           0.33      3684
   macro avg       0.57      0.61      0.32      3684
weighted avg       0.89      0.33      0.37      3684

ベクトル空間法と同様、クラス1ではrecallが高く、precisionが低くなってしまった。全体的に見てもベクトル空間法とあまり差が無いように見える。

感想

かなりの不均衡データだったにもかかわらず、素のSVMでも十分な性能が出た。
 
ただしこのSVMは「対象クラス」のラベル付きデータに加え、「それ以外のクラス」というラベルがついたデータも学習に使用している。
 
ベクトル空間法とOneClassSVMでは前者しか学習に使用していない。この点で素のSVMは有利だった。
 
ただし「それ以外のクラス」という雑なラベルで良いなら、機械的に集められなくもないので、そのような場合は「ふつうのSVM」+「不均衡データに対する一般的な対策」が最善かもしれない。
 
これが難しい場合は、ベクトル空間法かOneClassSVMになるが、今回の実験では大きな差は観測できなかった。
 
もちろん、これらの結果は、データそのもの、データクリーニング、分散表現への変換方法、ハイパーパラメータ等で変わってくるものと思います。
 
@youmounlp

ラベル

QooQ