python 递归实现的词组搜索。如何进行?

python group of words search implemented recursively. How to proceed?

我必须在文本中寻找概念。这些概念的表达方式如下:

"blue 5 house" >>> 意味着我必须找到单词 bluehouse 出现在 distance of 5 or less words 中的命中。 "little 3 cat" 则意味着找到单词 littlecat 出现在 distance of max 3 words 中的命中。 (即 "little cat"、"little annoying cat" 但不是 "the cat of my grandmother is little")

我猜你明白了。

到目前为止,我有一个(不是很复杂的)代码如下。我刚刚实现了两个遍历文本所有单词的嵌套循环,当第一个被命中时开始在周围的单词中寻找另一个并将结果添加到列表中:

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")???

我应该考虑什么? class?它是否已经以某种方式包含在 scikit-learn 中?不仅仅是一个代码(我想这会很复杂)我要问你方向。如何思考用代码递归解决的问题。

谢谢

注意 1:请忘记顺序 "little cat" 与 "cat little" 那是另一个问题。

注意 2:(在第一个答案之后)请注意,这是一个非常简化的案例,实际上我正在看这样的案例:((concept1 n1 concept2) n2 concept 3)) n3 (concept1 n4 concept 5)

解决方案的主要观察结果:

  • 当我们从令牌飞跃到 "concepts" 时,我们需要范围而不是索引。
  • 我们需要定义一个函数来找到两个概念之间的 "distance",即它们对应的范围。 (下图dist
  • 另一个组合概念的函数,即它们的范围。 (下图comb

现在在我们的主要递归函数中,我们首先找出这两个概念的所有出现。然后我们可以简单地找到距离小于指定距离的对。在这个实现中,我们的 main hits() 接受一个 "concept":它要么只是基本情况下的一个词,要么是一个具有两个概念的 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))

为了性能,预处理递归的基本情况。