Word Mover's Distance(5)Wikipedia の Page データを抽出する

Word Mover's Distance (5) Extracting Page Data from Wikipedia XML Dump


2021/05/22
藤田昭人


前回 はトリプレットを紹介しました。 でも、実際に fastWMD を実行する際には トリプレット・データを取り込んでいるように見えないことに お気づきの方も多いかと思います。

本稿ではそのあたりのカラクリを説明した上で、 その前処理のために必要な Wikipedia のバックアップから Page データを抽出するツール wikiPageSelector を紹介したいと思います。


付属スクリプトで生成される4つのファイル

前回紹介した triplets コマンドの実行スクリプトを再掲します。

#!/bin/sh -x
../build/triplets \
--trip ../dataset/triplets/wikipedia/wikipedia-triplets.txt \
--docs ../dataset/triplets/wikipedia/wikipedia-papers.txt \
--emb ../dataset/triplets/wikipedia/wikipedia-embeddings.txt \
--verbose false --num_clusters 289 --max_iter -1 --func cosine --r 16

オプション trip, docs, emb として triplets, papers, embeddings の 3つのデータファイルがコマンドに引き渡されてますが、 いずれも数字が羅列されているテキストファイルです。 この3つのデータファイルと tokens ファイルは fastWMD のリポジトリに付属するスクリプト wiki-xml-to-txt.py で生成することができます。

このスクリプトを読んでみたところ、 次の4つの処理を実行していることがわかりました。

  1. 解析対象となるWikipediaページ(あるいは論文)をトークンに分解
  2. 句読点と意味のないトークン、いわゆるストップ・ワードを除外
  3. トークン毎にユニークな ID を設定
  4. トリプレットデータ、解析対象データ、埋め込みデータについて、トークンを ID に差し替えたファイルを生成

Wikipediaデータセットについて各ファイル毎に説明すると…

wikipedia-triplets.txt は 前回紹介したトリプレット・ファイルを ID に置き換えたファイルです。 トリプレット・ファイルは1行に3つの Wikipedia ページの URL を定義していますが、 各々のタイトルをトークンとする3つの ID に置き換えられています。

wikipedia-papers.txt は対象となる文章を ID 列に置き換えたもので、 各 Wikipedia ページの記述が使われています。 ストップ・ワードが除外されているので トークン列に逆変換しても意味不明でしょうが。

wikipedia-embeddings.txt は埋め込みデータ、 すなわち Word2Vec の学習済みデータです。 元データはトークン毎にベクトルが定義されていますが、 トークン部分が ID に置き換えられています。

wikipedia-tokens.txt は ID とトークンの対応表で、 fastWMD の実行には使われません。 このファイルを使うと ID からトークンへの逆変換が可能です。

この一連の手順は自然言語処理では 典型的な前処理だと思います。 本来 WMD では二つの文章を入力とするAPIが 用意されることが多いと思うのですが、 敢えてトークンにIDを割り当てて ベンチマーク・プログラムの外へ追い出してるのは、 文章間距離の計算速度に注目する fastWMD では 文字列操作によりコストのかかる前処理を 評価から除外するためなんじゃないかと想像してます。


スクリプトに埋め込まれている暗黙のデータ

コードに埋め込まれているので わかりにくいのですが、スクリプト wiki-xml-to-txt.py を実行するにはトリプレット・データ以外に 更に2つデータを用意する必要があります。

ひとつ目はWord2Vecの学習済みデータです。 スクリプトには次のような記述があります。

word_embeddings_path = "<PATH-TO-EMBEDDINGS>/GoogleNews-vectors-negative300.bin"

このファイル名を見れば ピンと来る方もいらっしゃるでしょ😁 これはオリジナルのWord2Vecのページで 紹介されている学習済みデータです。 以前 Word2Vecの記事 で紹介した次の Google のサイトから入手できます。

code.google.com

このページの Pre-trained word and phrase vectors あたりを見てください。 ダウンロードの方法が記述されています。

ふたつ目は解析対象となる文章データです。 スクリプトには次の記述を見ると Wikipediaのダンプファイルを そのまま取り込めるように見えます。

