FPGA開発日記

カテゴリ別記事インデックス https://msyksphinz.github.io/github_pages , English Version https://fpgadevdiary.hatenadiary.com/

SyntaxNetを使って日本語の構文解析にトライ(1. サンプルCONLLデータのトレーニング)

f:id:msyksphinz:20160520003556j:plain

SyntaxNetを使ったチュートリアルで、おおよそSyntaxNetへの学習のさせ方が分かってきた(ただしコマンドを並べているだけだけど...)。

msyksphinz.hatenablog.com

msyksphinz.hatenablog.com

ここまで来たら、どうにかして日本語の構文を学習させてみたい。Universal Dependency の ver1.3では、日本語の学習データは一部しか含まれておらず、このままでは学習できない。

そこでいろいろ探していたのだが、下記の学習データを見つけたため、これを使ってみることにした。

github.com

Googleの中の人?の資料だろうか、論文も付いている。時間が取れれば読んでみたい。

CONLLデータを使って、日本語のタグ付けを学習させる

v2.0には、日本語のCONLLデータが付いているため、これを利用してまずは日本語構文のタグ付けに挑戦してみる。

英語版のサンプルと同様に、コマンドを実行すればよい。

PARAMS=128-0.08-4400-0.85-5

bazel-bin/syntaxnet/parser_trainer \
  --task_context=syntaxnet/context_ja2.pbtxt \
  --compute_lexicon \
  --arg_prefix=brain_pos \
  --graph_builder=greedy \
  --training_corpus=training-corpus \
  --tuning_corpus=tuning-corpus \
  --output_path=models \
  --batch_size=32 \
  --decay_steps=3600 \
  --hidden_layer_sizes=128 \
  --learning_rate=0.08 \
  --momentum=0.9 \
  --seed=0 \
  --params=${PARAMS}

for SET in training tuning dev; do
  bazel-bin/syntaxnet/parser_eval \
    --task_context=models/brain_pos/greedy/$PARAMS/context \
    --hidden_layer_sizes=128 \
    --input=$SET-corpus \
    --output=tagged-$SET-corpus \
    --arg_prefix=brain_pos \
    --graph_builder=greedy \
    --model_path=models/brain_pos/greedy/$PARAMS/model
done

context_ja2.pbtxt は以下のように記述してた。

input {
  name: 'training-corpus'
  record_format: 'conll-sentence'
  Part {
    file_pattern: '/home/vagrant/work/uni-dep-tb/universal_treebanks_v2.0/std/ja/ja-universal-train.conll'
  }
}
input {
  name: 'tuning-corpus'
  record_format: 'conll-sentence'
  Part {
    file_pattern: '/home/vagrant/work/uni-dep-tb/universal_treebanks_v2.0/std/ja/ja-universal-dev.conll'
  }
}
input {
  name: 'dev-corpus'
  record_format: 'conll-sentence'
  Part {
    file_pattern: '/home/vagrant/work/uni-dep-tb/universal_treebanks_v2.0/std/ja/ja-universal-test.conll'
  }
}

入力データはすべてCONLL形式だ。実行するのに結構時間がかかるが、上記のコマンドを叩くだけで学習とテストが完了する。

テスト結果を見てみよう。テスト結果は、models/brain_pos/greedy/128-0.08-4400-0.85-5/tagged-dev-corpusに格納されている。

正解と並べて比較してみる。

