1. ホーム
  2. python

2つの文の文字列が与えられたときの余弦類似度を計算する

2023-07-31 02:25:47

質問

から Python: tf-idf-cosine: ドキュメントの類似性を検索する。 を見ると、tf-idf cosineを使って文書の類似度を計算することができるようです。外部ライブラリを利用せずに、2つの文字列のcosine類似度を計算する方法はないのでしょうか?

s1 = "This is a foo bar sentence ."
s2 = "This sentence is similar to a foo bar sentence ."
s3 = "What is this string ? Totally not related to the other two lines ."

cosine_sim(s1, s2) # Should give high cosine similarity
cosine_sim(s1, s3) # Shouldn't give high cosine similarity value
cosine_sim(s2, s3) # Shouldn't give high cosine similarity value

どのように解決するのですか?

単純な純粋なPythonの実装は、次のようになります。

import math
import re
from collections import Counter

WORD = re.compile(r"\w+")


def get_cosine(vec1, vec2):
    intersection = set(vec1.keys()) & set(vec2.keys())
    numerator = sum([vec1[x] * vec2[x] for x in intersection])

    sum1 = sum([vec1[x] ** 2 for x in list(vec1.keys())])
    sum2 = sum([vec2[x] ** 2 for x in list(vec2.keys())])
    denominator = math.sqrt(sum1) * math.sqrt(sum2)

    if not denominator:
        return 0.0
    else:
        return float(numerator) / denominator


def text_to_vector(text):
    words = WORD.findall(text)
    return Counter(words)


text1 = "This is a foo bar sentence ."
text2 = "This sentence is similar to a foo bar sentence ."

vector1 = text_to_vector(text1)
vector2 = text_to_vector(text2)

cosine = get_cosine(vector1, vector2)

print("Cosine:", cosine)

印刷します。

Cosine: 0.861640436855

ここで使われるコサインの公式を説明します。 ここで .

これにはtf-idfによる単語の重み付けは含まれていませんが、tf-idfを使うためには、tfidfの重みを推定するために、それなりに大きなコーパスが必要です。

また、テキストの一部から単語を抽出し、ステム処理またはレマタイズするなど、より洗練された方法を使用して、さらに発展させることができます。