BoW+SVMで文書分類(2)

はじめに

Livedoor Newsコーパスを学習データとして、カテゴリ分類する分類器を作成する記事の続き。

前回、文書分類を行う為の前準備として、各文書を数値化(ベクトル化)するところまでを行った。
今回は、前回作成した文書ベクトルをインプットにSVMを使い文書分類器を作るところまでを行う。

Livedoor Newsコーパスをトレーニングデータとテストデータに分割

Livedoor Newsコーパスは、カテゴリ毎にディレクトリが切られており、その中に1文書1ファイルで作成されている。このディレクトリ名がカテゴリ(教師ラベル)で、各ファイルをベクトル化したものをインプットとして機械学習させる。
また、作成した文書分類器の精度を検証する為のテストデータもこのLivedoor Newsコーパスのデータを使うこととする。
各カテゴリ毎に、80%を学習用データ、20%をテスト用データとして分けておく。

SVMとは

サポートベクターマシン(SVM)とは、教師あり学習データから、各データ点との距離が最大となるマージン最大化超平面を求めることでパラメータを学習する方法である。
話を単純にする為に、下図のような2次元平面の赤点のデータと緑点のデータ(教師ありデータ)を考えてみる。

svm

上図のように赤点と緑点を分割する最適なラインを求めることで、未知のデータに対してもそのラインの左上にあるのなら赤グループ、右下にあるのなら緑グループと分類することができるようになる。
ただし、赤点と緑点を分けるラインは複数考えられれ、上図の例ではいくつかの例としてH1からH3を描いている。
サポートベクターマシンは、各点からラインへ垂直に伸ばした線の距離(マージン)を最大化するようなラインのパラメータを学習する。
今回の例ではマージンが最大となるH1のパラメータが求められる。

上図は単純な2次元の線形サポートベクターマシンの例であるが、今回は300次元のデータに対して、複数カテゴリへの分類を非線形SVMを用いて行ってみる。
尚、SVMには非線形のカーネル関数が複数存在するが、今回はRBFを用いて行う。

Scikit-learnのSVMを用いてパラメータ学習

Pythonの機械学習ライブラリであるScikit-learnを用いて実際に分類器を作成してみる。
SVMでは、分類の精度を高める為に、ハイパーパラメータを決める必要がある。
幸いScikit-learnではGrid Searchの機能があり、複数のパラメータをリスト形式で渡してあげることで、最適なパラメータを見つけてくれる。

  • コストパラメータ(C):誤分類をどれくらい許容するのか決定
  • RBFカーネルのパラメータ(Γ):Γ値が大きいほど複雑な決定境界となり、小さいほど単純な境界となる

またScikit-learnでは、学習データを自動でランダムに分割して交差検定(クロスバリデーション)を行ってくれる。
デフォルトでは3-Fold Cross Validationとなっており、データを3分割しての交差検定を行う。

テストデータで精度の確認

さて、分類器のモデルはできたので、最初に分割した20%のデータで分類器の精度を検証してみる。

結果としては、以下の通りなのだが、最終テストスコアが0.795と思ったほどの精度がでていない。
学習データの再調整やSVMハイパーパラメータの調整を行いつつ、再テストを実施し、精度を上げていく必要がありそうだ。

BoW+SVMで文書分類(1)

はじめに

機械学習を用いドキュメント分類を行う為には、文書自体を数値(ベクトル)として扱う必要がある。文書を数値として扱う代表的な方法としては、Bag of Words(BoW)がある。これは、全文書中に登場する単語を並べて、各単語の出現頻度をベクトルで表す表現である。
今回、Livedoor Newsコーパスの各文書をBoWでベクトル化し、そのデータを用いて、カテゴリ分けする文書分類器を作成してみる。

Livedoor Newsコーパスについて

以下のURLよりLivedoor Newsコーパスをダウンロードできる。
Livedoor Newsコーパスは、ニュースカテゴリ毎にディレクトリが分かれている為、文書分類器作成の学習データとして適している。

Livedoor Newsコーパス
9カテゴリ、7386文書

各種インストール

Python3及び以下のライブラリ群を用いて実装した。

  • Mecab、mecab-python: 形態素解析
  • Gensim: Python用トピックモデルライブラリ
  • scikit-learn:Python用機械学習ライブラリ

手順

BoW+SVMでの文書分類器作成までの大まかな手順は以下の通り。

  1. Livedoor Newsコーパスの各文書をベクトル表現に変換
  2. Livedoor Newsコーパスをトレーニングデータとテストデータに分割
  3. SVMを使い学習
  4. SVMのパラメータ調整
  5. テストデータに適用

Livedoor Newsコーパスの各文書をベクトル表現に変換

BoWで各文書をベクトル表現に変換

機械学習を行う前準備として、各文書をBoWにてベクトル表現に変換する。
「はじめに」でも述べた通り、BoWとは全文書中に登場する単語を並べて、各文章でのそれぞれの単語の出現頻度を表したものである。
例えば、以下の2つの文書から各文書のベクトルを求めてみる。

これら2つの文書に登場する全単語を並べると以下の通りとなる。

上記から各文章のベクトルは、1番目の要素=単語”John”の出現回数、2番目の要素=単語”likes”の出現回数、、、といった形で表せる。
ちなみに上記(1)、(2)をベクトルで表すと以下の通りとなる。

実際には、文書量が多いと登場する単語数も膨大となる為、「全文書での出現頻度が極端に少ない単語」「どの文書にも登場するような一般的すぎるような単語」などは外してベクトルを作成する。
今回は、「出現頻度が20文書未満の単語」及び、「30%以上の文書で登場する単語」を排除した。この時点で、登場する総単語数は約9000となり、9000次元のベクトルとなった。

TF-IDFによる重み付け

ここで作成したBoWモデルに対して、より文書の特徴を捉えられるようTF-IDFを用いて重み付けを行った。
TFとはTerm Frequencyの略で、ある文書中の単語の出現頻度を表している。
DFとはDocument Frequencyの略で、どれくらいの文書でその単語が現れたのかを表しており、IDFとは、DFに対して対数を取ったものである。
この2つの値を掛けたものをそれぞれの単語の重みとしている。

LSIによる次元削減

さて、これである文書の特徴を表しているベクトルが作成できたわけであるが、このままではベクトルの次元数が大きすぎる為、学習コストが非常にかかってしまう。また有益な結果を得る為のサンプル数も非常に多くなってしまうのも問題である。
その為、文章の特徴を損なわなずにベクトルの次元削減を行う必要がある。

今回は、LSI(Latent Semantic Indexing)を用いて、次元削減を行ってみる。
LSIとは、SVD(Singular Value Decomposition:特異値分解)を用いた次元圧縮の方法で、単語の持つ潜在的な意味を軸に取ろうという発想である。
LSIを用いて、9000次元から300次元まで圧縮を行った。

今回は、機械学習の前準備として、文書群をそれぞれの文書の特徴を表しているベクトルに変換するところまでを行った。
次回は、これらのデータを用いて、学習及びパラメータ調整を行ってみる。