Goで日本語の文書を前処理して分類器を学習するところまでやってみる
概要
日本語の文書を単純な方法で分類器を学習するところまでの一連の処理をGoでやってみる。 分類器は何でも良いのだけど、先日書いたAdaGrad+RDAを使う。
ラベルが付いた日本語のデータがあるという前提で、以下の流れで進める。
- 文書を文に分割する。今回は「。」で区切る。
- 文を形態素解析して名詞や動詞(表層形)を取り出し、文書をある単語を含む、含まないの二値で表現した素性ベクトルに変換する。
- 訓練データを使って分類器を学習して、できたモデルの中身を見てみる。
データ
下記URLから得られるテキストの一部を使って、ラベルをそれぞれ、「スポーツ」、「政治」、「Go言語」とラベルを付与し、第一カラムをラベル、第二カラムを文書としたCSVに保存しておく。
$cat data.csv
スポーツ,ACミランFW本田圭佑(28)が19日のアウェー、ベローナ戦で...
政治,渕経済産業相が関連する政治団体の資金処理問題で、最も不透明と指摘されて...
Go言語,編集者とこの本を5000部売れたらなという話をしたのをなんとなく覚えている。...
…以降は省略している。
ソースコード
動かしてみる
$./text data.csv > data
$cat data
スポーツ 2:1.000000 スルー:1.000000 本田:1.000000 セリエA:1.000000 アルゼンチン:1.000000...
政治 円:1.000000 なる:1.000000 者:1.000000 向け:1.000000 会:1.000000 収支:1.000000...
Go言語 処理:1.000000 ため:1.000000 Go:1.000000 編集:1.000000 5000:1.000000...
…以降は省略している。これで、dataファイルに素性ベクトルが書き込まれる。 次に分類器を学習する。
$./adagrad -f data -m learn -w model
できあがったモデルの中身を見てみる。
$cat model|grep "^スポーツ"|sort -k3 -nr|head
スポーツ カルロス・テベス 0.600000
スポーツ モチベーション 0.600000
スポーツ アルゼンチン 0.600000
スポーツ ACミラン 0.600000
スポーツ ユベントス 0.600000
スポーツ 抜け出し 0.600000
スポーツ ベローナ 0.600000
スポーツ ブラジル 0.600000
スポーツ セリエA 0.600000
スポーツ アウェー 0.600000
$cat model|grep "^政治"|sort -k3 -nr|head
政治 不透明 0.800000
政治 上回っ 0.800000
政治 関連 0.800000
政治 資金 0.800000
政治 説明 0.800000
政治 観劇 0.800000
政治 経済 0.800000
政治 産業 0.800000
政治 生じ 0.800000
政治 焦点 0.800000
$cat model|grep "^Go言語"|sort -k3 -nr|head
Go言語 インタビュー 0.700000
Go言語 カーニハン 0.700000
Go言語 グーグル 0.700000
Go言語 代わる 0.700000
Go言語 それら 0.700000
Go言語 いくら 0.700000
Go言語 言語 0.700000
Go言語 解決 0.700000
Go言語 覚え 0.700000
Go言語 考え 0.700000
一行が素性の重みを表していて、タブ区切りで左から順に、ラベル、素性、素性の重みとなっている。 たとえば、「カルロス・テベス」という素性の重みは、「スポーツ」というラベルで0.6の重みを持つことを表している。 このモデルでラベルが未知の文書を分類するとき、「カルロス・テベス」が出現しているほどその文書のラベルは「スポーツ」になりやすいし、「不透明」が出現しているほどラベルは「政治」になりやすい。
まとめ
自然言語処理でよく使う単純な前処理をGoで書いた。 あとは、文字の半角、全角の統一とか色々とよくありそうな前処理あたりをもっと調べたい。