Mahoutで体感する機械学習の実践

第9回(最終回) ナイーブベイズを用いてテキスト分類を行う

この記事を読むのに必要な時間:およそ 5.5 分

テキスト分類の流れ

前回は理論編として,自由回答式アンケートの分析手法の1つである,アフターコーディングの自動化方法について解説しました。今回は実践編として,Mahoutのナイーブベイズ実装を用いたテキスト分類の手順を見ていきましょう。

今回も,記載しているコマンドおよびサンプルコードはMahoutのバージョン0.7とバージョン0.8の双方で動作します。

今回取り上げるMahoutのナイーブベイズ実装を用いたテキスト分類のおもな流れは,以下のようになります。

  1. 形態素解析器を用いて,学習データの各文章を分かち書く
  2. 分かち書きされた学習データをシーケンスファイルへ変換する
  3. シーケンスファイルをベクトルファイルへ変換する
  4. ベクトルファイルの学習データを用いてモデルを作成する
  5. 生成したモデルの精度をテストする
  6. モデルを用いてテキスト分類を行う

サンプルデータを準備する

今回の学習データには,以下のサンプルデータを利用します。

サンプルデータは,ファミリーレストランのアンケートをシミュレートした65件の回答になっています※1)⁠

今回のサンプルデータは,1つの回答が1つのテキストファイルで構成されています。

ディレクトリ構成は以下のようになっており,回答が分類されるカテゴリ名がディレクトリ名となっています。

  • learning-data/food-negative ⇒ 味に関する否定的な回答
  • learning-data/food-positive ⇒ 味に関する肯定的な回答
  • learning-data/price-negative ⇒ 価格に関する否定的な回答
  • learning-data/price-positive ⇒ 価格に関する肯定的な回答
  • learning-data/service-negatie ⇒ サービスに関する否定的な回答
  • learning-data/service-positive ⇒ サービスに関する肯定的な回答
  • learning-data/else ⇒ 上記いずれにも該当しないその他の回答

今回のサンプルデータは学習データとして利用するため,正しいカテゴリのディレクトリ以下に各回答がすでに配置されています。

※1)
実際に精度の高いモデルの生成するためには,多くの場合において,より大量のデータが必要になります。

テキストの分かち書きを行う

前回解説したように,今回はモデルを構成する特徴として単語を利用します。

しかし,日本語の文章は英語のように各単語がスペースで区切られていないため,このままでは単語を利用することが困難です。そのため,まず形態素解析器を用いて,以下のように文章を単語に分かち書く必要があります。

分かち書き前
ハンバーグが中まで火が通ってなかった。
分かち書き後
ハンバーグ が 中 まで 火 が 通っ て なかっ た 。

日本語の分かち書きの機能はMahoutには用意されていないため,今回のサンプルデータには,すでに以下のディレクトリ以下に分かち書きが済んでいるテキストファイルを用意しています。

wakati-learning-data/food-negative
⇒味に関する否定的な回答の分かち書き済みテキスト
wakati-learning-data/food-positive
⇒味に関する肯定的な回答の分かち書き済みテキスト
⁠以下,省略)

なお,今回のサンプルデータの分かち書きには形態素解析器にmecab辞書にはIPA辞書を利用しています。mecabは現時点(2013年10月29日)の最新バージョンである,0.996を利用しています。

テキストファイルからシーケンスファイルを生成する

Mahoutのナイーブベイズ実装で利用する学習データのファイルフォーマットはテキストファイルに対応しておらず,ベクトルファイルである必要があります。このベクトルファイルは,まずテキストファイルからシーケンスファイルを作成し,次にこのシーケンスファイルから作成します。

そのため,まずは分かち書かれたテキストファイルからシーケンスファイルを作成します。これには,以下のようにMahoutのseqdirectoryコマンドを利用します。

mahout seqdirectory -i file:///home/yamakatu/gihyo-mahout-nb-sample/wakati-learning -o gihyo-mahout-nb-sample/seq-learning

