関口宏司のLuceneブログ

OSS検索ライブラリのLuceneおよびそのサブプロジェクト(Solr/Tika/Mahoutなど)について
<< モデルとなる京都コーパスの量を変えたときのCaboChaの性能を見る | main | CaboChaとKNBコーパスで固有表現抽出を行う >>
CaboChaでKNBコーパスを使う
またまたCaboChaの続きで、今回は京都コーパスではなくKNBコーパス(KNBC)を使う。KNBコーパスは京都コーパスと異なり、タグ情報だけでなく本文情報も含まれているので、この記事の通りのオペレーションを行えば、(途中までは)毎日新聞データを持たない読者も実際にCaboChaの学習や評価を試すことができる。

KNBコーパスにはさまざまな特徴があるが、ここで注目するのは京都コーパスと比較しての下記の点である:

  • データ量が少ない。
  • (大学生が書いた)ブログ記事である。


KNBコーパスは4つのカテゴリ「携帯電話」「京都観光」「グルメ」「スポーツ」のどれかについて書かれたブログ記事に文境界、形態素、係り受け、格・省略・照応、固有表現、評価表現の各種アノテーションを付加した解析済みコーパスである。毎日新聞の記事データにアノテーションを付加した京都コーパスに比べデータ量が約一桁少ない(京都コーパス38400文に対し、KNBコーパスは4184文)。また、ブログ記事ということで新聞記事と比べて「文境界があいまい」「構文構造の解析を困難にする括弧表現」「誤字、方言、顔文字などの多様な形態素」というCGM的な特徴を有する。

このような特徴を踏まえ、今回は次のような評価を行った:

  1. [KNBC-KNBC] KNBコーパスの一部を学習して他の部分のKNBコーパスで評価を行う。
  2. [KNBC-KC] KNBコーパスの全部を学習して京都コーパス(毎日新聞記事)を解析してみる。
  3. [KC-KNBC] 京都コーパスを学習してKNBコーパス(ブログ記事)を解析してみる。


1.はKNBコーパス内部の学習・評価を行うものである。ここでは簡単に522文からなるスポーツカテゴリを評価用に残し、それ以外のカテゴリである携帯電話、京都観光、グルメの全合計3662文を学習することにした。量的には前の記事で作成した chunk.juman.10.1 モデルファイルでのテスト(3200文;エラー率0.2116)に近い量である。

2.と3.はブログ記事と新聞記事のクロス的・相互的な学習・評価のテストであり、ブログ記事を学習してモデルファイルを作成し新聞記事を解析した場合やその逆を行ってみて、解析性能がどの程度になるか見るものである。

結果

前の記事と比較のため、また、自作したツール類が再利用できることなどから、同様にCaboChaのchunkを対象に評価を行った。結果は下表の通り:

テスト名学習データ評価データエラー率備考
KNBC-KNBCブログ記事(携帯電話、京都観光、グルメ)
chunk.juman.knbc-knbc, model.source.knbc-knbc
ブログ記事(スポーツ)
G44.txt, S44-x.txt, O44.txt
0.2989京都コーパス3200文ではエラー率0.2116
KNBC-KC全ブログ記事
chunk.juman.knbc-kc, model.source.knbc-kc
毎日新聞記事
G1011.dat, S1011-x.dat, O1011.txt
0.3214
KC-KNBC京都コーパスchunk.juman.10.10ブログ記事(スポーツ)
G44.txt
0.2969同じモデルを新聞記事に適用した場合のエラー率は 0.1259


KNBC-KNBCテストでは、ブログ記事の3662文を学習したモデルが、量的にはそれよりも少ない京都コーパス3200文を学習したモデルよりもエラー率が高くなった。

KNBC-KCテストは全ブログ記事のコーパスを学習したモデルで新聞記事を解析するテストだが、やはりエラー率はさらに上がった。

KC-KNBCテストはKNBC-KCテストとは逆に、新聞記事である京都コーパスを学習したモデルでブログ記事を解析するテストであるが、同様にエラー率は高かった。

今回作成したプログラム

KNBコーパスのcorpus1ディレクトリを第一引数に指定するとコーパスデータをCaboCha形式のKeitai.dat, Kyoto.dat, Gourmet.dat, Sports.datのデータに出力する knbc2cabocha_chunk.rb というプログラムを作成した:

KNBC_DIR = ARGV[0]

CATEGORIES = ["Keitai", "Kyoto", "Gourmet", "Sports"]

CATEGORIES.each{|category|
  File.open("#{category}.dat", "w"){|ofile|
    Dir.glob(KNBC_DIR+"/KN???_#{category}_*").sort!.each{|article_dir_path|
      File.open("#{article_dir_path}/fileinfos"){|info_file|
        while info_line = info_file.gets
          File.open("#{article_dir_path}/#{info_line.split[1].split(/:/)[1]}"){|ifile|
            chunk_num = 0
            while line = ifile.gets
              next if /¥A# S-ID:/ =~ line # skip the comment line
              terms = line.split
              if terms[0] == "*"
#                ofile.puts "* #{chunk_num} #{terms[1]}"
                ofile.puts "* #{chunk_num} -1D"
                chunk_num += 1
              elsif terms[0] == "+"
                next
              elsif terms[0] == "EOS"
                ofile.puts "EOS"
              else
                ofile.puts "#{terms[0]}¥t#{terms[3]},#{terms[5]},*,*,#{terms[2]},#{terms[1]},*"
              end
            end
          }
        end
      }
    }
  }
}


