Поиск группы слов в python реализован рекурсивно.Как действовать? - PullRequest
0 голосов
/ 19 декабря 2018

Я должен искать концепции в текстах.Понятия выражаются следующим образом:

"blue 5 house" >>> означало бы, что я должен найти совпадения, где слова blue и house появляются в пределах distance of 5 or less words."little 3 cat" будет означать поиск совпадений, где слова little и cat появляются в пределах distance of max 3 words.(то есть "маленькая кошка", "маленькая раздражающая кошка", но не "кошка моей бабушки маленькая")

Я думаю, вы поняли.

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

with open('applicationtext.txt', 'r') as f:
content=f.read()
# content = ' Lorem ipsum dolor sit amet, consectetur (23) adipiscing elit, sed do ( 23 , 45 ) eiusmod ( 23, 45 ) tempor incididunt ut  '
# Note: the text contains several times: "sit amet eros vestibulum"

elasticTerm1="sit"
elasticTerm2="vestibulum"
distance=5

content=content.strip()
# replace all the line breaks and two spaces.
content = content.replace('\n', ' ').replace('\r', '').replace('  ',' ')

listofHits=[]
content_tokenized = content.split(" ")

for i,word in enumerate(content_tokenized):
    if word==elasticTerm1:
        for j in range(distance):
            if content_tokenized[i+j]==elasticTerm2:
                # I got a hit
                position1=i
                myhitTupple=(i,elasticTerm1)
                listofHits.append(myhitTupple)

for i,tupple in enumerate(listofHits):
    print(tupple)

Пока все работает нормально.

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

(little 3 cat) 4 third_word иличетный concept1 5 concept2;где concept1=("blue 3 cat") и concept2=("little 4 dollar") ???

о чем мне думать?класс?это уже как-то содержится в scikit-learn?Больше, чем код (который, я думаю, будет сложно), я прошу вас об ориентации.Как думать о проблеме, решаемой с помощью кода рекурсивно.

Спасибо

ПРИМЕЧАНИЕ 1. Пожалуйста, забудьте о порядке "маленькая кошка" против "маленькая кошка", это еще одна проблема.

ПРИМЕЧАНИЕ 2: (после первого ответа) Имейте в виду, что это очень упрощенный случай, в действительности я смотрю на такие случаи: ((concept1 n1 concept2) n2 concept 3)) n3 (concept1 n4 concept 5)

1 Ответ

0 голосов
/ 19 декабря 2018

Ключевые наблюдения, лежащие в основе решения:

  • когда мы совершаем переход от токенов к «концепциям», нам нужен диапазон вместо индекса.
  • Нам нужно определить функцию длянайти «расстояние» между двумя понятиями, т.е. их соответствующий диапазон.(dist ниже)
  • другая функция для объединения понятий, т.е. их диапазонов.(comb ниже)

Теперь в нашей основной рекурсивной функции мы сначала выясним все вхождения обоих понятий.Тогда мы можем просто найти пары, расстояние которых меньше указанного.В этой реализации наша основная hits() принимает «концепт»: это либо просто слово в базовом регистре, либо кортеж из 3 элементов, который имеет две концепции и int, указывающий максимально возможное расстояние между ними.Выход этой функции представляет собой массив диапазонов, где каждый из этих диапазонов содержит обе концепции с максимальным расстоянием.Этот массив можно рассматривать как все вхождения концепции ввода.

Вот полный код.

#Find distance between two concept's ranges
#ex1: dist([2,9],[11,13]) = 2
#ex2: dist([2,9],[4,99]) = 0
def dist(r1,r2):
    #check for overlap
    if r2[0]<=r1[0]<=r2[1] or r1[0]<=r2[0]<=r1[1]:
        return 0

    return max(r1[0],r2[0]) - min(r1[1],r2[1])

#Combine two concept's ranges
#ex1: comb([1,3],[6,9]) = [1,9]
#ex2: comb([4,11],[1,7]) = [1,11]
def comb(r1,r2): 
    return [min(r1[0],r2[0]),max(r1[1],r2[1])]

def hits(concept):
    if type(concept)==str:
        return [(i,i) for i,w in enumerate(tokens) if w==concept]

    c1,c2,R = concept
    ans = []
    for r1 in hits(c1):
        for r2 in hits(c2):
            if dist(r1,r2)<=R:
                ans.append(comb(r1,r2))
    return ans

Чтобы проверить это, случай 1: (это выводит [[0-9]])

tokens = "python group of words search implemented recursively How to proceed".split()
c1 = ("python","words",3)
c2 = ("recursively","proceed",4)
print(hits((c1,c2,3))) 

случай 2: (выводит [[0-8]])

c1 = ("python","of",3)
c2 = ("search","recursively",4)
print(hits(((c1,c2,3),"to",3)))

случай 3: (выводит [[0, 3], [6, 8]])

tokens = "A B B X C C X Q A W".split()
c1 = ("A","X",4)
print(hits(c1))

Для производительности предварительно обработать базовый вариант рекурсии.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...