filepaths = [
    'hand/wikipedia-triplets-dump-20190918203353.xml'
]

そこで、Wikipedia英語版の 最新バックアップをダウンロードして来て 試してみたのですが… サイズが大き過ぎてズッコケました*1。 改めてWikipediaのダンプファイルを見てみると…

$ ls -l enwiki*
-rw-r--r--@ 1 fujita  staff  83108609305  5  6 23:25 enwiki-20210420-pages-articles-multistream.xml
-rw-r--r--@ 1 fujita  staff  19517540474  5  6 23:25 enwiki-20210420-pages-articles-multistream.xml.bz2
$ 

圧縮状態でも18.2GB、 解凍するとなんと77.4GBにもなる 超巨大ファイルです。 もちろん気づいてなかった訳ではないのですが、 内心「Python だからシレ〜っと動くかも?」 との淡い期待を抱いたのです。 期待はあっさりと打ち砕かれました。


Wikipedia のダンプファイルから Page データを抽出する

この種の、いわゆるビッグデータ処理は ある意味今どき感のあるプログラミングなんですけども、 例えて言えば「大型トラックで市街地をドライブする」ようなもので、 プログラミングは「曲がり角のたびに立ち往生する」といった感じになります*2。 やはり過去の経験どおり ベーシックなアプローチでないと乗り越えられないようです。

という訳で wikiPageSelector なる単純なCプログラムを書きました。 ソースコードgithub に置きましたので、 次のページからダウンロードしてください。

github.com

このプログラムは Wikipedia のダンプファイルから、 必要なPageデータだけを抜き出し、 サブセットの xml 形式として標準出力に出力させるだけのプログラムです。 「必要な Page データ」は「トリプレット・データに登場するページ 」と解釈しました。 第1引数にトリプレット・データ・ファイルのパスを、 第2引数に解凍後の Wikipedia のダンプファイルのパスを 指定します。

次に 最新のWikipedia英語版のダンプファイル を対象に time コマンドを噛ませて 抽出処理に要する時間を計測した例を示します。

$ time ./wikiPageSelector \
../triplets-data/wikipedia_2014_09_27_examples.txt \
~/Wikipedia/enwiki-20210420-pages-articles-multistream.xml 
・・・
21150000(99%): Still Life with Jupiter Tonans

real    344m41.938s
user    342m45.742s
sys 1m25.288s
$ time ./wikiPageSelector \
../triplets-data/wikipedia_2014_09_27_examples.txt \
~/Wikipedia/enwiki-20210420-pages-articles-multistream.xml 
・・・
21150000(99%): Still Life with Jupiter Tonans

real    339m57.163s
user    337m54.073s
sys 1m22.468s
$ 

ご覧のとおり、1回目が5時間44分、2回目が5時間39分かかりました。

標準出力をリダイレクトしてファイルに落とすと…

$ ls -l enwiki*
-rw-r--r--  1 fujita  staff  712146936  5 19 15:42 enwiki-20210420-pages-selected-1.xml
-rw-r--r--  1 fujita  staff  712146936  5 20 06:15 enwiki-20210420-pages-selected-2.xml
$ 

いずれも680MB程度の xml ファイルになりました。


まとめ

本稿では fastWMD 論文の評価実験を再現するための道具立てを調べて、 Wikipedia の Page データを抽出するツール wikiPageSelector を紹介しました。

正直、僕も論文の評価実験を再現すること自体には あまり意味を感じている訳ではないのですが、 明文化されてない評価実験のための準備作業の手順を追っていくことで、 WMDビッグデータを必要とするアルゴリズムであり、 その処理には非常に時間を要することが再確認できました。

システム、特に対話的なシステムに WMD を取り込むためには いろいろ工夫をしなければならないことが明らかになって良かったと思っています。 先端研究の成果を実用システムに応用するには 相応の二次的な研究開発が必要なんですねぇ。

以上

*1:実はこのあたりから雲行きが怪しくなって来ました😁

*2:これがブログの執筆スケジュールを破綻させた要因だったのですが😀