最近在学习文本挖掘,故而把书中关键的内容做个笔记,方便以后查阅。
信息检索是从大规模非结构化数据(通常是文本)的集合(通常保存在计算机上)中找出满足用户需求的资料的(通常是文档)的过程。按照所处理的数据的规模,信息检索可以分为三个级别:
第一个级别是以web搜索为代表的大规模级别;
第二个级别是小规模,可以看成是与第一种规模相对的另一极端情况;
第三个级别是中等规模的数据,包括面向企业、机构和特定领域的搜索(比如公司内部文档、专利库或生物医学文献的搜索)。
下面是一个信息检索的例子,以此来介绍布尔检索模型的基础知识
很多人都有《莎士比亚全集》这本书。假定你想知道其中的哪些剧本包含 Brutus 和 Caesar 但不包含 Calpurnia。一种办法就是从头到尾阅读这本全集,对每部剧本都留心它是否包含 Brutus 和 Caesar 且同时不包含 Calpurnia。这种线性扫描就是一种最简单的计算机文档检索方式,这个过程通常叫做grepping。
但是,很多情况下只采用上述扫描方式是远远不够的,我们需要做更多的处理,例如。
(1)大规模文档集条件下的快速查找。我们可能需要在几十亿到上万亿单词的数据规模下进行查找。
(2)有事我们需要更灵活的匹配方式。比如,在grep命令下不能支持诸如Romans NEAR countrymen之类的查询,这里的NEAR操作符定义可能为“5歌词之内”或者“同一个句子”中。
(3)需要对结果进行排序。很多情况下,用户希望在多个满足自己需求的文档中得到最佳答案。
此时,我们就不能采用线性扫描的方式了。一种非线性扫描的方式是事先给文档建立索引。
例如《莎士比亚全集》,假定我们对每篇文档(剧本)都事先记录他是否包含词表中的某个词,结果都会得到一个由布尔值构成的词项-文档关联矩阵。如下图
词项是索引的单位,它通常可以用词来表示,目前可以把词项当成词,以后会具体讨论。
此时,之前我们讨论的包含 Brutus 和 Caesar 但不包含 Calpurnia 的剧本,就可以转换为这种形式
Brutus AND Caesar AND NOT Calpurnia
分别取出Brutus、Caesar、Calpurnia对应的行向量,并对 Calpurnia 对应的向量求反,然后进行基于位的与操作,得到:
110100 AND 110111 AND 101111 = 100100
结果向量中的第1个和第4个元素为1,这表明该查询对应的剧本是 Antony and Cleopatra 和 Hamlet 。
但这样的方法也有一个很明显的缺陷。我们假定这样一种情况,词项的个数是50万,文档篇数为100万,所以其对应的词项-文档矩阵大概有5000亿(50万×100万)......呵呵,这已经远远大于一台计算机的内存容量了。另外,我们不难发现,这个庞大的矩阵实际上具有高度的稀疏性,即大部分元素都是0,只有极少数元素为1。(实际上这个矩阵中的99.8%的元素都是0)。很显然,只记录原始矩阵中的1的位置表示方法比词项-文档矩阵更加合理。于是,这里我们接触到了信息检索的第一个核心概念—倒排索引。倒排索引的基本思想如下图。
左部成为词项词典,每个词项都有一个记录出现该词项的所有文档的列表,即倒排表。如Brutus,他在第1、2、4、11篇文章中有出现;Caesar则在第1、2、4、5、6篇文章中有出现。
那么,如何构建倒排索引呢?下面列出构建索引的主要步骤:
(1)收集需要建立索引的文档,如:
(2)将每篇文档转换成一个个词条的列表,即词条化:
(3)进行语言学预处理,产生归一化的词条来做词项,如:
(4)对所有文档按照其中出现的词项来建立倒排索引,索引中包括一部词典和一个全体倒排记录表。
下图是一个完整的例子:
在最终得到的倒排索引中,词典和倒排记录表都有存储开销。前者往往放在内存中,而后者由于规模大得多,通常放在磁盘上。那么,对于单个倒排记录表应该采用怎样的数据结构呢?可以采用两种比较好的存储方法:一是链表,二是变长数组。
今天记录的内容到此为止,明天继续~~~(以上内容都是书中内容,我只是总结了一下关键点)