Поиск всех концептов во входной строке по большому списку концептуальных строк с использованием Python - PullRequest
0 голосов
/ 29 июня 2018

У меня есть большой набор (говорит 30 миллионов) строк концептов (максимум 13 слов на строку) в базе данных. Учитывая входную строку (возможно, максимум 3 предложения), я хотел бы найти все понятия из базы данных, доступные во входной строке.

Я использую Python для этой цели. Загружены все концепции из базы данных в список. Просмотрите список концепций и попробуйте найти, доступен ли этот концепт во входной строке. Поскольку я должен был искать это вроде последовательно, процесс занимает много времени, и мне придется сделать это для сотен входных строк.

Для сокращения некоторой итерации я токенизировал входную строку и пытался загрузить только концепты, имеющие какой-либо один из токенов, и длина концептов должна быть меньше или равна длине входной строки. Для загрузки этих коротко перечисленных понятий в список требуется запрос sql. Тем не менее, список может содержать 20 миллионов концепций. Процесс не такой быстрый.

Есть идеи, как сделать этот процесс более эффективным?

Для лучшей наглядности приведу небольшой пример:

 inputString = "The cow is a domestic animal. It has four legs, one tail, two eyes"
#load concept list from the database that have any of the words in input string (after removing stop words). Assume the list is as follows.

concepts = ["cow", "domestic animal", "domestic bird", "domestic cat", "domestic dog", "one eye", "two eyes", "two legs", "four legs", "two ears"]

for c in concepts:
    if c in inputString:
        print ('found ' + c + ' in ' + inputString) 

Было бы здорово, если бы вы могли дать мне несколько советов, чтобы сделать его более эффективным.

1 Ответ

0 голосов
/ 29 июня 2018

Вы должны использовать наборы, которые намного быстрее, чем списки и полнотекстовый поиск при поиске предметов.

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

Итак, при следующей инициализации:

from collections import defaultdict
import re
inputString = "The cow is a domestic animal. It has four legs, one tail, two eyes"
concepts = ["cow", "domestic animal", "domestic bird", "forever and ever", "practice makes perfect", "i will be back"]

Разобьем concepts на части наборов, проиндексированных по количеству слов понятий, содержащихся в наборе:

concept_sets = defaultdict(set)
for concept in concepts:
    concept_sets[len(concept.split())].add(concept)

Так что concept_sets становится:

{1: {'cow'}, 2: {'domestic bird', 'domestic animal'}, 3: {'practice makes perfect', "forever and ever"}, 4: {'i will be back'}}

Затем мы превращаем inputString в список слов в нижнем регистре, чтобы совпадение не зависело от регистра. Обратите внимание, что вы можете уточнить здесь регулярное выражение, чтобы оно могло включать некоторые другие символы в качестве «слова».

input_words = list(map(str.lower, re.findall(r'[a-z]+', inputString, re.IGNORECASE)))

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

for num_words, concept_set in concept_sets.items():
    for i in range(len(input_words) - num_words + 1):
        words = ' '.join(input_words[i: i + num_words])
        if words in concept_set:
            print("found '%s' in '%s'" % (words, inputString))

Это выводит:

found 'cow' in 'The cow is a domestic animal. It has four legs, one tail, two eyes'
found 'domestic animal' in 'The cow is a domestic animal. It has four legs, one tail, two eyes'
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...