ナード戦隊データマン

機械学習, 自然言語処理, データサイエンスについてのブログ

bitextorで使うlangstatsを生成する方法

langstatsでは、各ドメインに対する各々の言語のドキュメント量を定義します。langstatsをbitextorに渡せば、スレッショルドを指定して候補ドメインを制限することができます。このlangstatsを生成する方法があったので書きます。

github.com

paracrawl/extractor

paracrawl/extractorは、Common CrawlからダウンロードしたWETファイルを展開し、モノリンガルデータを抽出するためのプロジェクトです。extractorのオプションに--print_statsがあり、これを使うことでlangstatを生成することができます。

GitHub - paracrawl/extractor

使い方

事前準備

依存ライブラリをインストールします。

apt update -y
apt install -y curl libcurl4-openssl-dev cmake libgtest-dev libboost-all-dev
(cd /usr/src/gtest; cmake CMakeLists.txt; make; cp *.a /usr/lib)

コンパイル&インストール

git clone https://github.com/paracrawl/extractor
type mono || ( cd extractor/; mkdir -p build && cd build; cmake .. -DWITH_LZMA=off -DBUILD_TEST=on -DCMAKE_BUILD_TYPE=Release; make -j4; cp *.so /usr/local/bin; cp mono /usr/local/bin )

実行例

test -f wet.paths.gz || wget https://commoncrawl.s3.amazonaws.com/crawl-data/CC-MAIN-2019-43/wet.paths.gz
(test -d out && rm -r out) || echo "out directory is not found"
zcat wet.paths.gz | awk '{print "https://commoncrawl.s3.amazonaws.com/"$0}' | head -n 1 | mono --icompression gzip --ocompression gzip --workers 1 --output out --curl --print_stats

Note: この実行例では、wet.paths.gzからURLを1つだけ抜き出して実行しています。すべて抜き出すためには、head -n 1 を消して実行します。

出力例

0-network.bepress.com.library.simmons.edu       en      25851
0.123.klanten.instapinternet.nl nl      3140
00000000000000f.livejournal.com el      17
00000000000000f.livejournal.com en      3375
00000000000000f.livejournal.com hi      19
00000000000000f.livejournal.com ms      33
00000000000000f.livejournal.com nn      29
00000000000000f.livejournal.com zh      13
007cad.com      en      1679
00810.glasstargetballs.com      da      5
00810.glasstargetballs.com      el      7
00810.glasstargetballs.com      en      737
00810.glasstargetballs.com      ms      30
00810.glasstargetballs.com      no      10
00810.glasstargetballs.com      pt      3
00810.glasstargetballs.com      zh      694568
00810.glasstargetballs.com      zh-Hant 81
00tube.net      no      4
00tube.net      zh      6066
0120media.nl    en      2913
0120media.nl    la      2361
0120media.nl    nl      66
02150526.blog.fc2.com   en      40
(...と延々と続く。)

候補ドメインのランク付け

候補ドメインのランク付けとして、ここでは以下のルールに従ってランク付けする方法を考えます。

ルール: 指定した2つの言語の同一ドメイン内でのbyte lengthの比率が1に近いほど良い。

ランク付けのコード

import sys
 
 
class CandidateRanker:
    def __init__(self, lines):
        self._data = self._load_data(lines)
 
    def __call__(self, lang1, lang2):
        return self._calc_ratio(
            self._data, lang1, lang2)
 
    def _load_data(self, lines):
        out = {}
        for line in lines:
            line = line.strip().split("\t")
            if len(line) == 3:
                domain = line[0]
                lang = line[1]
                size = int(line[2])
                if domain not in out:
                    out[domain] = {}
                out[domain][lang] = size
        return out
 
    def _calc_ratio(self, data, lang1="ja", lang2="en"):
        out = {}
        for domain, values in data.items():
            if lang1 in values and lang2 in values:
                v1 = values[lang1]
                v2 = values[lang2]
                ratio = float(min(v1, v2)) / float(max(v1, v2))
                out[domain] = ratio
        return sorted(out.items(), key=lambda x: x[1], reverse=True)
 
 
def _main(lang1="ja", lang2="en"):
    lines = (line for line in sys.stdin)
    for domain, ratio in CandidateRanker(lines)(lang1, lang2):
        sys.stdout.write("{}\t{}\n".format(domain, ratio))
 
 
if __name__ == "__main__":
    _main(sys.argv[1], sys.argv[2])

コードの実行方法

cat langstats.0 | python3 rank_candidates.py ja en | head -n 100 > ranked_top_100.txt

出力例

illminate.shop-pro.jp   0.9911504424778761
booth.pm        0.9827511858559724
www.studioaya.com       0.9655172413793104
www.aiyu8.com   0.9555555555555556
bank.jrj.com.cn 0.9454545454545454
www.etihad.com  0.9415204678362573
www.ttbird.net  0.9347826086956522
ond-craftfood.com       0.9061032863849765
art24.photozou.jp       0.9031007751937985
www.trunglan.com        0.8958333333333334
makonarita.tokyo        0.8809523809523809
www.polycom.co.jp       0.878233247617607
jstore.jst.go.jp        0.8635312873654842
trphz.youtexun.com      0.8260869565217391
ir.soken.ac.jp  0.8241424229266174
www.bod-mart.com        0.8222222222222222
www.esquire.com 0.8086658086658086
kyomihoni.com   0.7931920359666025
www.uklrec.com  0.7777777777777778
jpshared.com    0.7531775317753178
t-matsuura.blog.openers.jp      0.75025942580422
www.50record.com        0.7455885204576304
www.unooki.com  0.7454545454545455

補足

内部的には、cld2という別のモジュールが使われています。これは言語検出モデルです。 https://github.com/CLD2Owners/cld2

気になる点としては、extractorが出力するlangstatのフォーマットがbitextorが想定するものと完全一致しているのかという点です。この点についてはissueを投稿しました。 Is print_stats' output format the same as the bitextor's langstat option? · Issue #2 · paracrawl/extractor · GitHub

参考

  1. GitHub - paracrawl/extractor
  2. GitHub - bitextor/bitextor: Bitextor generates translation memories from multilingual websites.
  3. [1911.10668] JParaCrawl: A Large Scale Web-Based English-Japanese Parallel Corpus