【自然言語処理のためのWikipediaデータの扱い方(#1) 】Wikipedia記事DBの作成

自然言語処理で遊ぶための学習用データとして魅力的なWikipediaのデータですが、ダウンロード可能なDumpデータは3GB程度と容量が大きく、形式はXMLデータだったりと扱うのが大変です。もしDBに格納されていれば条件検索して記事数など確認しながら必要なデータだけ取り出すことができて便利です。今回はファイルとして持ち運びにも便利なSQLiteでWikipediaの記事DBを作成します。

# 目的

・Wikipediaの記事データをDB(SQLite)に格納する
・記事名でパターン検索して、タイトルに特定の文字を含む記事データを抽出してみる。

# 方法(概要)

・Wikipadiaのダンプデータをダウンロードする
・Wikiextractorでテキストを整形しつつjsonデータとして抽出する
・抽出したjsonデータを拙作のPythonスクリプトwikiextractor2sqlite(※)を用いてsqliteのDBファイルに格納する

※[wikiextractor2sqlite](https://github.com/yuukimiyo/wikiextractor2sqlite)
簡単なPythonスクリプトなのでQiitaへ貼るだけでも良かったのですがせっかくなので

### 実行環境

- Ubuntu 18.04
- Python 3.6.0
- sqlite3 3.22.0

# 手順

## 記事データのダウンロード

Wiki dumpのサイトから、Wikipediaの本文データをダウンロードします。
次のURLにある、pages-articleが対象のdumpファイルです。
https://dumps.wikimedia.org/jawiki/

latestでも良いですが、後で別のデータと結合したい場合など日付付きの方が安全かもしれません。
今回は次のファイルをダウンロードしました。

```
wget https://dumps.wikimedia.org/jawiki/20191001/jawiki-20191001-pages-articles.xml.bz2
```

ファイルが大きいのでダウンロードに25分程度かかります。

## wikiextractorをダウンロード

Wikipediaのデータを整形するために、定番のWikiextractorを使用します。
次のコマンドでダウンロードします

``` sh
git clone https://github.com/attardi/wikiextractor
```

## Wikiextractorでテキストを整形しつつjsonデータとして抽出

次のコマンドでWikiextractorを実行します。

``` sh
./wikiextractor/WikiExtractor.py --json -q -o extracted jawiki-20191001-pages-articles.xml.bz2
```

ダウンロードに30分程度かかります。
処理が完了するとextractedというフォルダ内にAAといったアルファベット2文字のフォルダが作成され、その中に1MB毎に分割された記事データのJsonファイルが作成されます。
いくつもWARNINGが出ますが、記事データ出力には問題なさそうです。

オプションの説明

- --json: 出力をタグ形式からJSON形式に変更
- -q: メッセージの量を減らす
- -o extracted: 出力先として「extracted」フォルダを指定

Wikiextractorの詳細はこちらから
[Wikiextractor](https://github.com/attardi/wikiextractor)

## wikiextractor2sqlite をダウンロード

次のコマンドでダウンロードします。
合わせて必要ライブラリをインストールします。

```
git clone https://github.com/yuukimiyo/wikiextractor2sqlite.git
pip install tqdm
```

## Wikipedia DBを作成

wikiextractor2sqlite.pyを用いて、wikiextractorによる整形結果から、sqliteのdbファイルを作成します。

``` sh
./wikiextractor2sqlite/wikiextractor2sqlite.py ./extracted -o wikipedia.db
```

オプションの説明

- ./extracted: wikiextractorで抽出したファイルのディレクトリを指定
- -o wikipedia.db: 出力先のDB名を指定

この処理を実施すると、またWARNINGが出ます。wikiextractorが全ての改行コードを除去しきれていないのではと想像できる出方ですが、大した数ではなさそうなので今回は無視することにします。

オプションとして-qを指定するとWARNINGを非表示にできます。

## データの確認

以上の手順で記事DBが作成されていると思います。

``` sh
ls -l
>> -rw-r--r--  1 dev-user users 3.2G 10月 11 18:05 wikipedia.db
```

3.2GBと結構大きいですが、次のコマンドなどで圧縮すると大分小さくなるのでコピーする際は参考にしてください。(圧縮には結構時間がかかります)

``` sh
# tarコマンドで圧縮
tar zxvf wikipedia.db.tar.gz wikipedia.db

# 3.2GBが1.1GBまで圧縮されました。
ls -l
>> -rw-r--r--  1 dev-user users 1.1G 10月 11 18:49 wikipedia.db.tar.gz
```

# データの中身を見てみる

## SQLite3をインストールする(入っていない場合)

もしインストールされていない場合は適宜インストールしてください。
下記はUbuntuの場合です。

```sh
sudo apt install sqlite3
```

### 記事数を確認してみる

``` sh
sqlite3 wikipedia.db "select count(*) from extracted_page;"
>> 1170762
```

約110万件の記事が登録されています。
概ねWikipedia日本語版の記事数統計と一致するので、無事にdbが作成されているようです。

### 記事テーブルの構造を確認してみる

``` sh
sqlite3 wikipedia.db ".schema extracted_page"
>> CREATE TABLE `extracted_page` (
>>     `id` bigint PRIMARY KEY,
>>     `url` varchar(512),
>>     `title` varchar(1024),
>>     `text` text
>> );
```

wikiextractorが出力したJsonに合わせて筆者が軽く作成したTableなのでちょっと素朴すぎる気もしますが、このようなTableにデータが格納されています。さすがにidがbigintになっているのは恥ずかしいので将来の更新で直すかもしれません。


### タイトルに「アニメ」が含まれる記事の一覧を表示する

```sh
# まずは件数を確認
sqlite3 wikipedia.db 'select count(title) from extracted_page where title like "%アニメ%";'
>> 1073

# 多いので、絞って表示
sqlite3 wikipedia.db 'select title from extracted_page where title like "%アニメ%" limit 30;'
>> アニメ
>> SFアニメ
>> アニメ関係者一覧
>> アニメ作品一覧
>> アダルトアニメ
>> 東京を舞台とした漫画・アニメ作品一覧
>> アニメーション
>> 魔法少女アニメ
>> 宇宙の戦士 (アニメ)
>> ロボットアニメ
...
```

### タイトルに「アニメ」が含まれる記事の本文データを取得する

やっとここまで来ました。次のコマンドで、anime.txtとして1073件分の記事データを取得できます。

```sh
sqlite3 wikipedia.db 'select text from extracted_page where title like "%アニメ%";' > anime.txt
```

中身の確認

```
# 容量の確認。4.8MBです。
ls -lh anime.txt
>> -rw-r--r-- 1 dev-user users 4.8M 10月 11 20:03 anime.txt

# 行数
wc -l anime.txt
>> 37570 anime.txt

# 先頭の10行を表示
head -n 10 anime.txt
----------------------------------------
アニメ

アニメは、アニメーションの略語である。アニメーションを用いて構成された映像作品全般を指す。

各種メディアで提供されるサブカルチャーの一つ。

「文化芸術基本法」ではメディア芸術、関連法の「コンテンツの創造、保護及び活用の促進に関する法律」によるとコンテンツの一つと定義されており、い
ずれにおいてもアニメと略されてはおらず、アニメーションと正式表記されている。別定義として、多角的芸術分類観点において、美術（映像を含まない）
、映像、音楽、文学、芸能の総合芸術とされるときもある。

単に「アニメ」という場合は、セルアニメーション（セルアニメ）のことを指していることが多い。本項では、主に日本で製作された商業用セルアニメーシ
ョンについて解説する。
----------------------------------------
```

# 最後に

sqliteのクエリーを用いてデータの集計や抽出ができるようになるので、Wikidumpやwikiextractorによる整形結果に比べ、アイディアによっては便利に使えるのではないでしょうか。

次回はカテゴリデータを追加して、カテゴリによる記事の抽出など紹介できればと思います。