【问题标题】:Python inverted index efficiencyPython倒排索引效率
【发布时间】:2012-03-21 07:54:20
【问题描述】:

我正在编写一些 Python 代码来实现我最近学习的一些概念,这些概念与倒排索引/发布列表有关。我对 Python 很陌生,在某些情况下很难理解它的效率。

理论上,创建一组文档 D 的倒排索引,每个文档都有一个唯一 ID doc_id,应该包括:

  1. 解析/执行 D 中每个文档的词法分析
  2. 删除停用词、执行词干提取等
  3. 创建所有 (word,doc_id) 对的列表
  4. 对列表进行排序
  5. 将重复项压缩为{word:[set_of_all_doc_ids]}(倒排索引)

第 5 步通常是通过使用包含带有元数据(词频、字节偏移)的单词和指向发布列表(它出现在其中的文档列表)的指针的字典来执行的。帖子列表通常实现为允许有效随机插入的数据结构,即链表。

我的问题是 Python 是一种高级语言,直接使用内存指针(以及链表)之类的东西似乎超出了范围。我在分析之前进行了优化,因为对于非常大的数据集,众所周知,必须最大化效率才能保留在合理时间内计算索引的任何能力。

关于 Python 倒排索引的 SO 上还有其他几篇文章,就像我当前的实现一样,它们使用字典将键映射到列表(或集合)。人们是否期望这种方法与允许直接编码指向链表的指针的语言具有相似的性能?

【问题讨论】:

  • 当你说链表在 python 中是不可能的,那是完全错误的。你的意思是指针算术吗?

标签: python performance search-engine inverted-index


【解决方案1】:

有很多话要说:

  1. 如果特定列表实现需要随机访问,则链表不是最佳(无论编程语言如何)用过的)。要访问列表的第 i 个元素,链表要求您从第 0 个元素一直迭代到第 i 个元素。相反,列表应该存储为一个连续的块(如果它很长,则应存储为几个大块)。 Python 列表[...] 是以这种方式存储的,所以一开始,一个 Python 列表就足够了。

  2. 在 Python 中,任何赋值 a = b 对象b 不是基本数据类型(例如intfloat),由内部执行传递一个指针并将引用计数增加到b。因此,如果b 是一个列表或字典(或用户定义的类,就此而言),原则上这与在 C 或 C++ 中传递指针没有太大区别。

  3. 但是,a) 引用计数和 b) 垃圾回收显然会产生 一些开销。如果实现是为了学习目的,即更好地理解倒排索引的概念,我不会担心。但是对于一个严肃的、高度优化的实现,使用纯 Python(而不是嵌入到 Python 中的例如 C/C++)是不可取的。

  4. 当您进一步优化发布列表的实现时,您可能会发现需要 a) 进行随机插入,b) 保持排序和 c) 保持压缩 - 所有这些都同时进行。到那时,标准 Python 列表将不再足够好,您可能需要考虑在 C/C++ 中实现更优化的列表表示并嵌入它 进入 Python。然而,即便如此,仍然可能坚持使用纯 Python。例如。您可以使用大字符串来实现列表,并使用itertoolsbuffer 以某种方式访问​​特定部分,这在某种程度上类似于指针算法。

  5. 在处理 Python 中的字符串 时应始终牢记的一件事是,尽管我在上面提到了赋值操作,substring 操作text[i:j] 涉及创建子字符串的实际(深度)副本,而不仅仅是增加引用计数。这可以通过使用上面提到的buffer 数据类型来避免。

【讨论】:

  • 您好,回复很好,感谢您抽出宝贵时间。我想我在某种程度上预计 Python 可能不是解决这个问题的最佳方法。正是字符串操作的简便性吸引了我。至于 (4),我现在可能会坚持使用静态发布列表,但我可能会使用某种类型的编码来优化空间。感谢您的建议和您对 Python 的见解。
【解决方案2】:

您可以在 Python 中查看倒排索引的代码和文档:http://www.ssiddique.info/creation-of-inverted-index-and-use-of-ranking-algorithm-python-code.html

很快我就会用 C++ 编写代码。

【讨论】:

  • 您的链接似乎已损坏
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-07-09
  • 2012-03-16
  • 1970-01-01
  • 1970-01-01
  • 2013-07-07
相关资源
最近更新 更多