PythonでWord2Vecを使ってテキスト処理をしてみよう

AI

Word2Vecとは、Googleの研究者が考案し、Googleから公開されているテキスト処理を行うための技術です。具体的には、文書郡(コーパス)を入力にして、単語をベクトル形式で表現するためのモデルのグループのことを指します。Word2Vecを使用することで、例えば異なる単語や文章の類似度を分析することが可能になります。

今回は、PythonでWord2Vecを用いて、単語同士の類似度を検証する手順を紹介していきます。

環境

以下の環境で実施します。

種別環境
OS
開発環境
macOS Catalina バージョン 10.15
PyCharm 2019.1.3 (Community Edition)

なお、macにはHomebrewがインストールされていることを前提とします。

モデルの作成

まずは学習用データを元に、Word2Vecのモデルを作成します。学習用データは文章であればなんでも構わないのですが、今回は日本語版Wikipediaの記事を使用します。

必要なツールをインストールする

必要なツールは、WikiExtractor, Gensim, MeCabになります。基本的にPyCharmのProject Interpreterに追加することで利用できるようになりますが、MeCabだけはホストOS自身にインストールされていないと、PyCharmのプロジェクトに追加する時にエラーが出てしまいます。そのため、まずはmacOSへMeCabをインストールして、その後にPyCharmのプロジェクトにツールを追加していきます。

macOSへMeCabをインストールする

まずはターミナルから、下記のコマンドを実行します。また、後ほどテキストファイルをUTF-8に変換する必要があるため、ついでにnkfもインストールしておきます。

$ brew install mecab
$ brew install nkf

MeCabを利用するには辞書データが必要になります。そのため、下記のページからIPA辞書ファイルをダウンロードしてください。
http://taku910.github.io/mecab/#download

上記ファイルをダウンロードしたら、MeCabで利用できる準備をします。ターミナルから下記のコマンドを実行してください。

$ cd $HOME/Downloads ##ファイルのダウンロード先へ移動する
$ tar xvfz mecab-ipadic-2.7.0-20070801.tar.gz ##辞書ファイルを解凍する
$ cd mecab-ipadic-2.7.0-20070801
$ ./configure --with-charset=utf8
$ make
$ sudo make install

これで、/usr/local/lib/mecabに辞書がインストールされます。

PyCharmのインタプリタに必要なツールをインストールする

続いて、PyCharmでプロジェクトを作成して、必要なツールをインストールします。上部メニューにて PyCharm > Preferencesを選択してください。次に開かれたウィンドウにてProject: XXXX(プロジェクト名) > Project Interpreter を選択して、「+」ボタンをクリックして、以下のツールを順に検索、インストールしていってください。

  • wikiextractor
  • mecab
  • gensim

依存するパッケージも一緒にインストールされるため、以下のようになります。

学習用のコーパスを用意する

次に、学習用のコーパスを用意します。ここからはPyCharm上で、作成したプロジェクトのターミナルで作業します。

まずは以下のコマンドを実行して、記事データをダウンロードします。

$ python WikiExtractor.py jawiki-latest-pages-articles.xml.bz2

データが大きいため、時間が掛かります。完了するまでしばらく待ってください。

ダウンロードが完了したら、複数のファイルを1つにまとめます。

$ find text/ | grep wiki | awk '{system("cat "$0" >> wikipedia.txt")}'

モデルを作成するにあたっては、英語のように言葉の区切りが空白で区切られている必要があります。これを分かち書きと言います。そのため、MeCabを使ってコーパスを分かち書きに変換します。

$ mecab -Owakati wikipedia.txt -o wikipedia_owakati.txt

仕上げに、コーパスをUTF-8に変換します。

nkf -w --overwrite wikipedia_owakati.txt

以上で、学習用のコーパス作成が完了しました。

学習済みモデルを作成する

いよいよ、Word2Vecのモデルを作成します。まずは以下のコードを作成してください。名前はなんでもいいですが、「create_model.py」としておきます。

from gensim.models import word2vec as w2v
import logging

# 進捗状況を出力する
logging.basicConfig(format='%(asctime)s : %(levelname)s : %(message)s', level=logging.INFO)

# コーパスからモデルを生成する
corpus = w2v.Text8Corpus('./wikiextractor/wikipedia_owakati.txt')
model = w2v.Word2Vec(corpus, size=100, min_count=5, window=5, iter=100)

# モデルを保存する
model.save('wiki.model')

