テキスト同士の類似度を判定する【Python】

word2vecを使用してテキスト同士の類似度を計測します。
チャットボットを作る上で必要となる意図解析に繋がる技術です。

プログラム

from gensim.models import word2vec
from scipy import spatial

import sys
import MeCab
import numpy as np

import warnings
warnings.filterwarnings('ignore')

#モデルまでのパス
model_path = 'word2vec.gensim.model'
#モデルの読み込み
model = word2vec.Word2Vec.load(model_path)

mecab = MeCab.Tagger()

# テキストのベクトルを計算
def get_vector(text):
    sum_vec = np.zeros(50)
    word_count = 0
    node = mecab.parse(text).splitlines()
    for item in node:
        if item.split('\t')[0]=='EOS':
            break
        field = item.split('\t')[1].split(',')[0]
        if field == '名詞' or field == '動詞' or field == '形容詞':
            # print(item.split('\t')[0])
            # print(model.wv[item.split('\t')[0]])
            sum_vec += model.wv[item.split('\t')[0]];
            word_count += 1
    return sum_vec / word_count

def sentence_similarity(sentence_1, sentence_2):
    sentence_1_avg_vector = get_vector(sentence_1);
    sentence_2_avg_vector = get_vector(sentence_2);
    return 1 - spatial.distance.cosine(sentence_1_avg_vector, sentence_2_avg_vector)

result = sentence_similarity(
    "似ている芸能人は",
    "芸能人で似ている人は"
)
print(result)

これを実行すると 0.87 という類似度が得られます。

まとめ

ちなみに「似ている芸能人は」と「タイ旅行に行くにはどうしたらいい」を比較すると 0.3 という類似度が得られます。ちゃんと、類似性があるかどうかを判定しているようです。

もちろん、単純に同じ単語を使うから類似性があるという評価ではありません。word2vecを使っているので「バンコクに行くにはどうするべきか」と「タイ旅行に行くにはどうしたらいい」を比較しても 0.76 という類似度が得られます。ちゃんと、バンコクとタイが同じような意味だと理解しているようです。

システム開発

Posted by @erestage