LoginSignup
1
1

More than 1 year has passed since last update.

wikipediaのデータからword2vecコーパスを作成する

Last updated at Posted at 2023-02-26

wikipediaのデータからword2vecコーパスを作成する

GitHub

この記事のコードは全て以下のリポジトリにあります。

仮想環境の作成

conda create -n wikiw2v python=3.10
conda activate wikiw2v

wikiのデータダウンロード

curl https://dumps.wikimedia.org/jawiki/latest/jawiki-latest-pages-articles.xml.bz2 -o jawiki-latest-pages-articles.xml.bz2

約15分で完了した。

wikiデータの解凍

WikiExtractorで解凍する。

pip install git+https://github.com/prokotg/wikiextractor

以下コマンドで解凍を実行する。

python -m wikiextractor.WikiExtractor jawiki-latest-pages-articles.xml.bz2
[出力]
INFO: Preprocessing 'jawiki-latest-pages-articles.xml.bz2' to collect template definitions: this may take some time.
INFO: Preprocessed 100000 pages
INFO: Preprocessed 200000 pages
INFO: Preprocessed 300000 pages
INFO: Preprocessed 400000 pages
INFO: Preprocessed 500000 pages
INFO: Preprocessed 600000 pages
INFO: Preprocessed 700000 pages
INFO: Preprocessed 800000 pages
INFO: Preprocessed 900000 pages
INFO: Preprocessed 1000000 pages
INFO: Preprocessed 1100000 pages
INFO: Preprocessed 1200000 pages
INFO: Preprocessed 1300000 pages
INFO: Preprocessed 1400000 pages
INFO: Preprocessed 1500000 pages
INFO: Preprocessed 1600000 pages
INFO: Preprocessed 1700000 pages
INFO: Preprocessed 1800000 pages
INFO: Preprocessed 1900000 pages
INFO: Preprocessed 2000000 pages
INFO: Preprocessed 2100000 pages
INFO: Preprocessed 2200000 pages
INFO: Preprocessed 2300000 pages
INFO: Preprocessed 2400000 pages
INFO: Preprocessed 2500000 pages
INFO: Preprocessed 2600000 pages
INFO: Preprocessed 2700000 pages
INFO: Loaded 98635 templates in 682.9s
INFO: Starting page extraction from jawiki-latest-pages-articles.xml.bz2.
INFO: Using 11 extract processes.
INFO: Finished 11-process extraction of 2204987 articles in 980.6s (2248.6 art/s)

Mecabのインストール

https://taku910.github.io/mecab/#win からインストール。
windowsなので、Binary package for MS-Windowsを選択してダウンロードし、実行すると辞書とともにインストール完了。辞書の文字コードはUTF-8を選択した。

このとき、パスが通っていなかったので、環境変数に追加した。

pip install mecab-python3

Pythonのライブラリもインストールしておく。

ファイルの結合と分かち書き

解凍されたデータでは、AA,ABのようにフォルダに分かれて入っているので、フォルダごとに分かち書きをしてテキストを結合し、さらに一つのテキストファイルに結合する。

wiki1_wakati_gather.py
import glob
import logging
import os

import MeCab

if not os.path.exists("./wakati"):  # ディレクトリが無かったら作成
    os.mkdir("wakati")


logging.basicConfig(format='%(asctime)s : %(levelname)s : %(message)s', level=logging.INFO)
logger = logging.getLogger(__name__)

tagger = MeCab.Tagger("-Owakati")

AllData = ''
Folders = glob.glob('text\*')  # textディレクトリ内のフォルダを取得


start_num = 0  # 開始するフォルダの番号を指定
# 一度で実行する場合は0,途中で止まった後に再開するときはその番号

f = open(f"wakati/wiki_data_{Folders[start_num][5:7]}.txt", 'r', encoding='UTF-8')  # 読み込むので"r",UTF-8を指定
AllData = f.read()


for FolderName in Folders[start_num+1:]:
    files = glob.glob(f"{FolderName}\*")  # フォルダの中身を取得
    for file in files:
        f = open(file, 'r', encoding='UTF-8')  # 読み込むので"r",UTF-8を指定
        data = f.read()
        #AllData += data + '\n'
        wakatiData = tagger.parse(data)
        AllData += wakatiData + '\n'
        logger.info(file)
        f.close()

    #wf = open(f'data/wiki_data_{FolderName[5:7]}.txt', 'w', encoding='UTF-8')
    wf = open(f'wakati/wiki_data_{FolderName[5:7]}.txt', 'w', encoding='UTF-8')
    wf.write(AllData)
    wf.close

wf = open('wiki_data.txt', 'w', encoding='UTF-8')
wf.write(AllData)
wf.close()

これには2時間程度かかり、途中経過も保存しているためストレージを50GB以上くらい使用するので注意。

途中で止まった場合、wakatiフォルダ内に途中のデータがあるため、そこから再開できる。その際はstart_numの値を変更する。

タグと記号の除去

wikiデータは<doc></doc>で囲まれた部分があったり、記号がまだ含まれているのでそれを除去する。

wiki2_remove_tags.py
import re

import MeCab


f = open("wiki_data.txt", 'r', encoding='UTF-8')
data = f.read()
f.close()


# 最初にあるタグを消す
data = re.sub(r"<.*?>", r"", data)
# 半角記号削除
data = re.sub(r'[!"#$%&\'\\\\()*+,-./:;<=>?@[\\]^_`{|}~「」〔〕“”〈〉『』【】&*・()$#@。、?!`+¥%]', '', data)
# 全角記号削除
data = re.sub("[\uFF01-\uFF0F\uFF1A-\uFF20\uFF3B-\uFF40\uFF5B-\uFF65\u3000-\u303F]", '', data)

# print(data[0:10000])

#ファイルに書き込み
wf = open('wiki_tag_removed_data.txt', 'w', encoding='UTF-8')
wf.write(data)
wf.close()

単語のベクトル化

wiki3_make_vector.py
from gensim.models import word2vec
import logging

logging.basicConfig(format='%(asctime)s : %(levelname)s : %(message)s', level=logging.INFO)
sentences = word2vec.Text8Corpus('./wiki_wakati.txt')

model = word2vec.Word2Vec(sentences, vector_size=200, min_count=20, window=15)
model.wv.save_word2vec_format("./wiki.model", binary=True)

これでコーパス(モデル)を作成する。
ここでは200次元、20回以上出現する単語を使用、単語間の最大距離15としている。

使ってみる

類似単語検索

get_similar_word.py
from gensim.models import KeyedVectors

wv = KeyedVectors.load_word2vec_format('wiki.model', binary=True)
results = wv.most_similar(positive='日本')
for result in results:
  print(result)
単語を入力
>>> ご飯
('味噌汁', 0.8243885636329651)
('御飯', 0.8029778003692627)
('おかず', 0.7956658005714417)
('炊き込み', 0.7943350672721863)
('汁物', 0.790287435054779)
('チャーハン', 0.7815099358558655)
('おにぎり', 0.7813826203346252)
('米飯', 0.7800269722938538)
('目玉焼き', 0.775774359703064)
('お茶漬け', 0.763556182384491)

いい感じ。

類似度計算

get_similarity_of_2_words.py
from gensim.models import KeyedVectors

wv = KeyedVectors.load_word2vec_format('wiki.model', binary=True)

jpkr = wv.similarity('日本', '韓国')
print(f'日本と韓国の類似度 : {jpkr}')
日本と韓国の類似度 : 0.3739430904388428

参考:wikipediaを使ったword2vecコーパスの作り方をまとめてみた

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1