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

для 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 быстрее, я пытаюсь сделать это в spacy, но объекты-токены, похоже, не предлагают быстрого решения этой проблемы. Любые идеи?

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


person will kinsman    schedule 04.01.2017    source источник


Ответы (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*)

person syllogism_    schedule 04.01.2017
comment
спасибо силлогизм! вы правы, я делал слова, но для моего приложения слова или токены работают нормально. Это определенно будет полезно многим людям, кроме меня. ценю вашу помощь! - person will kinsman; 04.01.2017