分類 (テスト後) 詳細分類 (テスト後) 分類(正解) 詳細分類(正解)
1 これに PRON PRON-POSTP PRON PRON-POSTP
2 不快感を NOUN NOUN-PRT NOUN NOUN-PRT
3 示す VERB VERB-AUX VERB VERB-AUX
4 住民は NOUN NOUN-PRT NOUN NOUN-PRT
5 いましたが NOUN NOUN-VERB-AUX-CONJ VERB NOUN-VERB-CONJ
6 , . . .
7 現在 NOUN NOUN NOUN NOUN
8 , . . .
9 表立って NOUN NOUN-POSTP ADV ADV
10 反対や NOUN NOUN NOUN NOUN-CONJ
11 抗議の NOUN NOUN-POSTP NOUN NOUN-POSTP
12 声を NOUN NOUN-PRT NOUN NOUN-PRT
13 挙げている VERB VERB-AUX-AUX VERB VERB-AUX-AUX
14 住民は NOUN NOUN-PRT NOUN NOUN-PRT
15 いないようです。 VERB VERB-AUX-AUX VERB VERB-AUX-NOUN-VERB-AUX

詳細分類のところが多少間違えている。

CONLLデータを使って、日本語の構文を学習させる

次に、構文を学習させてみよう。英語版と同様のトレーニングをさせる。

PARAMS=200x200-0.08-4400-0.85-6

bazel-bin/syntaxnet/parser_trainer \
  --task_context=syntaxnet/context_ja2.pbtxt \
  --compute_lexicon \
  --arg_prefix=brain_pos \
  --graph_builder=greedy \
  --training_corpus=training-corpus \
  --tuning_corpus=tuning-corpus \
  --output_path=models \
  --batch_size=32 \
  --decay_steps=3600 \
  --hidden_layer_sizes=128 \
  --learning_rate=0.08 \
  --momentum=0.9 \
  --seed=0 \
  --params=${PARAMS}


for SET in training tuning dev; do
  bazel-bin/syntaxnet/parser_eval \
    --task_context=models/brain_pos/greedy/$PARAMS/context \
    --hidden_layer_sizes=128 \
    --input=$SET-corpus \
    --output=tagged-$SET-corpus \
    --arg_prefix=brain_pos \
    --graph_builder=greedy \
    --model_path=models/brain_pos/greedy/$PARAMS/model
done


bazel-bin/syntaxnet/parser_trainer \
  --task_context=syntaxnet/context_ja.pbtxt \
  --compute_lexicon \
  --arg_prefix=brain_pos \
  --graph_builder=greedy \
  --training_corpus=training-corpus \
  --tuning_corpus=tuning-corpus \
  --output_path=models \
  --batch_size=32 \
  --decay_steps=3600 \
  --hidden_layer_sizes=128 \
  --learning_rate=0.08 \
  --momentum=0.9 \
  --seed=0 \
  --params=${PARAMS}


bazel-bin/syntaxnet/parser_trainer \
  --arg_prefix=brain_parser \
  --batch_size=32 \
  --projectivize_training_set \
  --decay_steps=4400 \
  --graph_builder=greedy \
  --hidden_layer_sizes=200,200 \
  --learning_rate=0.08 \
  --momentum=0.85 \
  --output_path=models \
  --task_context=models/brain_pos/greedy/$PARAMS/context \
  --seed=4 \
  --training_corpus=tagged-training-corpus \
  --tuning_corpus=tagged-tuning-corpus \
  --params=${PARAMS}


for SET in training tuning dev; do
  bazel-bin/syntaxnet/parser_eval \
    --task_context=models/brain_parser/greedy/$PARAMS/context \
    --hidden_layer_sizes=200,200 \
    --input=tagged-$SET-corpus \
    --output=parsed-$SET-corpus \
    --arg_prefix=brain_parser \
    --graph_builder=greedy \
    --model_path=models/brain_parser/greedy/$PARAMS/model
done

パラメータの部分を、200x200に変更しないと構文解析のパートで動作しなかったので、タグ付けの学習からやり直している。

同様にテスト結果は、models/brain_parser/greedy/200x200-0.08-4400-0.85-5/parsed-dev-corpusに格納されている。詳細は省略するが、これもおおむね正しく学習されていた。

とりあえず、ここまでサンプルの日本語を学習、テストさせることができるようになったので、今度は新たに別の日本語を作って構文解析をさせてみよう。