索引文档中单词的最有效方法?

Leg*_*end 7 python text nlp

这出现在另一个问题中,但我认为最好将此问题作为一个单独的问题.提供大量句子(订单数量为10万):

[
"This is sentence 1 as an example",
"This is sentence 1 as another example",
"This is sentence 2",
"This is sentence 3 as another example ",
"This is sentence 4"
]
Run Code Online (Sandbox Code Playgroud)

编写以下函数的最佳方法是什么?

def GetSentences(word1, word2, position):
    return ""
Run Code Online (Sandbox Code Playgroud)

这里给出了两个词,word1,word2和位置position,函数应该返回满足该限制所有语句列表.例如:

GetSentences("sentence", "another", 3)
Run Code Online (Sandbox Code Playgroud)

应该返回句子1和句子3的索引.我目前的方法是使用这样的字典:

Index = defaultdict(lambda: defaultdict(lambda: defaultdict(lambda: [])))

for sentenceIndex, sentence in enumerate(sentences):
    words = sentence.split()
    for index, word in enumerate(words):
        for i, word2 in enumerate(words[index:):
            Index[word][word2][i+1].append(sentenceIndex)
Run Code Online (Sandbox Code Playgroud)

但是,由于我的48GB RAM在不到5分钟的时间内耗尽,因此在数据集大小约为130 MB的情况下,这很快就会导致一切不成比例.我不知何故感觉这是一个常见的问题,但无法找到有关如何有效解决这个问题的任何参考.有关如何处理此问题的任何建议?

Tad*_*eck 14

使用数据库存储值.

  1. 首先将所有句子添加到一个表中(它们应该具有ID).你可以称它为例如.sentences.
  2. 其次,所有句子中包含的单词创建表格(例如words,将每个单词称为ID),在单独的表格中保存句子表格记录和单词表格记录之间的连接(例如sentences_words,调用它,它应该有两列,优选word_idsentence_id).
  3. 当搜索包含所有提到的单词的句子时,您的工作将被简化:

    1. 您应该首先words表中查找记录,其中的单词正是您搜索的记录.查询可能如下所示:

      SELECT `id` FROM `words` WHERE `word` IN ('word1', 'word2', 'word3');
      
      Run Code Online (Sandbox Code Playgroud)
    2. 其次,您应该从表找到sentence_idsentences具有所需word_id值的值(对应于words表中的单词).初始查询可能如下所示:

      SELECT `sentence_id`, `word_id` FROM `sentences_words`
      WHERE `word_id` IN ([here goes list of words' ids]);
      
      Run Code Online (Sandbox Code Playgroud)

      这可以简化为:

      SELECT `sentence_id`, `word_id` FROM `sentences_words`
      WHERE `word_id` IN (
          SELECT `id` FROM `words` WHERE `word` IN ('word1', 'word2', 'word3')
      );
      
      Run Code Online (Sandbox Code Playgroud)
    3. 在Python中过滤结果,只返回sentence_id具有所需所需word_idID的值.

这基本上是一种基于以最适合的形式存储大量数据的解决方案 - 数据库.

编辑:

  1. 如果你只搜索两个单词,你可以在DBMS方面做更多(几乎所有的).
  2. 考虑到你还需要位置差异,你应该将单词的位置存储在sentences_words表格的第三列中(让我们只调用它position),当搜索适当的单词时,你应该计算与这两个单词相关的这个值的差异.

  • +1非常感谢你的时间.我想我会配合这个.我正在考虑暂时使用sqlite,但如果这不起作用,也许MySQL. (2认同)
  • 我再次回来再次感谢你.它说"使用正确的工具来完成正确的工作"有很长的路要走:)构建搭配的时间已从X减少(X> 12并且因内存耗尽而没有完成!)现在使用小时到1小时sqlite,它甚至没有重! (2认同)