Нечеткие совпадающие строки, встроенные в строки - PullRequest
0 голосов
/ 11 мая 2018

У меня есть список из нескольких тысяч мест и список из миллионов предложений. Моя цель - вернуть список кортежей, в которых сообщается о сопоставленном комментарии и месте, указанном в комментарии. Например:

locations = ['Turin', 'Milan']
state_init = ['NY', 'OK', 'CA']

sent = ['This is a sent about turin. ok?', 'This is a sent about milano.' 'Alan Turing was not from the state of OK.'

result = [('Turin', 'This is a sent about turin. ok?'), ('Milan', 'this is a sent about Melan'), ('OK', 'Alan Turing was not from the state of OK.')]

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

Milan

должно соответствовать

Melan, Mlian, or Mlan but not Milano 

Следующая функция очень хорошо работает для всего, кроме нечеткого сопоставления и возврата кортежа, но я не знаю, как сделать что-либо из этого без цикла for. Не то чтобы я был против использования цикла for, но я все еще не знал бы, как реализовать это таким образом, чтобы он был эффективен в вычислительном отношении.

Есть ли способ добавить эти функции, которые мне интересны, или я пытаюсь сделать слишком много в одной функции?

def find_keyword_comments(sents, locations, state_init):
    keywords = '|'.join(locations)
    keywords1 = '|'.join(state_init)
    word = re.compile(r"^.*\b({})\b.*$".format(locations), re.I)
    word1 = re.compile(r"^.*\b({})\b.*$".format(state_init))
    newlist = filter(word.match, test_comments)
    newlist1 = filter(word1.match, test_comments)
    final = list(newlist) + list(newlist1)
    return final

1 Ответ

0 голосов
/ 11 мая 2018

Я бы порекомендовал вам взглянуть на метрики для нечеткого сопоставления, в основном интересует вас Расстояние Левенштейна (иногда называемое расстоянием редактирования).

Здесь Некоторые реализации в чистом Python, но вы можете использовать несколько модулей, чтобы сделать вашу жизнь проще:

  • fuzzywuzzy очень распространено (устанавливается pip)пакет, который реализует это расстояние для того, что они называют чистое соотношение .Он предоставляет немного больше функциональности, чем вы, возможно, ищете (частичное сопоставление строк, игнорирование знаков препинания, нечувствительность к порядку следования токенов ...).Единственным недостатком является то, что ratio также учитывает длину строки.См. этот ответ для дальнейшего базового использования

    from fuzzywuzzy import fuzz
    fuzz.ratio("this is a test", "this is a test!")  # 96
    
  • python-Levenshtein - довольно быстрый пакет, потому что это в основном оболочка в pythonв библиотеку С внизу.Документация не самая хорошая, но должна работать.Теперь он вернулся в индекс PyPI, поэтому его можно установить в pip.

...