類似文の自動収集について。
ノートブックはこちら(GitLab)。
ある文に似た文を収集したいする。
これを通常の2値分類で解こうとすると、
- 興味のある文に似たセンテンス
- それ以外のセンテンス
の分類になるが、
- 教師ラベルが必要
- それ以外のデータ(興味のないデータ)にラベル付けするのはめんどう
- それ以外のデータの特徴量は分散が大きい
- ラベルを分けると、それ以外のデータのラベル数が膨大で現実的に網羅しきれない
などなどの色々と問題がある。
現実問題として、自分の興味のあるセンテンスの集合だけが手元にあり、それ以外のデータについては教師ラベルはおろか、データそのものすら手元にない、というケースは結構ある。
自分の興味のあるセンテンス集合については、明示的にラベルを振っていなくても、その集合が特定のカテゴリーのセンテンスからなることを保証できれば、カテゴリー自体をそのセンテンス群のラベルと見なせる。
「それ以外のデータ」のラベルを用いない方法として、以下の2つのアプローチがある。
- ベクトル空間法
- 教師なし学習(OneClassSVMなど)
どちらも、手持ちデータを何らかの手法でベクトル化、つまりセンテンスの分散表現に変換しておく必要がある。
ここの選択はハイパーパラメータなので、TF-IDFでも、LDAでも、Word2vecの平均でもよい。
今回はGiNZAの文ベクトル(トークンベクトルの平均)を使用した。
ベクトル空間法
こちらはイメージが簡単。
- 手持ちデータの分散表現の平均を求める
- 未知データを分散表現に変換する
- 手順1と2で求めた分散表現同士のコサイン類似度を計算する
- 適当なしきい値を設け、コサイン類似度>しきい値(例えば+0.5)なら類似文とする
OneClassSVM
教師なし学習であるOneClassSVMを用いる方法。
OneClassSVMはSVMを改造して、学習データとそれ以外を分類できるようにした学習器。
OneClassの名の通り、学習データには分類したいカテゴリーのデータだけで用意すればよく、それ以外のデータを必要としない。
OneClassSVMはsklearnに実装されている。
実験
日本語のテキスト分類ベンチマークとしてよく用いられるライブドアニュースコーパスを使う。
教師ラベルついてるじゃん、と思うかもしれないが以下のような設定にする。
- データを学習データ、評価データに分ける(1:1)
- 9クラス(IT、映画、スポーツなど)から1クラスを選ぶ
- 選んだ1クラスの学習データで学習する
- 9クラスのすべての評価データで評価する
- 9クラス分類ではなく、9クラスの各データが、手順2で選んだクラスか、それ以外かを識別する
- 最終的な出力は2値分類と同じなのでF値で評価する
- 手順2で選ばなかった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
0 件のコメント:
コメントを投稿