関数は、トークンではなく、共有されている単語の種類の割合を取得します。あなたは単語のセットを取っていますが、その数に敏感ではありません。
トークンの数が必要な場合は、ボキャブラリ ファイルがロードされている限り (データがインストールされている場合はデフォルトでロードされます)、以下が非常に高速になると思います。
from spacy.attrs import ORTH
def symm_similarity_types(nlp, textA,textB):
docA = nlp.make_doc(textA)
docB = nlp.make_doc(textB)
countsA = Counter(docA.count_by(ORTH))
countsB = Counter(docB.count_by(ORTH)
diff = sum(abs(val) for val in (countsA - countsB).values())
return diff / (len(docA) + len(docB))
上記のコードとまったく同じことを計算したい場合は、同等の spaCy を次に示します。オブジェクトを使用すると、オブジェクトDoc
を反復処理できますToken
。token.orth
次に、文字列の整数 ID である属性に基づいてカウントする必要があります。整数の操作は、文字列のセットよりも少し高速になると思います。
def symm_similarity_types(nlp, textA,textB):
docA = set(w.orth for w in nlp(textA)
docB = set(w.orth for w in nlp(textB)
intersection = len(textA.intersection(textB))
difference = len(textA.symmetric_difference(textB))
return intersection/float(intersection+difference)
これは、文字列ではなく整数のセットを操作しているため、NLTK バージョンよりも少し効率的です。
効率が本当に気になる場合は、Python が何をしているのかを推測するよりも、Cython で作業する方が便利な場合がよくあります。基本的なループは次のとおりです。
# cython: infer_types=True
for token in doc.c[:doc.length]
orth = token.lex.orth
doc.c
is aTokenC*
であるため、連続したメモリを反復処理し、単一のポインターを逆参照しています ( token.lex
is a const LexemeC*
)