LoginSignup
1

More than 1 year has passed since last update.

AmazonLinux2+python+Word2Vecで連想語辞書を作る

Posted at

pythonとWord2Vecで連想語辞書を作成した際の作業記録を残します。コーパスにはWikipediaのDumpを利用させて頂いています。

前提

  • OSはAmazonLinux2、形態素解析エンジンのMeCabがインストール済であること。
    • ※ MeCabのインストールについては前回または他の方のインストール記事を参考にして下さい。

作業手順

pythonとpip、依存するライブラリのインストール

$ sudo yum install -y python3
$ echo 'alias python=python3.7' >> ~/.bashrc
$ source ~/.bashrc

それぞれバージョンを表示させられればOK。

$ python --version
Python 3.7.10
$ pip3 --version
pip 20.2.2 from /usr/lib/python3.7/site-packages/pip (python 3.7)

ライブラリをインストール。

pip3 install mecab-python3 wikiextractor gensim

コーパスとしてwikipediaのDumpを取得

※ 詳細はWikipedia:データベースダウンロード参照。

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

取得したデータからModelを生成

wikipediaのDumpはタグなどが含まれておりそのまま自然言語処理に利用するのは難しい。そこでWikiExtractorでクリーニングする。

python -m wikiextractor.WikiExtractor ./jawiki-latest-pages-articles.xml.bz2 --processes 16 -o result/ -b 50m

クリーニングしたテキストデータがresult/以下にwiki_NNの名で生成される。

├── AA
│   ├── wiki_00
│   ├── wiki_01
│   ├── wiki_02
│   ├── wiki_03
    (省略)
│   ├── wiki_64
│   └── wiki_65

そこで今度はこれらファイル群にクリーニング・単語分割・正規化・ストップワードの除去をそれぞれかけていく。今回はpythonスクリプトを利用した。

python convert.py

convert.pyの内容は下記の通り。

convert.py
import re
import os
import MeCab
from multiprocessing import Pool

mecab = MeCab.Tagger ("-d /usr/local/lib/mecab/dic/mecab-ipadic-neologd/ -F\"%f[6] \" -U\"%m \" -E\"\n\"")

def convert(filename: str):
    if os.path.exists(filename) == False:
        return

    isTitleNext = False
    with open(filename, mode='rt', encoding='utf-8') as reader:
        with open(filename + '.result', mode='w') as writer:
            for line in reader:
                # クリーニング
                if '</doc>' in line:
                    continue
                if '<doc id=' in line:
                    isTitleNext = True
                    continue
                if isTitleNext == True:
                    isTitleNext = False
                    continue

                if len(re.sub('[0-9a-zA-Z ]*', '', line)) == 0:
                    continue

                # 単語分割と正規化(※ MeCabを呼ぶときのオプション部分が正規化)
                parsedLine = mecab.parse (line)

                # ストップワードの除去
                parsedLine = parsedLine.strip()
                parsedLine = parsedLine.strip(".")
                parsedLine = re.sub('[。、,.]', '', parsedLine)
                parsedLine = re.sub(' +', ' ', parsedLine)
                if (len(parsedLine.split(" ")) <= 2) or (" " in line == False):
                    continue 

                writer.write(parsedLine)

filePaths = []
for current, dummy, files in os.walk("./result/"):
    for file in files:
        filePaths.append(current + "/" + file)

cpuCount = 16
p = Pool(cpuCount)
p.map(convert, filePaths)
p.close()

処理後のテキストデータが[元ファイル名].resultの名でできる。

│   ├── AA
│   │   ├── wiki_00
│   │   ├── wiki_00.result
│   │   ├── wiki_01
│   │   ├── wiki_01.result
    (省略)
│   │   ├── wiki_64
│   │   ├── wiki_64.result
│   │   ├── wiki_65
│   │   └── wiki_65.result

そこで結果を統合して1テキストファイルにまとめ、pythonスクリプトを利用してモデルを生成する。

find ./result/ -name *.result | xargs cat >> ./result/all.txt
python createmodel.py

createmodel.pyの内容は下記の通り。

createmodel.py
from gensim.models import word2vec
import logging

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

model = word2vec.Word2Vec(sentences, vector_size=200, min_count=20, window=15, workers=14)
model.wv.save_word2vec_format("./wikiall.vec.pt", binary=True)

wikiall.vec.pt という名のファイルが生成される。後はこれをKeyedVectorsのmost_similar()から利用すれば連想語辞書となるため、スクリプト等から呼び出せばよい。

$ python usemodel.py たま駅長
[('貴志駅', 0.7633522748947144), ('和歌山電鐵', 0.6615394949913025), ('名誉駅長', 0.6613053679466248), ('駅長', 0.6518781185150146), ('芦ノ牧温泉駅', 0.5756949782371521), ('マスコットキャラクター', 0.5370191931724548), ('イメージキャラクター', 0.5328614115715027), ('貴志川線', 0.523949921131134), ('わさお', 0.5135292410850525), ('一日駅長', 0.5096750259399414)]

"たま駅長"の語からちゃんと'貴志駅'、'和歌山電鐵'、'名誉駅長'などの語が導き出せている。
※たま駅長は和歌山電鐵貴志駅の名誉永久駅長。

尚usemodel.pyの内容は下記の通り。

usemodel.py
import sys
from gensim.models import KeyedVectors

wv = KeyedVectors.load_word2vec_format('./wikiall.vec.pt', binary=True)
results = wv.most_similar(positive=[sys.argv[1]], topn=10)
print(results)

以上。

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
What you can do with signing up
1