Ваша функция получает процент общих типов слов, а не токены. Вы берете набор слов, не обращая внимания на их количество.
Если вам нужно количество токенов, я ожидаю, что следующее будет очень быстрым, если у вас загружен файл словаря (который будет по умолчанию, если у вас установлены данные):
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
, который является целочисленным идентификатором строки. Я ожидаю, что работа с целыми числами будет немного быстрее, чем с наборами строк:
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, потому что вы работаете с наборами целых чисел, а не со строками.
Если вы действительно заботитесь об эффективности, зачастую удобнее просто работать в Cython, вместо того, чтобы пытаться угадать, что делает Python. Вот основной цикл:
# cython: infer_types=True
for token in doc.c[:doc.length]
orth = token.lex.orth
doc.c
— это TokenC*
, поэтому вы перебираете непрерывную память и разыменовываете один указатель (token.lex
— это const LexemeC*
)
person
syllogism_
schedule
04.01.2017