0
0

言語処理100本ノック2020 (95. サブワード化)

Last updated at Posted at 2023-11-08

はじめに

本記事は言語処理100本ノックの解説です。
100本のノックを全てこなした記録をQiitaに残します。
使用言語はPythonです。

今回は第10章: 機械翻訳(95. サブワード化)の解答例をご紹介します。
問題95は文章をサブワード化して問題91~94を再度実施するため、この問題単独で記事にしました。

95. サブワード化

トークンの単位を単語や形態素からサブワードに変更し,91-94の実験を再度実施せよ.

準備
データセットをサブワードするためにsubword-nmtを入れます。

コマンド
$ pip install subword-nmt

コード

コード
!subword-nmt learn-bpe -s 10000 < "[PATH]/kftt-data-1.0/sorce/kyoto-train.en"> "[PATH]/kftt-data-1.0/codec/en_codec.txt"
!subword-nmt learn-bpe -s 10000 < "[PATH]/kftt-data-1.0/sorce/kyoto-train.ja"> "[PATH]/kftt-data-1.0/codec/ja_codec.txt"

def Subword(name):
  !subword-nmt apply-bpe -c "[PATH]/kftt-data-1.0/codec/en_codec.txt" < "[PATH]/kftt-data-1.0/sorce/kyoto-"$name".en" > "[PATH]/kftt-data-1.0/codec/"$name".en"
  !subword-nmt apply-bpe -c "[PATH]/kftt-data-1.0/codec/ja_codec.txt" < "[PATH]/kftt-data-1.0/sorce/kyoto-"$name".ja" > "[PATH]/kftt-data-1.0/codec/"$name".ja"

Subword("train")
Subword("test")
Subword("dev")

コメント
OSコマンドを関数に組み込んでtrain, test, devのデータを作ります。そして、問題90-94を再び実施します。

95-90. データの準備

機械翻訳のデータセットをダウンロードせよ.訓練データ,開発データ,評価データを整形し,必要に応じてトークン化などの前処理を行うこと.ただし,この段階ではトークンの単位として形態素(日本語)および単語(英語)を採用せよ.

コマンド
$ fairseq-preprocess -s ja -t en \
--trainpref  "[PATH]/kftt-data-1.0/codec/train" \
--validpref "[PATH]/kftt-data-1.0/codec/dev" \
--testpref "[PATH]/kftt-data-1.0/codec/test" \
--destdir "[PATH]/kftt-data-1.0/processed-95/" \
--task translation \
--thresholdsrc 5 \
--thresholdtgt 5

コメント
問題90~95の記事と全く同じです。

95-91. 機械翻訳モデルの訓練

90で準備したデータを用いて,ニューラル機械翻訳のモデルを学習せよ(ニューラルネットワークのモデルはTransformerやLSTMなど適当に選んでよい).

コマンド
$ fairseq-train "[PATH]/kftt-data-1.0/processed-95/" \
  --task translation \
  --arch transformer \
  --tensorboard-logdir "logs" \
  --source-lang ja --target-lang en \
  --max-epoch 100 \
  --lr 1e-5 \
  --batch-size 32 \
  --optimizer adam \
  --save-interval 3 \
  --save-dir "[PATH]/kftt-data-1.0/model-95/" \
  --restore-file  "[PATH]/kftt-data-1.0/model-95/checkpoint_last.pt" \
| tee -a "[PATH]/kftt-data-1.0/log-95/train.log"

コメント
また、学習していきます。

95-92. 機械翻訳モデルの適用

91で学習したニューラル機械翻訳モデルを用い,与えられた(任意の)日本語の文を英語に翻訳するプログラムを実装せよ.

コマンド
$ fairseq-generate "[PATH]/kftt-data-1.0/processed-95/" \
--path "[PATH]/kftt-data-1.0/model-95/checkpoint_best.pt" \
--task translation \
--gen-subset test \
| tee >(grep "^H" | cut -f3 > "[PATH]/kftt-data-1.0/processed-95/test-transform.txt")\
| grep "^T" | cut -f2 >  "[PATH]/kftt-data-1.0/processed-95/test-true.txt"

出力結果

予測
Some arg@@ ue that this caused the er@@ rors in their ages .
Emperor Tenchi ( Ten@@ ji )
1879 : Osaka Techn@@ ical College
" Ten@@ zo K@@ yok@@ un "
" Fu@@ sh@@ uku Han@@ ho "
正解
Thus , er@@ rors were wrong .
Emperor Ten@@ ji ( also pronounced Ten@@ ji )
In 1879 , he became Osaka Sen@@ mon Gakko ( Osaka V@@ oc@@ ational School ) .
" Ten@@ z@@ oku-@@ kyo Sutra "
" H@@ ow to eat g@@ our@@ d rice "

これだと分からないので、サブワードから元の表記に戻します。

コマンド
$ cat "[PATH]/kftt-data-1.0/processed-95/test-transform.txt" | sed -r 's/(@@ )|(@@ ?$)//g' > "[PATH]/kftt-data-1.0/processed-95/test-transform-decoded.txt"
$ cat "[PATH]/kftt-data-1.0/processed-95/test-true.txt" | sed -r 's/(@@ )|(@@ ?$)//g' > "[PATH]/kftt-data-1.0/processed-95/test-true-decoded.txt"

改めて翻訳結果と正解の文章は以下のようになります。

予測
Thus , errors were wrong .
Emperor Tenji ( also pronounced Tenji )
In 1879 , he became Osaka Senmon Gakko ( Osaka Vocational School ) .
" Tenzoku-kyo Sutra "
" How to eat gourd rice "
正解
Some argue that this caused the errors in their ages .
Emperor Tenchi ( Tenji )
1879 : Osaka Technical College
" Tenzo Kyokun "
" Fushuku Hanho "

コメント
例が悪いのかもですが、できている感じがしないですね。

95-93. BLEUスコアの計測

91で学習したニューラル機械翻訳モデルの品質を調べるため,評価データにおけるBLEUスコアを測定せよ.

サブワードで評価

コマンド
$ fairseq-score --sys  "[PATH]/kftt-data-1.0/processed-95/test-transform.txt"\
--ref  "[PATH]/kftt-data-1.0/processed-95/test-true.txt"

結果
image.png

元の文章に戻して評価

コマンド
$ fairseq-score --sys  "[PATH]/kftt-data-1.0/processed-95/test-transform-decoded.txt"\
--ref  "[PATH]/kftt-data-1.0/processed-95/test-true-decoded.txt"

結果
image.png

コメント
サブワードのままだと23.27、元の文章に戻すと20.94でした。サブワード化すると語彙を少なくできるため評価値が高くなるのかなと。サブワード化せずに学習、評価した結果が前記事で18.69でしたので、サブワード化は有効な手法だと言えますね。

95-94. ビーム探索

トークンの単位を単語や形態素からサブワードに変更し,91-94の実験を再度実施せよ.

コード
from matplotlib import pyplot
beam_list = []
for i in range(1, 100):
  try:
    beam_temp = !fairseq-generate "[PATH]/kftt-data-1.0/processed-95/" \
      --path "[PATH]/kftt-data-1.0/model-95/checkpoint_best.pt" \
      --task translation \
      --gen-subset test \
      --beam $i  | grep '^Generate'
    beam_list.append(float(beam_temp[-1].split(",")[0].split(" ")[-1]))
  except:
    break

pyplot.plot(beam_list)

出力結果
download.png

コメント
だいたい23.25~23.50の間でまとまっていますね。

他章の解答例

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0