Word2Vecでベクトル分析してみる


前回の続き。

Janomeで単語に分割した文章を使って分析してみる。
出現頻度の多い単語は何かを調べるくらいなら、
前回紹介したAnalyzerでも調べられる。

TokenFilterにTokenCountFilterを指定すると、
出現回数の多い順に、単語(表層形)とその出現回数のタプルを返す。

from janome.tokenizer import Tokenizer
from janome.analyzer import Analyzer
from janome.tokenfilter import *
text = u'すもももももももものうち'
token_filters = [POSKeepFilter('名詞'), TokenCountFilter()]
a = Analyzer(token_filters=token_filters)
for k, v in a.analyze(text):
  print('%s: %d' % (k, v))
もも: 2
すもも: 1
うち: 1

 
これだけでも色々わかることはあるけれど、もう少し突っ込んだ調査がしたい。
例えば、前回は表記ゆれを吸収するために「RegexReplaceCharFilter」で置換したけれど、
まだ見つけ切れていない表記ゆれがあるのではないだろうか?
それを探すために「Word2Vec」でベクトル分析をしてみる。

ベクトル分析の細かい説明はこちらがわかりやすいかも。
Word2Vec:発明した本人も驚く単語ベクトルの驚異的な力

 

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

まずはWord2Vecを使うため、gensimをインストール。

>pip instrall gensim

 

ベクトル分析の前処理として、形態素解析する

前回作ったクラスを利用して、形態素解析結果をファイル出力しておく。

from WordSplit import WordSplit

input_file = "input.txt"
output_file = "output.txt"

ws = WordSplit()
with open(input_file, mode="r", encoding="utf-8") as f:
    with open(wakati_file, mode="w", encoding="utf-8") as of:
        # input_file読み込み
        for row in f:
            # 文字分かち
            for word in ws.tokenize(row):
                # 分かち結果をファイル出力
                of.write(word.surface + "\n")

 

Word2Vecでベクトル分析を行う

先ほど作成した形態素解析結果を読み込み、ベクトル分析を行う。
ベクトル分析の解析結果(model)はファイル出力しておくと、後々便利。

from gensim.models import word2vec

model_file = "word2vec.model"

words = word2vec.Text8Corpus(output_file )
model = word2vec.Word2Vec(words, size=32, min_count=5, window=3, iter=100, batch_words=5)
model.save(model_file)

 

似た単語を探す

most_similarで、似た単語(同じような文脈で使われている単語)を抽出することができる。

def calc(model, target):
    ret = model.wv.most_similar(positive=[target])
    print(model.__dict__['wv'][target])
    for item in ret:
        print(item[0], item[1])

解析結果

[-0.88293612 -0.3013185  -0.35126361  0.60957962  0.00221068 -0.14672852
  0.34758356  0.3130497  -0.26381639  0.01039159  0.74854016  0.22990224
  0.53207207  0.35894531 -0.18870777 -0.14299707 -0.17026021 -0.39226729
 -0.55686295 -1.03862309  0.34342393 -0.38474649  0.22264372  0.2148834
 -0.57690299  0.50958228  0.21316393 -0.45058063 -0.01531385  0.21411817
 -0.13765882  0.36555257 ]

hoge 0.537174940109
fuga 0.535886764526
foo 0.532948195934
bar 0.522415161133

上の表の数字が極端に小さかったり、したの表の数字が極端に1に近かったりすると
ベクトル分析がうまくいっていないとの事。
そう言う場合は、Word2Vecのパラメータを色々変えて試してみる。

 

ベクトル分析結果から全ての単語を取り出し、それに似た単語を取得する

まだ気づいていない表記ゆれを見つけるため、
全ての単語に対して似た単語を探してみる。

relationship_list = ""relationship.csv"
def find_relationship(model):
    with open(relationship_list, mode="w", encoding="utf-8") as sf:
        for vocab in model.wv.vocab:
            # 1文字の単語は解析対象外とする
            if not re.match("^.$", vocab):
                ret = model.wv.most_similar(positive=[vocab])
                for item in ret:
                    sf.write(vocab + "," + item[0] + "," + str(item[1]) + "\n")

 
うまく分析できていれば、自分でも気づかなかった表記ゆれや
誤変換などを見つけることができる。
それらも読み替え用リストに追加してやることで、より分析の精度が高くなる・・・と思う。


この投稿へのコメント

コメントはありません。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

CAPTCHA


この投稿へのトラックバック

トラックバックはありません。

トラックバック URL