Извлечение ключевых слов из документов на основе фиксированного списка ключевых слов / фраз

У меня есть список примерно из 100 ключевых слов, и мне нужно искать их в огромном корпусе из более чем 0,1 миллиона документов.

Мне не нужно точное соответствие, например, если ключевое слово - Фонд роста, я ожидаю все совпадения, такие как фонды роста, фонд роста Америки и т. Д.

Есть предложения по этому поводу?

Я пробовал использовать Spacy PhraseMatcher, но он дает ValueError: [T001] Максимальная длина в настоящее время 10 для сопоставления фраз.

import spacy
from spacy.matcher import PhraseMatcher

full_funds_list_flat = "<list of 100+ Keywords>"


nlp = spacy.load('en_core_web_sm')
keyword_patterns = [nlp(text) for text in full_funds_list_flat]
matcher = PhraseMatcher(nlp.vocab)
matcher.add('KEYWORD', None, *keyword_patterns)

person Keshav Kumar    schedule 26.03.2019    source источник
comment
возможно, подумайте, что лакх не является общеизвестным словом для измерения в большинстве стран мира.   -  person Christian Sloper    schedule 26.03.2019
comment
@ChristianSloper мой плохой, отредактировал   -  person Keshav Kumar    schedule 26.03.2019
comment
@KeshavKumar добро пожаловать. Интересный вопрос. Можете показать, что пробовали? Кроме того, на ум приходят некоторые концепции, которые могут помочь - лемматизация, разбиение на фрагменты именованных сущностей и распараллеливание. Первые два рассматриваются в любом хорошем введении в НЛП. Последнее - просто здравый смысл для большого корпуса.   -  person fiacre    schedule 26.03.2019
comment
@fiacre Спасибо :) Отредактировал вопрос кодом, который я пробовал. Я лемматизирую токены, прежде чем передать их сопоставителю фраз. Что касается фрагментов именованных сущностей, поскольку список слов, которые я должен найти, не принадлежит ни к каким предопределенным именованным сущностям, и даже для меня невозможно вручную пометить данные, поэтому обучение пользовательской модели NER кажется трудным. Большое спасибо, пожалуйста, предложите, если что-то еще бросается в глаза.   -  person Keshav Kumar    schedule 27.03.2019


Ответы (3)


Сейчас я работаю над чем-то очень похожим. У нас есть несколько вариантов, вот краткий выбор:

  • Итерируйте, используя "a in b". Хотя это довольно просто, это очень мощно и, хотя и не идеально, если это однократная проверка для этих ключевых слов, вы можете найти наиболее частичное совпадение (если во множественном числе только 's', «совпадение» в «совпадениях» == Правда)

  • Сохраните свой корпус в Postgresql и используйте встроенную опцию полнотекстового поиска, которая довольно сильна. Это тяжелее, но поможет вам, если вам нужно повторить ключевое слово несколько раз, поскольку вы выполняете преобразование только один раз. см. https://www.compose.com/articles/mastering-postgresql-tools-full-text-search-and-phrase-search/

Поскольку я не эксперт, я открыт для любых идей и знаю, что это может быть не лучший ответ. Но, по крайней мере, тебе есть чем заняться.

person Born Tbe Wasted    schedule 26.03.2019
comment
Спасибо. Обязательно попробую второй вариант и обновлюсь. Из первого, что я понял, вы хотели токенизировать документы и искать каждый токен в списке? Как жетон в списке. Как вы правильно сказали, будет хорошо, если это будет разовая проверка, но в моем случае ее непрерывный процесс и проверка итерации по списку для каждого токена будут слишком дорогими, я полагаю, любезно дайте мне знать ваши мысли. - person Keshav Kumar; 27.03.2019
comment
Вместо использования полноценной базы данных вы можете использовать движок Lucene (который доступен в Python через pylucene Он предназначен именно для решения вашей проблемы. - person sophros; 05.02.2020

Я бы рекомендовал вам использовать нечеткую библиотеку Python, поскольку вам не нужно точное совпадение, она использует алгоритм расстояния Левенштейна. Что точнее будет узнать фразы.

справочная ссылка - https://github.com/seatgeek/fuzzywuzzy

person Naitik Chandak    schedule 27.03.2019
comment
Я бы не рекомендовал levenshtein - он говорит вам, на сколько букв разнесены два слова с точки зрения замененных / удаленных / добавленных символов - это не скажет вам, что два слова являются синонимами. Я не могу комментировать библиотеку Fuzzywuzzy, но levenshtien не помогает с синонимами. - person Evan Mata; 27.03.2019
comment
Расстояние Левенштейна (LD) - это мера сходства между двумя строками. Поскольку нам не нужно точное совпадение строк, мы можем найти коэффициент нечеткости с помощью библиотеки fuzzywuzzy. - person Naitik Chandak; 28.03.2019

Есть несколько вариантов, я бы порекомендовал сначала использовать лемматизацию в вашем корпусе. Я не знаю, со сколькими именованными сущностями вам нужно будет работать, поэтому вы можете подумать о конкретном подходе для них (лемматизация здесь не поможет, но, как уже упоминал кто-то другой, A в B может помочь, или вы могли бы добавить их как отдельные случаи в SpaCy). Еще одна рекомендация - использовать кортежи в модели word2vec (или другом встраивании текста) и проверять k-наиболее похожие слова на некоторые слова, которые вы хотите избежать повторения, и использовать это для информирования о любых случаях, которые вы хотели бы специально проверьте. Еще один быстрый способ найти возможные фразы, которые следует учитывать в первую очередь, - это импортировать модель (у gensim есть некоторые) и просто извлечь любые фразы / слова, не входящие в модель - это, вероятно, даст вам много названных сущностей, поэтому вы знаете, какие дела вам придется рассмотреть.

person Evan Mata    schedule 27.03.2019