ナード戦隊データマン

機械学習と自然言語処理についてのブログ

bitextor: Webから自動的にパラレルコーパスを生成するツール

bitextor1とは、指定したホストから自動的にパラレルコーパスを収集するツールです。

概要

bitextorは、paracrawlプロジェクト2で使われているツールで、Webから自動的にパラレルコーパスを生成します。機械翻訳の大きな課題は、大量かつ質の良いデータを用意することですが、Webという巨大な資源を利用すれば、人間の手をあまりかけずにコーパスを用意することができます。

実行方法

実行方法は色々ありますが、今回はdockerイメージを利用して実行します。

dockerコンテナに入る

docker pull paracrawl/bitextor
docker run -it paracrawl/bitextor

必要なものを入れる

cd /opt/bitextor
apt install cmake automake pkg-config python3 python3-venv python3-pip libboost-all-dev openjdk-8-jdk liblzma-dev time poppler-utils httrack 
pip3 install -r requirements.txt
pip3 install -r bicleaner/requirements.txt https://github.com/bitextor/kenlm/archive/master.zip
pip3 install -r bifixer/requirements.txt

トーカナイザの準備(mecab-tokenizer.perl)

次に、言語固有のトーカナイザを準備します。デフォルトでは、Mosesのトーカナイザを利用しているようですが、日本語を使いたいので、MeCabを使います。ただ、Mosesを使うようになっているため、perlしか実行できないのかもしれないので、perlMeCabのラッパーを作成します。(事前にMeCabのインストールが必要です。)

#!/usr/bin/env perl
system("mecab -Owakati");

sentence splitterも用意する必要がありますが、Mosesは日本語にも対応できるのでそれを使います。

パラレルコーパスの準備

document alignmentの方法をオプションで選択できますが、今回は辞書ベース手法を使うので、その辞書を作成するためのパラレルコーパスを準備します。

mkdir dic_data
cd dic_data
mkdir Tatoeba
cd Tatoeba
wget https://object.pouta.csc.fi/OPUS-Tatoeba/v20190709/moses/en-ja.txt.zip
unzip en-ja.txt.zip
gzip Tatoeba.en-ja.ja
gzip Tatoeba.en-ja.en

myconfig.yamlを書く

bitextorを実行する際に読み込む設定ファイルを書きます。

# BITEXTOR CONFIG FILE
 
bitextor: /opt/bitextor
temp: /home/bitextor/transient
permanentDir: /home/bitextor/permanent/bitextor-output
transientDir: /home/bitextor/transient
 
LANG1Tokenizer: /opt/bitextor/preprocess/moses/tokenizer/tokenizer.perl -q -b -a -l en
LANG2Tokenizer: /opt/bitextor/preprocess/moses/tokenizer/mecab-tokenizer.perl
LANG1SentenceSplitter: /opt/bitextor/preprocess/moses/ems/support/split-sentences.perl -q -b -l en
LANG2SentenceSplitter: /opt/bitextor/preprocess/moses/ems/support/split-sentences.perl -q -b -l yue
 
lang1: en
lang2: ja
 
crawler: wget
crawlTimeLimit: 30s
crawlSizeLimit: 1G
crawlTld: false
crawlerNumThreads: 8
crawlerConnectionTimeout: 10
 
hosts: ["mynlp.is.s.u-tokyo.ac.jp"]
 
dic: /opt/bitextor/dic_data/Tatoeba/en-ja.dic
initCorpusTrainPrefix: ["/opt/bitextor/dic_data/Tatoeba/Tatoeba.en-ja"]
boilerpipeCleaning: false
 
documentAligner: DIC

hostsには、クロール対象のホストを指定します。このツールは、指定されたホストのみを探索します。ホスト内のlang1とlang2が対応しているURLを見つけたら、そこからdocument alignmentを実行します。ホストは複数指定できますが、ホストファイルを用意することもできます。その場合は、以下のような設定パラメータを指定してください。

hostsFile: /home/user/hosts.gz

hosts.gzは、hostsというファイルに改行区切りでホストを記述したものをgzip圧縮したものです。

注意: 上記のhostsの設定をそのまま使わないでください。相手先のサイトに迷惑をかけます。

実行

以下を実行します。

./bitextor.sh -s myconfig.yaml

結果

抽出結果は、myconfig.yamlで記述された permanentDir 内に保存されます。

ls /home/bitextor/permanent/bitextor-output
en-ja.sent.xz  hosts.gz  warc

en-ja.sent.xzを展開すれば、抽出結果が見れます。抽出結果は以下の形式になっています。

src_url,tgt_url,src_sentence,tgt_sentence,score

Note: 実際はコンマではなく、タブ区切りです。

考察

bitextorでは、指定したホストのページだけを収集するので、Web全体というわけにはいきません。Web全体から探したい場合、hostsの候補URLを探す形でクローリングすることになりそうです。検索エンジンからinurl:enのようなオプションを利用して検索できれば理想的ですが、すぐに検索エンジン側からブロックされてしまうでしょう。

そのため、hostsファイルを複数に区切って連続的に生成するような仕組みが必要になります。さらに、生成されたhostsファイルから、bitextorで抽出していないものを探し出し、連続的に、あるいは複数のマシンによって実行するのがよいかもしれません。

要するに、実用的な面から言えば、bitextorを使う際に以下の2つのフェーズを実行する必要があります。

  • 候補となるホストの発見。
  • 発見されたホストに対してbitextorを実行。

ホストの発見のためのスクリプトはないので、自前で用意する必要があります。

ちなみに、bitextorを任意の言語で実行するために必要な最小限のリソースは以下です:

  • トーカナイザ。
  • センテンススプリッタ。
  • 指定したdocument alignerが必要とするもの(パラレルコーパス、辞書、MTシステムなど)

これは、開発者によってissue3で話されています。

追記

crawlTld: creepy-specific option that allows the crawler to jump to a different web domain as far as it is part of the same top-level domain (TLD); a TLD could be, for example, .es, .info or .org

「同じトップレベルドメイン内であれば、他のwebサイトへも飛ぶ」というオプションを有効化できるようです。なので、ホストの発見フェーズをつけなくても使えます。

参考