gensimのWord2Vecの使ってみたので、そのメモ。
今回はWikipediaの文章を使ってやってみますが、すぐに学習結果を知りたかったので少ないデータで学習をしています。
環境
※MeCabをWindowsにインストールするには
https://www.pytry3g.com/entry/2018/04/24/143934#Windows
データの用意
ライブラリのインポート
必要なライブラリのインポートをします。
import MeCab
import codecs
import urllib.parse as parser
import urllib.request as request
from bs4 import BeautifulSoup
Wikipediaから学習データを取ってきます。今回はいくつかの戦国大名に関する記事を学習データとして使います。
urllibを使ってWikipediaの記事をダウンロードします。
参考リンク
tagger = MeCab.Tagger("-Owakati")
link = "https://ja.wikipedia.org/wiki/"
keyword = ["織田信長", "徳川家康", "豊臣秀吉",
"伊達政宗", "武田信玄", "上杉謙信",
"明智光秀", "島津義弘", "北条氏康",
"長宗我部元親", "毛利元就", "真田幸村",
"立花宗茂", "石田三成", "浅井長政"]
corpus = []
for word in keyword:
with request.urlopen(link + parser.quote_plus(word)) as response:
html = response.read().decode('utf-8')
BeautifulSoup
urillibを使って受け取ったresponseを読み込むと、HTMLのformatになっているので、BeautifulSoupを使っていらないタグを取り除きます。
参考リンク
soup = BeautifulSoup(html, "lxml")
p_tags = soup.find_all('p')
for p in p_tags:
corpus.append(tagger.parse(p.text).strip())
上でやっていることはHTML形式の文字列から<p></p>で囲まれているところを取り出し、形態素解析して分かち書きしたものをcorpusに追加しています。
その後、corpusのそれぞれの要素の末尾に改行文字を加え、pwiki.txtというファイルにして保存しています。これを学習データとして使います。
with codecs.open("pwiki.txt", "w", "utf-8") as f:
f.write("\n".join(corpus))
Word2Vec
ライブラリのインポート
import codecs
from gensim.models import word2vec
学習する
with codecs.open("pwiki.txt", "r", "utf-8") as f:
corpus = f.read().splitlines()
corpus = [sentence.split() for sentence in corpus]
model = word2vec.Word2Vec(corpus, size=200, min_count=20, window=10)
データの用意のところで作成したpwiki.txtを読み込んで、Word2Vecに渡しています。
corpusの中身は以下のようになっていて、リストの中に単語が入ったリストがあります。
[
['織田', '信長', '(', 'おだ', 'のぶ', 'な', 'が', ')', 'は', '、', '戦国', '時代', 'から', '安土', '桃山', '時代', 'にかけて', 'の', '武将', '・', '戦国', '大名', '。', '三', '英傑', 'の', '一', '人', '。'],
['尾張', '国', '(', '現在', 'の', '愛知', '県', ')', 'の', '古渡', '城主', '・', '織田', '信秀', 'の', '嫡男', '[', '注釈', '5', ']。']
]
モデルの保存と読み込み
model.save("pwiki.model")
model = word2vec.Word2Vec.load("pwiki.model")
単語のベクトルを見る
word_vector = model.wv["尾張"]
型はnumpy
ある単語と類似している単語を見る
similar_words = model.wv.most_similar(positive=["尾張"], topn=9)
print(*[" ".join([v, str("{:.2f}".format(s))]) for v, s in similar_words], sep="\n")
similar_wordsにはリストになっていて、その要素はtupleとなっている。
tupleは単語と類似度の組になっている。
において 1.00
信虎 1.00
斎藤 1.00
原 1.00
立花 1.00
乱 1.00
河 1.00
川中島 1.00
尼子 1.00
2つの単語の類似度を計算
similarity = model.wv.similarity(w1="尾張", w2="天正")
vocab
vocab = model.wv.vocab
辞書になっていて、中身はkeyは単語、valueはgensim.models.keyedvectors.Vocabになっている。
index2word
index2word = model.wv.index2word
リストになっていて、要素は単語が入っている。
syn0
word_vectors = model.wv.syn0
全ての単語のベクトルを返す。
おすすめの記事
次のステップ
word2vecを使って文書ベクトルを作る話。
www.pytry3g.com
自分が自然言語処理について勉強したことを記事にしてまとめたものです。
www.pytry3g.com
import MeCab
import codecs
import urllib.parse as parser
import urllib.request as request
from bs4 import BeautifulSoup
tagger = MeCab.Tagger("-Owakati")
link = "https://ja.wikipedia.org/wiki/"
keyword = ["織田信長", "徳川家康", "豊臣秀吉",
"伊達政宗", "武田信玄", "上杉謙信",
"明智光秀", "島津義弘", "北条氏康",
"長宗我部元親", "毛利元就", "真田幸村",
"立花宗茂", "石田三成", "浅井長政"]
corpus = []
for word in keyword:
with request.urlopen(link + parser.quote_plus(word)) as response:
html = response.read().decode('utf-8')
soup = BeautifulSoup(html, "lxml")
p_tags = soup.find_all('p')
for p in p_tags:
corpus.append(tagger.parse(p.text).strip())
with codecs.open("pwiki.txt", "w", "utf-8") as f:
f.write("\n".join(corpus))
import codecs
from gensim.models import word2vec
with codecs.open("pwiki.txt", "r", "utf-8") as f:
corpus = f.read().splitlines()
corpus = [sentence.split() for sentence in corpus]
model = word2vec.Word2Vec(corpus, size=200, min_count=20, window=10)
model.save("pwiki.model")
model = word2vec.Word2Vec.load("pwiki.model")
word_vector = model.wv["尾張"]
similar_words = model.wv.most_similar(positive=["尾張"], topn=9)
similarity = model.wv.similarity(w1="尾張", w2="天正")
vocab = model.wv.vocab
index2word = model.wv.index2word
word_vectors = model.wv.syn0
Wikipedia全日本語記事のWord2Vecを作ってみる話
www.pytry3g.com