データナード

機械学習と自然言語処理についての備忘録 (旧ナード戦隊データマン)

MGIZA++の最終出力からbicleaner用の確率的辞書を生成する

確率的辞書とは、ソース言語の各単語に対して、どのぐらいの確率でターゲット言語の対応する各単語が生起するかを表す辞書です。この辞書は、ターゲット言語の単語[space]ソース言語の単語[space]生起確率[newline]という形式で生成されます。MGIZA++は単語アライメントツールですが、このツールによってアライメントされた結果を利用して確率的辞書を生成します。

This script creates a probabilistic dictionary from MGIZA++ final outputs. · GitHub

MGIZA++のインストール

cd /opt
git clone https://github.com/moses-smt/mgiza/
cd mgiza/mgizapp
cmake .
make
make install

MGIZA++の実行方法

/opt/mgiza/mgizapp/instにインストールされるので、その中のバイナリを使います。

クラスの作成

/opt/mgiza/mgizapp/inst/mkcls -n10 -pexample.clean.en -Vexample.en.vcb.classes
/opt/mgiza/mgizapp/inst/mkcls -n10 -pexample.clean.ja -Vexample.ja.vcb.classes

-pと-Vの直後にスペースを入れてはいけません。

コーパスGizaフォーマットに変換

/opt/mgiza/mgizapp/inst/plain2snt example.clean.en example.clean.ja

co-ocurrenceの作成

/opt/mgiza/mgizapp/inst/snt2cooc example.clean.en_example.clean.ja.cooc \
example.clean.en.vcb example.clean.ja.vcb \
example.clean.en_example.clean.ja.snt

アライメントの実行

/opt/mgiza/mgizapp/inst/mgiza configfile

configfileの例は以下:

https://gist.github.com/sugiyamath/8d96a678bc614ac816962fc3eef6fdd8

probabilistic dictionaryの作成

以下のスクリプトを作成します。

import os
import re
from tqdm import tqdm
 
 
_re_fend = re.compile(r"part[0-9]+$")
_re_align = re.compile(r"([^ ]+) (\(\{[ 0-9]+\}\))")
 
 
def _process_file(pdict, fpath):
    with open(fpath) as f:
        process_line = 0
        for line in tqdm(f):
            process_line += 1
            if line.startswith("# Sentence pair"):
                process_line = 0
                tgt_words = []
            elif process_line == 1:
                tgt_words = line.split()
            elif process_line == 2:
                for match in re.finditer(_re_align, line):
                    sword = match.group(1)
                    if sword not in pdict:
                        pdict[sword] = {}
                    tmp = match.group(2).split()
                    if not len(tmp) == 2:
                        for i in tmp[1:-1]:
                            try:
                                tword = tgt_words[int(i)-1]
                                if tword not in pdict[sword]:
                                    pdict[sword][tword] = 1
                                else:
                                    pdict[sword][tword] += 1
                            except IndexError:
                                print("sword:", sword)
    return pdict
 
 
def build_pdict(dataroot):
    pdict = {}
    for fname in tqdm(os.listdir(dataroot)):
        if re.match(_re_fend, fname) is None:
            pdict = _process_file(pdict, os.path.join(dataroot, fname))
    return pdict
 
 
def write_pdict(pdict, outfile):
    with open(outfile, "w") as f:
        for sword, values in pdict.items():
            total = sum([v for k, v in values.items()])
            for tword, v in values.items():
                prob = float(v)/float(total)
                f.write(' '.join([tword, sword, str(prob)])+"\n")
 
 
if __name__ == "__main__":
    import sys
    pdict = build_pdict(sys.argv[1])
    write_pdict(pdict, sys.argv[2])

実行方法は以下

python3 create_pdic.py <MGIZA++の最終出力が格納されたディレクトリ> <確率的辞書の出力ファイル名>

すると、以下のような内容のファイルが出力されます:

[]

Consequently 余分 0.041666666666666664
extra 余分 0.4166666666666667
dimension 余分 0.08333333333333333
Diverging 余分 0.041666666666666664
has 余分 0.041666666666666664
With 余分 0.041666666666666664
further 余分 0.041666666666666664
twins 余分 0.041666666666666664
excess 余分 0.041666666666666664
, 余分 0.041666666666666664
therefore 余分 0.041666666666666664
off 余分 0.041666666666666664
NO 余分 0.041666666666666664
formation 余分 0.041666666666666664
- 次元 0.38518024032042725
dimensional 次元 0.4699599465954606
dimension 次元 0.02069425901201602
- 次元 0.0774365821094793
D 次元 0.029372496662216287
dimensionally 次元 0.0033377837116154874
dimensions 次元 0.011348464619492658
dimentional 次元 0.0026702269692923898
fully 完全 0.027950310559006212
perfectly 完全 0.2732919254658385
perfect 完全 0.21428571428571427
completely 完全 0.2080745341614907
complete 完全 0.18322981366459629
full 完全 0.062111801242236024
Complete 完全 0.012422360248447204
whole 完全 0.003105590062111801
completeness 完全 0.009316770186335404
has 完全 0.003105590062111801
perfectness 完全 0.003105590062111801

[]

ファイルの形式を知りたい場合は、以下から他の言語の確率的辞書をダウンロードできます。

https://github.com/bitextor/bitextor-data/releases/tag/bicleaner-v1.1

参考

  1. CSLab Blog
  2. GitHub - bitextor/bicleaner: Parallel corpus classifier/cleaner