2.1 Document delineation and character sequence decoding
2.1.1 Obtaining the character sequence in a document
数字化的文档输入一般都是在服务器上的文件字节流。建立索引的第一步就是把字节流转化成一系列线性字符串,对于以 ASCII 编码的英语来说,这很简单。但是当字符串以其他各种各样的形式编码的时候,就没用那么简单了,不如 UTF-8 之类的其他编码。这可以被认为是一个机器学习的分类问题,我们将会在第 13 节具体讨论。但经常用一些启发式的方法来解决这个问题,或者是用户选择,或者使用提供的文档的 metadata。一旦编码确定下来了,我们就能进行字符串的转化。我们也需要存储下所使用的编码方式,这会告诉我们原文档是用什么语言写的。
这些字符串可能需要被解码成二进制表示的文件,比如微软的 doc 文件,或者 zip 那样的压缩文件。又一次,我们需要决定好文档的格式,以及正确的 decoder 。就算仅仅是纯文本文档,额外的 decoding 也是可能需要的。比如在 XML 文档里,字符实体,比如 ‘&’ 就需要被正确解码,结果是 ‘&’。最后,可能还要进行一些重要文本的提取,过滤那些不需要的信息。这可以是一种比较好的 XML 文件的处理方式,在 markup 可以被忽视的前提下。对于 postscript 或者 PDF 文件,我们也可以进行类似的处理。本书不会涉及 postscript 或者 PDF,我们仅仅考虑纯文本文档。商业化的产品需要支持各种各样的用户需求以及文件格式,但用户只关心自己的需求是否得到了满足,他们只考虑文本存在于应用中并且甚至不会去想编码方式或者硬盘存储这些技术细节。一般来说,都会授权给某些 software library 来专门处理编码和解码的问题。
把文本当成纯粹的线性字符串来处理有时也会引发问题,比如 Arabic 语言。 Arabic 语言把文本当成二维的打乱顺序的特征, 如图 2.1 和 2.2 。但是除了一些比较复杂的系统惯例,还是有潜在的声音流以及核心的线性结构,这就是 Arabic 的数字化表示。
2.1.2 Choosing a document unit
下一步就是要确定索引的单位是什么。我们暂且认为文档单元是固定的,比如把每一个文件夹中的一个文件视为一个文档。但有时候可能有其他的情况,传统的 Unix 邮件文件把一系列邮件信息 存在一个文件里,但你可能要把每一个邮件信息单独视为一个文档。如今许多邮件信息包含了附件,有可能你需要把他们分别作为单独的文档。例如附件是一个 zip 文件,你可能想把解压后的每一个文件视为一个单独的文档。相反的,有时候你需要把许多文件合为一个文档。
总的来说,对于长文档来说,问题在于索引的粒度。如果是一系列书籍,一般都不会把每本书当作一个文档,这通常索引效果很差。设想你想搜索中国的玩具,可能你会得到这样一本书,前几章提到了中国后几章又提到了玩具,但和我们的意愿相悖。我们可能 需要为每一章节建立索引,或者是每一段落。这样可能搜索的效果会更好,并且更利于用户定位相关信息。但是为什么不继续 缩小粒度呢?我们可以把单独的句子作为文档,显然这里有一个 precision/recall 的权衡。(precision 指搜索结果的精确性, recall 指搜索结果是否取到了所有相关的文档) 粗粒度的问题可以通过使用 proximity search 来处理,之后我们会继续讨论。现在我们假设选择的文档大小合适,粒度也正好, 并且正确地分开了文档。