文書分散表現SCDVと他の分散表現を比較してみた



今回は、以下の論文の文章分散表現、Sparse Composite Document Vectors; SCDVについて書きます。

https://arxiv.org/abs/1612.06778

実は去年に試しに実装していたのですが、他にネタがないためまだ投稿していませんでしたので、書こうと思います。

SCDVについて

SCDVは、文章ベクトルを取得する方法の1つです。

文章ベクトルを取得する手法はDoc2Vecなど色々ありますが、論文において、取得した文章ベクトルを用いたマルチラベル分類では、他の方法よりも高い精度を出せているようです。

うーむ、ていうか、NTSGってのはなんだ。

すでにここに並べられているモデルさえ、知らないものが多いですが、一旦無視しましょう。

SCDVの方法はそこまで難しくないようです。

文章データから得られる全単語について、Word2Vecベクトルとidf値を計算しておきます。

この単語ベクトルについて、混合ガウスモデルで K クラス分類に学習し、一つ一つの単語ベクトルが各クラスに属する予測確率を単語ベクトルにかけて連結して、単語ベクトル数*クラスタ数に次元を広げるようなことをします。

これにidf値をかけたものが、単語ベクトル Word-topics vector になります。

これを、文章の構成単語について平均をとって、スパースさせたものを、文章ベクトルとして扱います。

実装

実装は以下のGitHubにもあげました。

GitHub: https://github.com/Gin04gh/datascience/blob/master/news_corpus/scdv.ipynb

今回は論文と同じくニュースコーパスのデータを使いました。

ただし、20クラスも分類していると時間がかかるので、5クラス分だけ取得してきて、分散表現のt-SNEの可視化の確認や、分類モデルに使った時の精度の比較を行いました。

準備として、ライブラリをインポートと、scikit-learnからニュースコーパスをダウンロードします。

選んだカテゴリは適当です。

それぞれ

の件数分のニュースデータがあり、計2,800件の文章データになります。

また、以下のパラメータを決めておきます。

いずれの分散表現も文章を単語に分解して作成します。

その時の文章から単語へ分解する関数を用意しておきます。

ストップワードはもっと他にもたくさん入れるべきでしょうが、ひとまずはこのくらいで。

BoW

まずは一番基礎的なBoWで文章の特徴量を表した場合について。

この辺りは sklearn.feature_extraction.text で特徴量作成が用意されているので、積極的に使っていきます。

これをt-SNEで二次元に圧縮して、可視化してみます。

このカラーマップだと、カテゴリごとに綺麗に色が分かれてくれるので見やすいです。

この図では、あまり分かれてくれていないように見えますね。

tf-idf

次にTf-Idfです。

これも sklearn.feature_extraction.text に関数が用意されていますので、すぐ作成できます。

かなり綺麗に分かれてくれているように見えます。

Word2Vec (Average)

Word2Vecは単語ベクトルですが、文章に含まれる単語をこのベクトルで計算して、平均など集約することで文章ベクトルとする方法も、文章の分散表現としてよく利用されます。

Word2Vecは gensim で簡単に学習、ベクトルの変換が可能です。

今回はWord2Vecモデルで表される単語ベクトルの平均(Average)をとって文章ベクトルとしました。

ベクトルの次元数は先ほどのハイパーパラメータで決定した通り、200次元としました。

あとは同様にt-SNEで圧縮して、可視化できます。

これも割と文章のラベルごとに分かれてくれているようです。

同じクラスだけども、さらに別の集団として捉えているようなものも見られます。

ちなみに、書籍で『ゼロから作るDeep Learning』の第2弾が最近登場しており、内容は自然言語処理メインになっていて、Word2Vecの解説なども分かりやすく書いているのでおすすめです。

内容は深層学習に寄っているので、RNNや系列変換モデルについても書いてあります。

系列変換モデルは以前に投稿しているので、よかったら参考にどうぞ。

(adsbygoogle = window.adsbygoogle || ).push({});MLPシリーズの「深層学習による自然言語処理」を読みました。深層学習による自然言語処理 (機械学習プロフェッショナルシリーズ)posted with ヨメレバ坪井 祐太,海野 裕也,鈴木 潤 講談社 2017-05-25 Amazon楽天...

Doc2Vec

文章の分散表現なので、そのまんま、Doc2Vecも試してみます。

こちらも gensim から利用可能。

この辺りの自然言語処理に関しては、scikit-learngensim のおかげでコードもかなりスッキリと書けるようになりました。

なんかお花みたいで綺麗。

ただ、他の分散表現もそうですが、一定数、うまく分かれてくれていない文章が中心辺りに集まって見られるようですね。

SCDV

ここまで、様々な文章ベクトルを表してきました。

SCDVについて同様にやってみます。

論文で実装が公開されていますので、こちらも参考にしながら書いてみます。

https://github.com/dheeraj7596/SCDV

まずは、全ての単語ベクトルを混合ガウスモデルで学習してクラスタリングします。

論文においては、このクラスタ数を変化させた時に、どのように分類モデルの精度が変化するかを調査しています。

これを見る限り、クラスタ数が60以上からは、あまり変化がないように見えますので、クラスタ数は60としました。

後述になりますが、sparsityは4%。

ベクトル次元数は300の方が良いようですが、今回はなぜ200にしているのかというと、単純に間違えました。←

次に、Word-topics vectorを作成します。

単語ごとに、単語ベクトルと各クラスの予測確率、idf値を掛け合わせます。

出来上がった Word-topics vector を用いて、文章ごとにベクトルを作成します。

ふむり。

同クラス内でさらに特徴的な文章の分類を表現できるようになっているような気がします。

ただ、やっぱり微妙にうまく分かれてくれない文章はちらほらいるようで、元々難しい文章については同様に難しい感じなんですかね。

XGBoostで分類精度を比較

さて、これを分類モデルに突っ込んで精度を確認してみます。

論文でもSVMで同様に調べていますが、今回はXGBoostを使ってみました。

おお、SCDVだけ頭一つ抜けていますね。

誤差でたまにBoWやDoc2Vecに劣ることもあるようですが、全体的には精度が上がっているように見受けられます。

むしろこれ見て意外だったのが、BoWがSCDV以外の他の手法に対して良いという点だったり。

可視化ではだいぶ潰されてしまったように見えましたが、潰されたベクトルに良い感じのがあったのでしょうか。

まとめ

SCDVについて書きました。

論文も今回も20newsコーパスデータですが、分類精度の向上が見られました。

もちろんこの辺りはどんな方法でも文章データがどういうものかに依存する部分はあるかと思いますが、実装も難しくありませんし、データに対して様々な文章ベクトルを試して判断すると良いと思います。



 

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です