seqdirectoryコマンドには,おもなオプションとして以下があります。

  • --input (-i) ⇒ 入力データ
  • --output (-o) ⇒ シーケンスファイルの出力先
  • --chunkSize (-chunk) ⇒ ファイルの分割サイズ(デフォルトは64Mbytes)
  • --keyPrefix (-prefix) ⇒ 指定した文字列がKeyのprefixに利用される
  • --charset (-c) ⇒ 文字コードを指定(デフォルトはUTF-8)

生成されたシーケンスファイルの内容は,本連載の第5回目でも利用したseqdumperコマンドで確認できます。

mahout seqdumper -i gihyo-mahout-nb-sample/seq-learning

無事,以下のような内容が出力されたでしょうか?

(略)

Key: /price-positive/65.txt: Value: ここ の コーヒー は , 注文 が 入っ て から エスプレッソマシーン で 入れ て くれ て いる ので , とても コス パ が いい と 思う 。

Key: /price-positive/62.txt: Value: ランチ セット は お 得 で 良い と 思う 。

(略)

出力された内容からわかるように,seqdirectoryコマンドはファイルのパスをKeyに,テキストファイルの内容をValueとして,シーケンスファイルを作成します。

シーケンスファイルからベクトルファイルを作成する

次に,作成したシーケンスファイルをベクトルファイルへ変換します。ベクトルファイルへの変換には,以下のようにMahoutのseq2sparseコマンドを利用します。

mahout seq2sparse -i gihyo-mahout-nb-sample/seq-learning -o gihyo-mahout-nb-sample/sparse-learning -a org.apache.lucene.analysis.WhitespaceAnalyzer

今回は最初に分かち書きを済ませているため,各単語間はスペースで区切られています。そのため,アナライザとしてWhitespaceAnalyzerを利用します。

成功すると,以下のように,出力先にtf-vectorsとtfidf-vectorsが生成されます。ベクトル以外にも,df値,辞書ファイル,単語の出現回数などが生成されます。

[yamakatu@localhost data]$ hadoop fs -ls gihyo-mahout-nb-sample/sparse-learning
Found 7 items
drwxr-xr-x   - yamakatu supergroup          0 2013-10-03 10:35 /user/yamakatu/gihyo-mahout-nb-sample/sparse-learning/df-count
-rw-r--r--   1 yamakatu supergroup       1860 2013-10-03 10:34 /user/yamakatu/gihyo-mahout-nb-sample/sparse-learning/dictionary.file-0
-rw-r--r--   1 yamakatu supergroup       1993 2013-10-03 10:35 /user/yamakatu/gihyo-mahout-nb-sample/sparse-learning/frequency.file-0
drwxr-xr-x   - yamakatu supergroup          0 2013-10-03 10:35 /user/yamakatu/gihyo-mahout-nb-sample/sparse-learning/tf-vectors
drwxr-xr-x   - yamakatu supergroup          0 2013-10-03 10:36 /user/yamakatu/gihyo-mahout-nb-sample/sparse-learning/tfidf-vectors
drwxr-xr-x   - yamakatu supergroup          0 2013-10-03 10:34 /user/yamakatu/gihyo-mahout-nb-sample/sparse-learning/tokenized-documents
drwxr-xr-x   - yamakatu supergroup          0 2013-10-03 10:34 /user/yamakatu/gihyo-mahout-nb-sample/sparse-learning/wordcount

tf-vectorsとtfidf-vectorsの内容は,本連載の第5回目でも利用したvectordumpコマンドで以下のように確認することができます。

mahout vectordump -i gihyo-mahout-nb-sample/sparse-learning/tfidf-vectors

tf-vectorsとtfidf-vectors以外のファイルは,これまでと同様にseqdumperコマンドで内容を確認することができます。

著者プロフィール

やまかつ(山下勝司)

開発/インフラ/統計,機械学習/プロジェクトマネージメントをこなす器用貧乏。最近はビッグデータ,Hadoop,機械学習あたりに夢中。

株式会社マーズフラッグ 先端研究開発本部所属。

趣味は妻と子供と過ごすこと。

Twitter:@yamakatu
Facebook:http://www.facebook.com/katsushi.yamashita.9

コメント

コメントの記入