上記のプログラムを実行すれば、「wiki.model」という学習済みモデルが作成されます。相当な時間が掛かると思うので、標準出力に進捗状況を出力しています。(私の場合は3日掛かりました)

下記のような具合に永遠と進捗が出力されつづけ、「saved wiki.model」が出力されれば完了です。

$ python create_model.py

 〜省略〜
2020-01-12 22:33:56,062 : INFO : EPOCH 100 - PROGRESS: at 99.36% examples, 689163 words/s, in_qsize 5, out_qsize 0
2020-01-12 22:33:57,071 : INFO : EPOCH 100 - PROGRESS: at 99.52% examples, 689162 words/s, in_qsize 5, out_qsize 0
2020-01-12 22:33:58,072 : INFO : EPOCH 100 - PROGRESS: at 99.68% examples, 689185 words/s, in_qsize 3, out_qsize 0
2020-01-12 22:33:59,080 : INFO : EPOCH 100 - PROGRESS: at 99.85% examples, 689197 words/s, in_qsize 5, out_qsize 0
2020-01-12 22:34:00,010 : INFO : worker thread finished; awaiting finish of 2 more threads
2020-01-12 22:34:00,016 : INFO : worker thread finished; awaiting finish of 1 more threads
2020-01-12 22:34:00,036 : INFO : worker thread finished; awaiting finish of 0 more threads
2020-01-12 22:34:00,036 : INFO : EPOCH - 100 : training on 613690332 raw words (433072395 effective words) took 628.4s, 689203 effective words/s
2020-01-12 22:34:00,038 : INFO : training on a 61369033200 raw words (43307030240 effective words) took 89024.5s, 486462 effective words/s
2020-01-12 22:34:00,060 : INFO : saving Word2Vec object under wiki.model, separately None
2020-01-12 22:34:00,108 : INFO : storing np array 'vectors' to wiki.model.wv.vectors.npy
2020-01-12 22:34:01,088 : INFO : not storing attribute vectors_norm
2020-01-12 22:34:01,160 : INFO : storing np array 'syn1neg' to wiki.model.trainables.syn1neg.npy
2020-01-12 22:34:02,198 : INFO : not storing attribute cum_table
2020-01-12 22:34:04,989 : INFO : saved wiki.model

Word2Vecモデルを利用する

作成したモデルを利用して、テキスト処理をしてみましょう。

意味の近い単語を検出する

以下のコードでは、「富士山」に意味の近い単語を検出します。

from gensim.models import word2vec

model = word2vec.Word2Vec.load('./wiki.model')


results = model.wv.most_similar_cosmul(positive=['富士山'])

for result in results:
    print(result)

実行すると、以下のように出力されました。

('御嶽山', 0.8907154202461243)
('岩手山', 0.8835008144378662)
('岩木山', 0.8818954229354858)
('筑波山', 0.8775238990783691)
('阿蘇山', 0.8728675246238708)
('高尾山', 0.8697397708892822)
('山頂', 0.867121696472168)
('八ヶ岳', 0.8624481558799744)
('赤城山', 0.8613798022270203)
('浅間山', 0.8609115481376648)

単語の意味を足し引きしてみる

単語の足し算、引き算のようなこともできます。以下のコードでは、富士山から日本という意味を引いて、アメリカという意味を足しています。

from gensim.models import word2vec

model = word2vec.Word2Vec.load('./wiki.model')


results = model.wv.most_similar_cosmul(positive=['富士山', 'アメリカ'], negative=['日本'])

for result in results:
    print(result)

これを実行したところ、下記のように出力されました。

('ベースキャンプ', 1.0038424730300903)
('ウェスト・マウンテン', 0.990940272808075)
('グランドキャニオン', 0.9908800721168518)
('ヨセミテ', 0.9798535704612732)
('山並み', 0.9764869809150696)
('ハーフドーム', 0.9744011163711548)
('マッターホルン', 0.9648380875587463)
('頂上', 0.9636467099189758)
('キリマンジャロ', 0.9624046087265015)
('湖岸', 0.9616795778274536)

1位のベースキャンプなど、よくわからないものもありますが、まあ納得できる内容が出力されました。

今回のまとめ

今回は、学習用のコーパスを用意、整形して、Word2Vecのモデルを作成しました。モデルの利用方法については、ほんの少ししか触れませんでしたが、他にもいろいろなことができるので、後々、別の記事で紹介したいと思います。

コメント

タイトルとURLをコピーしました