見出し画像

全文検索のテストデータ作成にWikipediaのデータを利用してみました。

はじめに

こんにちは。SHIFT DAAE 開発グループ所属のsakuraiです。

今後の案件で全文検索を利用する予定があり、技術調査を行う際に大量のテキストデータをうまく作成できないかと考えました。
せっかく調査するなら出来る限り自然なデータを利用したい! ということで
Wikipediaの日本語データを利用してテストデータを作成してみました。
今回はMySQLに登録するまでに実施したことをまとめようと思います。

日本語Wikipediaのダンプデータの取得

ウィキペディアのデータは再配布や再利用のために利用できる一元化されたデータベース・ダンプでの提供が行われており、以下からダウンロードが可能です。

このリンクから全ページの記事本文を含む jawiki-latest-pages-articles.xml.bz2 というファイルをダウンロードします。全記事の本文のデータですので、ファイルサイズが大きいです。ご注意ください。

WikiExtractorの利用

ダンプファイルは本文以外の情報も含んだ大きいファイルですので必要ないデータを省略したり、形式を変換したくなると思います。
WikiExtractorというツールを利用することで、簡単に変換ができますので
こちらを利用します。
https://github.com/attardi/wikiextractor

それでは以下に、詳細な実施手順を記載していきます。

実施手順

事前準備

WikiExtractorはpythonを利用します。
pythonをインストールして実行環境を準備することでも問題ありませんが、
私は専用のDocker環境を作成しました。 以下がツールを利用するために作成した環境です。

# ディレクトリ構成
.
├── docker-compose.yml
└── work
    ├── jawiki-latest-pages-articles.xml.bz2
    └── to_csv.py

Docker起動用のディレクトリを作成し、ダウンロードしたダンプデータを配置します。
to_csv.pyについては後ほど。

# docker-compose.yml
services:
  python:
    image: python:3.10-slim
    container_name: python-container
    tty: true
    volumes:
      - type: bind
        source: ./work
        target: /work

pythonのバージョンについて、この記事を作成した時点ではpython:3.11の環境でWikiExtractorを実行した場合、エラーが発生しました。

root@6954b6a1fad6:/work# wikiextractor --json -o extracted jawiki-latest-pages-articles.xml.bz2
Traceback (most recent call last):
  File "/usr/local/bin/wikiextractor", line 5, in <module>
    from wikiextractor.WikiExtractor import main