オペレーションメモ

# KNBコーパスをCaboCha形式に変形しつつ、4つのカテゴリごとのファイルに分ける。
$ ruby knbc2cabocha_chunk.rb ../KNBC_v1.0_090925/corpus1

# 前の記事の習慣に合わせリネーム。
$  mv Keitai.dat G41.dat
$  mv Kyoto.dat G42.dat
$  mv Gourmet.dat G43.dat
$  mv Sports.dat G44.dat

# [KNBC-KNBC] モデルのソースを作成。
$ cat G4[1-3].dat > model.source.knbc-knbc

# [KNBC-KNBC] 学習。
$ /usr/local/libexec/cabocha/cabocha-learn -e chunk -P JUMAN model.source.knbc-knbc chunk.juman.knbc-knbc

# [KNBC-KNBC] CaboCha形式の学習データG44.datから原文テキストファイルS44-x.txtを逆再生
$ ruby make_source.rb 44

# [KNBC-KNBC] cabochaの実行。
$ cat S44-01.txt | cabocha -d /usr/local/lib/mecab/dic/jumandic -M ./chunk.juman.knbc-knbc -O2 -f1 -n0 > O44.txt
$ cat S44-02.txt | cabocha -d /usr/local/lib/mecab/dic/jumandic -M ./chunk.juman.knbc-knbc -O2 -f1 -n0 >> O44.txt

# [KNBC-KNBC] 正解データとcabochaの出力を比較用に正規化。
$ ruby norm_chunk.rb G44.dat > G44-norm.dat
$ ruby norm_chunk.rb O44.txt > O44-norm.txt

# [KNBC-KNBC] エラー率の表示。
$ ruby diff_chunk.rb G44-norm.dat O44-norm.txt 
error = 0.2989 (156/522)

# -----------

# [KNBC-KC] モデルのソースを作成。
$ cat G4[1-4].dat > model.source.knbc-kc

# [KNBC-KC] 学習。
$ /usr/local/libexec/cabocha/cabocha-learn -e chunk -P JUMAN model.source.knbc-kc chunk.juman.knbc-kc

# [KNBC-KC] cabochaの実行。
$ cat S1011-01.txt | cabocha -d /usr/local/lib/mecab/dic/jumandic -M ./chunk.juman.knbc-kc -O2 -f1 -n0 > O1011.txt
$ cat S1011-02.txt | cabocha -d /usr/local/lib/mecab/dic/jumandic -M ./chunk.juman.knbc-kc -O2 -f1 -n0 >> O1011.txt
:
$ cat S1011-16.txt | cabocha -d /usr/local/lib/mecab/dic/jumandic -M ./chunk.juman.knbc-kc -O2 -f1 -n0 >> O1011.txt

# [KNBC-KC] cabochaの出力を比較用に正規化。
$ ruby norm_chunk.rb O1011.txt > O1011-norm.txt

# [KNBC-KC] エラー率の表示。
$ ruby diff_chunk.rb G1011-norm.dat O1011-norm.txt 
error = 0.3214 (2057/6400)

# -----------

# [KC-KNBC] cabochaの実行。
$ cat S44-01.txt | cabocha -d /usr/local/lib/mecab/dic/jumandic -M ./chunk.juman.10.10 -O2 -f1 -n0 > O1044.txt
$ cat S44-02.txt | cabocha -d /usr/local/lib/mecab/dic/jumandic -M ./chunk.juman.10.10 -O2 -f1 -n0 >> O1044.txt

# [KC-KNBC] cabochaの出力を比較用に正規化。
$ ruby norm_chunk.rb O1044.txt > O1044-norm.txt

# [KC-KNBC] エラー率の表示。
$ ruby diff_chunk.rb G44-norm.dat O1044-norm.txt 
error = 0.2969 (155/522)
| 関口宏司 | NLP | 11:05 | comments(0) | trackbacks(0) |









http://lucene.jugem.jp/trackback/470
+ Solrによるブログ内検索
+ PROFILE
  12345
6789101112
13141516171819
20212223242526
2728293031  
<< August 2017 >>
+ LINKS
検索エンジン製品 - 比較のポイント
商用検索エンジンを購入した企業担当者は読まないでください。ショックを受けますから・・・
>>製品比較 10のポイント
+ Lucene&Solrデモ
+ ThinkIT記事
+ RECOMMEND
Apache Solr入門 ―オープンソース全文検索エンジン
Apache Solr入門 ―オープンソース全文検索エンジン (JUGEMレビュー »)
関口 宏司,三部 靖夫,武田 光平,中野 猛,大谷 純
+ RECOMMEND
Lucene in Action
Lucene in Action (JUGEMレビュー »)
Erik Hatcher,Otis Gospodnetic,Mike McCandless
FastVectorHighlighterについて解説記事を寄稿しました。
+ RECOMMEND
+ SELECTED ENTRIES
+ RECENT COMMENTS
+ RECENT TRACKBACK
+ CATEGORIES
+ ARCHIVES
+ MOBILE
qrcode
+ SPONSORED LINKS