LoginSignup
0
0

More than 1 year has passed since last update.

Python3: cos類似度を計算 (janome)

Last updated at Posted at 2021-11-27

次のページを参考にしました。
Pythonで「Bag Of Words」を使い文章の類似度を調べる【自然言語処理】

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

pip install janome
janome_check.py
#! /usr/bin/python
#
#   janome_check.py
#                   Nov/27/2021
# ------------------------------------------------------------------
from janome.tokenizer import Tokenizer
import numpy as np
import sys

# ------------------------------------------------------------------
def gen_toks_list(sentence_list):
    """
    文章のリストをJanomeのトークン列のリストに変換する
    """
    t = Tokenizer()
    return [list(t.tokenize(s)) for s in sentence_list]

# ------------------------------------------------------------------
def gen_word_to_index(toks_list):
    """
    トークンの表層形から添え字を得られるようにマップを作成する
    """
    word_to_index = {}

    for toks in toks_list:
        for tok in toks:
            # もしトークンがマップに含まれていなければインデックスを追加する
            if tok.surface not in word_to_index.keys():
                new_index = len(word_to_index)  # 新しいインデックスを作成
                word_to_index[tok.surface] = new_index  # マーク

    return word_to_index

# ------------------------------------------------------------------
def gen_corpus(toks_list, word_to_index):
    """
    行列の作成
    """
    # len(toks_list) x len(word_to_index) の成分0の行列を作成
    corpus = np.zeros((len(toks_list), len(word_to_index)))

    # 行列を処理する
    for i, toks in enumerate(toks_list):
        # 行を処理する
        for tok in toks:
            # 行の持っているトークンの列に対してマーキング
            corpus[i, word_to_index[tok.surface]] += 1

    return corpus

# ------------------------------------------------------------------
def gen_bag_of_words(toks_list):
    """
    Bag of Wordsを使って行列を作成
    """
    word_to_index = gen_word_to_index(toks_list)
    corpus = gen_corpus(toks_list, word_to_index)
    return corpus

# ------------------------------------------------------------------
def cos_sim(x, y):
    """
    類似度の計算
    cos類似度という方法を用いる
    """
    return np.dot(x, y) / (np.sqrt(np.sum(x ** 2)) * np.sqrt(np.sum(y ** 2)))

# ------------------------------------------------------------------
def show_per(corpus):
    for it, vv in enumerate(['B', 'C', 'D', 'E']):
        it += 1
        per = cos_sim(corpus[0], corpus[it])
        print(f'A vs {vv}: {per:.2}')

# ------------------------------------------------------------------
def proc01(sentence_list):

    # トークン列のリストの作成
    toks_list = gen_toks_list(sentence_list)

    # Bag of Wordsの作成
    corpus = gen_bag_of_words(toks_list)

    # 結果を出力
    show_per(corpus)


# ------------------------------------------------------------------
sys.stderr.write("*** 開始 ***\n")

sentence_list = [
        '昔ある所に、王様がいました。',  # 文章A
        'ある所に、かわいい女の子がいました。',  # 文章B
        '一人の王様がいました。',  # 文章C
        '昔ある所に、貧しい女がいました。',  # 文章D
        '昔、王様がある所にいました。',  # 文章E
    ]

proc01(sentence_list)

sys.stderr.write("*** 終了 ***\n")
# ------------------------------------------------------------------

実行結果

$ ./janome_check.py 
*** 開始 ***
A vs B: 0.82
A vs C: 0.6
A vs D: 0.87
A vs E: 1.0
*** 終了 ***
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0