統計的機械翻訳システムMosesで英日翻訳

#統計的機械翻訳
ざっくり言うと、[Google翻訳](https://translate.google.co.jp/)のように、
入力文から翻訳文を生成して出力してくれるシステムのこと

以下もうちょっと詳しく↓↓↓

コーパスから言語モデル、翻訳モデルを学習し、それらを利用して、
入力文に対して最も最適な翻訳候補を翻訳文として出力する

翻訳する原言語文を $f$ 、生成された翻訳候補文を $e$ 、最終的な翻訳結果を $\hat{e}$ とすると、
統計的機械翻訳は以下の式で表される

$$\hat{e} = {\mathop{\rm arg~max}_e} P(e|f)$$

上式は、ベイズの定理を用いて以下のように変形できる

$$\hat{e} = {\mathop{\rm arg~max}_e} P(e)P(f|e)$$

上式の $P(e)$ が言語モデル、 $P(f|e)$ が翻訳モデルを表す

言語モデル：翻訳候補文の言語らしさ、流暢さを評価する確率モデル
翻訳モデル：翻訳候補文の訳語としての正しさを評価する確率モデル

上式を見ると分かる通り、言語モデルは単言語コーパス、
翻訳モデルは対訳コーパスからそれぞれ学習される

統計的機械翻訳は、言語モデルと翻訳モデルの確率値をかけ合わせた値を
最大化するような $e$ を翻訳文として出力する

#Moses
オープンソースの統計的機械翻訳システム
対訳コーパスを用いて言語モデルと翻訳モデルを学習し、統計的機械翻訳を実現
http://www.statmt.org/moses/

#Mosesのインストール
###インストール環境
CentOS7.2、sudo権限なしのマシンにインストール

###インストールするもの
- Boost
- Moses
- GIZA++

予めBoostとMosesをインストールするディレクトリ(boost_dir, moses_dir)を作っておく

###Boostのインストール
```
$ wget http://downloads.sourceforge.net/project/boost/boost/1.62.0/boost_1_62_0.tar.gz
$ tar zxvf boost_1_62_0.tar.gz
$ cd boost_1_62_0
$ ./bootstrap.sh
$ ./b2 -j16 --prefix=/path/to/boost_dir --libdir=/path/to/boost_dir/lib \
  --layout=system link=static install || echo FAILURE
```
-j16の16は利用するコア数のため、マシンによって変更する必要あり

###Mosesのインストール
```
$ git clone https://github.com/moses-smt/mosesdecoder.git
$ cd mosesdecoder
$ ./bjam -j16 --prefix=/path/to/moses_dir --with-boost=/path/to/boost_dir \
  --install-scripts=/path/to/moses_dir/dist 
```
-j16の16は利用するコア数のため、マシンによって変更する必要あり

###GIZA++のインストール
```
$ git clone https://github.com/moses-smt/giza-pp.git
$ cd giza-pp
$ make
```
make後、必要なファイルをmoses_dirにコピー

```
$ cd path/to/moses_dir
$ mkdir tools
$ cp path/to/giza-pp/GIZA++-v2/GIZA++ path/to/giza-pp/GIZA++-v2/snt2cooc.out \
  path/to/giza-pp/mkcls-v2/mkcls tools
```

以上でインストール完了

#英日翻訳を試す
言語モデルの学習コーパスとして、ntcir7から50万文の日本語文(train500k.ja)、
翻訳モデルの学習コーパスとして、ntcir7から10万文の英日対訳文(train100k.{en/ja})、
翻訳モデルのチューニングコーパスとして、ntcir7から1,000文の英日対訳文(dev1000.{en/ja})、
テストコーパスとして、ntcir10から2,000文の英日対訳文(test2000.{en/ja})
以上のコーパスを用意

###言語モデル学習
Mosesに標準で装備されているKenLMを使ってARPAファイルを作成
train500k.jaを用いて学習する

```
$ cd path/to/moses_dir
$ mkdir lm
$ cd lm
$ ../bin/lmplz -o 5 -S 80% < path/to/train500k.ja > output.arpa
```

-o:言語モデルのオーダー数、ここでは5を使う
-S:使用するメモリのパーセンテージ

その後、バイナリファイルを構築

```
$ ../bin/build_binary output.arpa output.bin
```

出来上がったoutput.binを言語モデルとして利用する

###翻訳モデル学習
train100k.{en/ja}を用いて翻訳モデルを学習する

```
$ cd path/to/moses_dir
$ mkdir tm
$ cd tm
$ perl ../dist/training/train-model.perl -root-dir . \
  -corpus path/to/train100k -f en -e ja \
  -alignment grow-diag-final-and -reordering msd-bidirectional-fe \
  -lm 0:5:path/to/moses_dir/lm/output.bin:0 \
  -external-bin-dir path/to/moses_dir/tools --parallel
```

-corpus:拡張子抜きのコーパス名を指定する
-f:入力言語コーパスの拡張子
-e:出力言語コーパスの拡張子
-lm:中のパスは上で作った言語モデルのフルパス
-external-bin-dir:moses_dirにコピーしたGIZA++のファイルが入っているディレクトリをフルパス指定
--parallel:並行処理、約2倍早くなる(CPUコア数2以上の場合)
その他はおまじないだと思ってください(笑)

翻訳モデルの学習が終わると、tm/model内にmoses.iniができている
チューニング、翻訳の前にmoses.iniの以下の部分を変更する

- [distortion-limit] を -1 に変更
- SRILM name= を KENLM name= に変更

###翻訳モデルのチューニング(オプション)
※この作業は飛ばしても翻訳ができます
Minimum Error Rate Trainingで翻訳モデルをチューニング
チューニングコーパスにdev1000.{en/ja}を利用

```
$ cd path/to/moses_dir/
$ mkdir tune
$ cd tune
$ perl ../dist/training/mert_moses.pl path/to/dev1000.en path/to/dev1000.ja \
  ../bin/moses ../tm/model/moses.ini --working-dir .
```

tuneディレクトリ内にチューニングされたmoses.iniができている

###翻訳実験

test2000.enを日本語に翻訳する

```
$ cd path/to/moses_dir
$ mkdir test
$ cd test
$ ../bin/moses -config path/to/moses.ini -input-file path/to/test2000.en > result2000.ja
```

翻訳結果であるresult2000.jaとtest2000.jaからBLEUを測定する
BLEUの値が高いほど翻訳精度が高い

```
$ cd path/to/moses_dir/test
$ perl ../dist/generic/multi-bleu.perl path/to/test2000.ja < result2000.ja 
BLEU = 20.43, 62.9/30.1/15.5/7.8 (BP=0.933, ratio=0.935, hyp_len=70265, ref_len=75128)
```

チューニングなしの場合とありの場合のBLEUを比較した結果は以下の表になる

||チューニングなし|チューニングあり|
|:-:|:-:|:-:|
|BLEU|20.43|22.82|

チューニングありの方がBLEUが高い
チューニングが翻訳精度向上に効いている

もし言語モデルを変更して実験を再度行いたい場合は、
moses.iniの KENLM name= の path= 以下を
新しく使用する言語モデルの名前に変更(フルパス)すればOK
(再度翻訳モデルを学習する必要はなし
ただしコーパスを変えて翻訳モデルを学習し直したい場合は別)