Найти процент токенов, разделяемых двумя документами с пространством

Для nltk это было бы что-то вроде:

def symm_similarity(textA,textB):
    textA = set(word_tokenize(textA))
    textB = set(word_tokenize(textB))    
    intersection = len(textA.intersection(textB))
    difference = len(textA.symmetric_difference(textB))
    return intersection/float(intersection+difference) 

Поскольку spacy быстрее, я пытаюсь сделать это в просторном виде, но объекты-токены, похоже, не предлагают быстрого решения этой проблемы. Есть идеи?

Спасибо всем.

1 ответ

Решение

Ваша функция получает процент общих типов слов, а не токенов. Вы берете набор слов без учета их количества.

Если вы хотите подсчитать количество токенов, я ожидаю, что следующее будет очень быстрым, если у вас загружен словарный файл (который будет по умолчанию, если у вас установлены данные):

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*)

Другие вопросы по тегам