データナード

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

OPUSからデータを得てアラインメントする

OPUSとは、継続的に更新を続けている公開パラレルコーパスのコレクションです。

概要

LASERの訓練時に、WikiMatrixを使っていましたが、データの質が悪いらしく、Sentence Embeddingがまともに機能しませんでした。そのため、LASERの論文内にかかれているように、OPUSからいくつかのコーパスをダウンロードすることにしました。

We collect training corpora for 93 input languages by combining the Europarl, United Nations, OpenSubtitles2018, Global Voices, Tanzil and Tatoeba corpus, which are all publicly available on the OPUS website (Tiedemann, 2012). https://arxiv.org/abs/1812.10464

OPUSの主な部分では、データを2つに分割しています:

  • 単一言語の文リスト。
  • 2つの言語の文リスト内の対応する部分を指し示すIDリスト。

これらのファイルは、XML, TMX, XCESのような形式で分離されていますが、訓練データとしてすぐに使える形式にするのは面倒です。

そこで、opus_readというコマンドを提供する、opustools-pkgを使うことができます。

$ pip install opustools-pkg

コード

以下のコードにより、英語とスペイン語をソース言語として、ダウンロードスクリプトを一気に150程度の言語に対して走らせます:

import os
import re
import requests
from subprocess import check_output
from tqdm import tqdm


def download_langs():
    reg = r"<option value='(.*)'"
    r = requests.get("http://opus.nlpl.eu")
    langs = re.findall(reg, r.text)
    return sorted([x for x in langs[1:-6] if "_" not in x and len(x) == 2])


def download_corpus(corpus_name, source_lang, target_lang):
    cmd = ["yes | opus_read --directory {CN}"]
    cmd.append("-s {SL}")
    cmd.append("-t {TL}")
    cmd.append("-sz {CN}_latest_raw_{SL}.zip")
    cmd.append("-tz {CN}_latest_raw_{TL}.zip")
    cmd.append("-dl ./downloads/")
    cmd.append("--preprocess raw")
    cmd.append("--write outputs/{CN}_{SL}-{TL}.txt")
    cmd = ' '.join(cmd)
    cmd = cmd.format(CN=corpus_name, SL=source_lang, TL=target_lang)
    return check_output(cmd, shell=True)


def _load_setting(langs_file):
    settings = set()
    with open(langs_file) as f:
        for line in f:
            line = line.strip()
            if line or not line.startswith("#"):
                settings.add(line)
    return sorted(list(settings))


def main(langs_file, corpus_file):
    langs = _load_setting(langs_file)
    corpus_names = _load_setting(corpus_file)

    for cname in tqdm(corpus_names):
        try:
            print(download_corpus(cname, "en", "es"))
        except Exception as e:
            print(e)
        for slang in ["en", "es"]:
            for tlang in tqdm(langs):
                if slang == tlang:
                    continue
                try:
                    print(download_corpus(cname, slang, tlang))
                except Exception as e:
                    print(e)


if __name__ == "__main__":
    main("./langs.txt", "./corpus_names.txt")
  • langs.txtは、download_langs関数で取得した言語一覧です。
  • corpus_names.txtは、対象のコーパス名(Tatoeba, Europealなど)の一覧で、LASERの論文内に書かれているコーパスを指定します。

参考

  1. OPUS - an open source parallel corpus
  2. GitHub - facebookresearch/LASER: Language-Agnostic SEntence Representations
  3. [1812.10464] Massively Multilingual Sentence Embeddings for Zero-Shot Cross-Lingual Transfer and Beyond
  4. opustools-pkg · PyPI