~~ 省略 ~~
  File "/usr/local/lib/python3.11/re/_parser.py", line 841, in _parse
    raise source.error('global flags not at the start '
re.error: global flags not at the start of the expression at position 4

エラーを回避するため、python:3.10のイメージを利用しています。

JSON形式へのファイル変換

準備ができたので、WikiExtractorでファイルの変換を実施します。
まずは実行用のDocker環境を起動しましょう。

docker compose up -d
docker exec -it python-container bash

次にDockerコンテナ内でWikiExtractorをインストール、実行します。

cd /work
pip install wikiextractor
wikiextractor --json -o extracted jawiki-latest-pages-articles.xml.bz2

今回はxmlからjsonに変換を行います。
WikiExtractorのオプションで変換後の形式の指定が可能です。
その他オプションで設定できる項目もありますので、詳細はUsageを参照ください。
https://github.com/attardi/wikiextractor#usage

extractedというディレクトリに変換されたデータがファイル分割されて作成されます。入力ファイルのサイズが大きいため時間がかかりますので気長に待ちましょう。。
(今回は全件ほど大量のデータは必要ありませんでしたので、数十万件くらいで処理を中断しました。)

.extracted
├── AA
│   ├── wiki_00
│   ├── wiki_01
│   └── ...
├── AB
│   ├── wiki_00
│   ├── wiki_01
│   └── ...
├── AC
│   ├── wiki_00
│   ├── wiki_01
│   └── ...
├── ...

分割されていると扱いにくいのでまとめます。

find extracted -name 'wiki*' -exec cat {} \; > wikipedia.json

wikipedia.jsonというファイルができました。

# wikipedia.json
{"id": "5", "revid": "166965", "url": "https://ja.wikipedia.org/wiki?curid=5", "title": "\u30a2\u30f3\u30d1\u30b5\u30f3\u30c9", "text": "\u30a2\u30f3...
{"id": "10", "revid": "1637918", "url": "https://ja.wikipedia.org/wiki?curid=10", "title": "\u8a00\u8a9e", "text": "\u72ed\u7fa9\u306e\u8a00\u8a9e...
{"id": "11", "revid": "572369", "url": "https://ja.wikipedia.org/wiki?curid=11", "title": "\u65e5\u672c\u8a9e", "text": " \n\u65e5\u672c\u8a9e...

ここまで作成できればあとはお好みの形で加工して取り込んでいただければと思います!おまけとして、私がMySQLに取り込んだ手順を記載しておきます。

MySQLへの取り込み

MySQLへ取り込むため、CSVへ変換します。
WikiExtractorが動作するpyhton実行環境を作成しましたので、引き続きpythonを利用して変換を行います。
ディレクトリ作成時に配置したto_csv.pyを利用します。

# to_csv.py
import json

def toCsv(from_file, to_file):

    with open(from_file, encoding='utf-8') as input:
        with open(to_file, mode='w', encoding='utf-8') as output:
            for line in input:

                json_data  = json.loads(line)

                if not  json_data['text']:
                    continue

                text = json_data['text'][:1000].replace('"', '').replace('\n', '') 
                new_line = '"' + json_data['id'] + '","' + json_data['title'].replace('"', '') + '","' + text + '"' + '\n'
                output.write(new_line)


toCsv('wikipedia.json', 'wikipedia.csv')

元データからid, title, textのみを抽出しました。
データを簡易にするため、1000文字までで切り取り、改行と本文中のダブルクォーテーション(CSVの囲み文字として使用)を除去しています。
ということで無事csvファイルが作成できました。

# wikipedia.csv
"18550","裁判所 (地方制度)","地方制度としての裁判所(さいばんしょ)は、1868年(慶応4年)...
"18551","ヒューストン","ヒューストン(英語:、)は、アメリカ合衆国のテキサス州の都市。同...
"18552","法律行為","法律行為(ほうりつこうい、, )とは、広義においては、「法的権限の行使...

圧縮後3.5GByte(展開すると15GByteくらい)のデータから、数万件の簡素なデータに絞り込んだので容量も89MByteと小さくなりました。

-rw-r--r-- 1 1000 1000 3.5G Oct 14 01:15 jawiki-latest-pages-articles.xml.bz2
-rw-r--r-- 1 root root  89M Nov 10 08:39 wikipedia.csv

あとはMySQLにテーブルを作成してcsvファイルを読み込めば完了です!
全文検索の検証ですので、テーブル作成時にFULLTEXT INDEXも作成しています。

CREATE TABLE text (
  id int NOT NULL AUTO_INCREMENT, 
  title varchar(255) NOT NULL, 
  text varchar(1000) ,
  PRIMARY KEY (`id`),
  FULLTEXT KEY `FT_title_text` (`title`,`text`)
);

LOAD DATA LOCAL INFILE 'wikipedia.csv' IGNORE INTO TABLE text FIELDS TERMINATED BY ',' ENCLOSED BY '"' LINES TERMINATED BY '\n';

おわりに

ということで、自然なテストデータでの全文検索の検証を行うことができました。今回はMySQLへの取り込み想定で手順を書きましたが、Elasticsearchなどの検証やその他の用途でも利用できそうですね。

テストデータの作成でも有用なWikipediaさんありがとうございます!
今後も継続的に寄付させていただきます!
と感謝を述べて終わりとさせていただきます。


\もっと身近にもっとリアルに!DAAE公式Twitter/

★★さて、明日の「SHIFTアドベンドカレンダー」は★★
★★★どんな記事が公開されるでしょうか?お楽しみに!★★★


執筆者プロフィール:sakurai
SHIFT DAAE部所属の開発エンジニアです。
鎌倉殿の13人。

お問合せはお気軽に
https://service.shiftinc.jp/contact/

SHIFTについて(コーポレートサイト)
https://www.shiftinc.jp/

SHIFTのサービスについて(サービスサイト)
https://service.shiftinc.jp/

SHIFTの導入事例
https://service.shiftinc.jp/case/

お役立ち資料はこちら
https://service.shiftinc.jp/resources/

SHIFTの採用情報はこちら  
https://recruit.shiftinc.jp/career/