Word2Vec
テキスト解析して学習して
単語の意味をベクトル表現する方法
モデルは隠れ層と出力層の2層ニューラルネットワークになっている
Word2Vec を使うことで
ある単語や文章と似通った単語や文章を解析できる
例
コーパスにある単語の得微量ベクトルを学習し出力する
python で Word2Vec を使うには
gensim ライブラリをインストールする
pip3 install gensim
Mecab でコーパスを作成する
Word2Vec で類似語解析するには
テキストデータから
コーパス(基礎資料)を作成する必要がある
今回は明治以降の文学者15人のデータを wiki から取得し学習
まずはライブラリインストール
import MeCab import requests from bs4 import BeautifulSoup
次にターゲットURL指定
domain ="https://ja.wikipedia.org/wiki/"
次に対象人物をリストで宣言
names =["森鴎外","夏目漱石","島崎藤村","与謝野晶子","坪内逍遥","石川啄木", "谷崎潤一郎","芥川龍之介","萩原朔太郎","川端康成","志賀直哉","中原中也", "太宰治","大岡昇平","三島由紀夫"]
次に Mecab を分かち書きモードでインスタンス生成
コーパス(基礎資料)をいれるリストの宣言
m=MeCab.Tagger("-Owakati") corpus =[]
ループ処理で
URL+キーワード
で項目のHTMLを取得
for name in names: with requests.get(domain + name) as response: soup = BeautifulSoup(response.content, "html.parser") p_text = soup.find_all("p") for p in p_text: corpus.append(m.parse(p.text).strip())
最後にコーパス(基礎資料)の結果を
data.txt に出力
with open("data.txt","w") as file: file.write("\n".join(corpus))
全体ソースは
import MeCab import requests from bs4 import BeautifulSoup domain="https://ja.wikipedia.org/wiki/" names =["森鴎外","夏目漱石","島崎藤村","与謝野晶子","坪内逍遥","石川啄木", "谷崎潤一郎","芥川龍之介","萩原朔太郎","川端康成","志賀直哉","中原中也", "太宰治","大岡昇平","三島由紀夫"] m=MeCab.Tagger("-Owakati") corpus =[] for name in names: with requests.get(domain + name) as response: soup = BeautifulSoup(response.content, "html.parser") p_text = soup.find_all("p") for p in p_text: corpus.append(m.parse(p.text).strip()) with open("data.txt","w") as file: file.write("\n".join(corpus))
となり
実行すると
data.txt が作成される
次に
data.txt を解析し学習モデルを生成
gensim から Word2Vec をインポート
from gensim.models import word2vec
次にファイルからコーパス(基礎資料)の読み込み
corpus = file.read().splitlines()
splitlines() を使うと改行コードをリストにするときに入れなくなる
python でファイルを read してリストにする時に、改行コードを入れない
https://qiita.com/suzuki-hoge/items/8eac60f7b68044eea6c1
を参考に
次にコーパス(基礎資料)を元に学習モデルを生成
corpus =[sentence.split() for sentence in corpus] model = word2vec.Word2Vec(corpus,size=200,min_count=20,window=10)
次にモデルを元に似通ったキーワードをsy筒力
今回は文学と似通ったキーワードを出力
similar_words = model.wv.most_similar(positive=["文学"], topn=9) print(*[" ".join([v ,str("{:.2f}".format(s))]) for v, s in similar_words], sep="\n")
全体ソースは
from gensim.models import word2vec file = open("data.txt") corpus = file.read().splitlines() corpus =[sentence.split() for sentence in corpus] model = word2vec.Word2Vec(corpus,size=200,min_count=20,window=10) similar_words = model.wv.most_similar(positive=["文学"], topn=9) print(*[" ".join([v ,str("{:.2f}".format(s))]) for v, s in similar_words], sep="\n")
結果は
物語 0.99 作 0.98 題材 0.98 代表 0.98 時代 0.97 評論 0.97 世界 0.97 描い 0.97 歌 0.96
となった
参考書籍とは違ったけど
年数が立っているので誤差範囲
print(*[" ".join([v ,str("{:.2f}".format(s))]) for v, s in similar_words], sep="\n")
がわかりにくいので調べてみた
python {:.2f}
で検索したら
{インデックス番号:書式指定}
ということで
意味は下2桁で小数点タイプということ
これは format() の使い方であるということ
Pythonの文字列フォーマット(formatメソッドの使い方)
をみることで解決
なお今回のようにコーパス(基礎資料)作成
モデル構築
類似度の集計まで一気にやらず
モデル構築時点で一度ファイルに出力すれば
計算処理時間が縮小できる
model.save("data.model")
全体ソースは
from gensim.models import word2vec file = open("data.txt") corpus = file.read().splitlines() corpus =[sentence.split() for sentence in corpus] model = word2vec.Word2Vec(corpus,size=200,min_count=20,window=10) model.save("data.model") similar_words = model.wv.most_similar(positive=["文学"], topn=9) print(*[" ".join([v ,str("{:.2f}".format(s))]) for v, s in similar_words], sep="\n")
として実行すると
data.model が作成される
あとは学習済みモデルを読み込むには
model.word2vec.Word2Vec.load("data.model")
でOKらしいので
word2vecmodel_data.py
を作成し
from gensim.models import word2vec model =word2vec.Word2Vec.load("data.model") similar_words = model.wv.most_similar(positive=["文学"], topn=9) print(*[" ".join([v ,str("{:.2f}".format(s))]) for v, s in similar_words], sep="\n")
で実行したら
物語 0.99 歌 0.99 古典 0.99 海 0.98 時代 0.98 近代 0.98 作 0.98 世界 0.97 歴史 0.97
と同じ結果になった
Word2Vecの学習済み日本語モデルを読み込んで使う
を参考に
参考書籍は
なお kindle Fire でみるときには
拡大しなくても見れるので
10インチがおすすめ
カバーがほしい場合には
マグネット機能で閉じたらOFFにしてくれる純正がおすすめ