Prolog 与 WordNet (4)

来源:互联网 发布:华为mate9pro下载软件 编辑:程序博客网 时间:2024/06/05 08:36

3、使用 WordNet

以下讨论使用 WordNet 的基本问题,并给出几个方便使用的谓词,以提高效率。若要更多的文档,请查看源程序。

(1)建立索引

Prolog 版的 WordNet 数据库文件,共有代码484381行。因而提高文件处理速度,是 WordNet 的主要目标之一。减少查词时间的一个办法,是建立索引。

从 WordNet 中查找单词,我们需要用到谓词

s(+Synset_ID,+W_Num,+Word,+SS_Type,+Sense_Number,+Tag_Count).

可用谓词 g(+Synset_ID,+Gloss). 查询单词的含义。

要找的单词,由 s/6 的第3个形参 Word 指定,这意味着默认的索引不影响匹配的合一。

建立索引的办法有2个。一个是内建的谓词 index(+Predicate) ,以形参指定索引用到的谓词。若按形参 Predicate 建立索引,该形参就实例化为1;否则,实例化为0。记住,在居前的32个形参中,最多4个可以索引。因此,查词时,谓词 index(s(0,0,1,0,0,0))应该优化。这项技术的优点,是我们可以对多于一个的形参建立索引,例如,同义词集合的标示、单词本身;缺点是我们不得不在每个生成的文件中,声明谓词 index/1,于是,数据库的兼容性变差。

以索引减少查词时间的第二个办法,是将文件 wn_s.pl 的形参顺序改变。谓词 improve_file/0 将谓词 s 作为第一参数,并通过 s 取得单词。其他参数保留原有顺序不变。更新后的文件是 wn_s_new.pl。现在,默认的索引方式提高了查找速度,可达到原来的9倍。

(2)转换 WordNet 文件

将 WordNet 用作自然语言处理时,有几种通常的办法,简化与其他工具的交互。尤其开发 Prolog 的自然语言处理工具时,我们可用以下参数改进交互。首先,在子句中只允许小写字母出现;其次,不用下划线分隔单词,改用列表 list;第三,使用开放式列表,以便处理单词、语句和全文。

如上所说,谓词 convert_file/0 用于转换 wn_s.pl 文件,它是谓词 improve_file/0 的扩展。建立索引的好处依然存在。下面这个子句是新结构的实例:s([human, action|_G4016],100022113,2,n,1,1).

(3)WordNet 的一个子集

为了方便测试的需要,可以只用 WordNet 的子集。子集只包括英语最常用的单词。由此,我要介绍谓词 subset_wn_s(+Number)。

谓词 subset_wn_s(+Number) 以文件 wn_s.pl 作为输入的数据,并且创建新文件 wn_s_subset.pl。新文件只包括最常用的单词,具体的单词由谓词 s/6 确定。谓词的参数 Number 指定在子集中应该有多少单词。这将极大地加速 WordNet 的实验。

如果你决定在项目中使用子集,可以做个有趣的尝试,不仅建立主要文件 wn_s.pl 的子集,还要对 WordNet 其他文件建立子集。谓词 subset_wordnet(+Number) 查询子集 wn_s/1,并且转换其他相应文件。新文件的名字是 wn_operator_subset.pl。

这些谓词可以实现使用 WordNet 子集的好处。另外,它们给出了如何自动转换文件的编程示范。将来可以创建不同的子集,如仅含名词、动词、形容词的 WordNet 子集。

(4)很有用的 WordNet 谓词

使用 WordNet 需要 Prolog 数据库的界面。本文列出的全部谓词,都在 Prolog 文件中有详细描述。你只需查阅这些文件定义的谓词,即可使用它们。其他文件可在调入内存后查询。

首先,需要弄清怎样的输入谓词可接受。由于我们转换了文件以使用开放式列表,它也就明显成为输入对象。为了更便于用户使用,Prolog 的数据类型“原子”也是可用的。例如,如果你要输入单词 dog,可以键入它或者 [dog|X]。但如前所述有一例外:由于其他自然语言处理工具不承认下划线,若是2个单词,你必须用开放式列表,如 [physical,thing|X]。

全部谓词都是为了转换 WordNet 文件,而非原始数据。用完整数据库还是其子集,可以选择。WordNet 最直接的用途是查找单词。谓词 lookup(+Word) 从文件 wn_s.pl 中查找单词,并显示其语法类别和定义。它的扩展 lookup(+Word,-SynsetList) 查找单词,并返回该词的全部同义词集合。若要得到单词不同含义的全部同义词,这个谓词很有用处。这2个谓词定义在文件 lookup.pl。

在本文的上半部分,我说明了 WordNet 文件,描述了单词作同义词分组的方式。谓词 find_synset(+Synset_ID,-WordList) 按照给出的同义词集合标示,返回一列表,内有该集合的全部单词。它定义在文件 find_synset.pl 中。

同时,详尽解释了各种语义关系和字面关系。下面实验谓词对这些关系的处理。

谓词 find_hyp_chains(+Word,+Cat) 查找单词的上位词链,并将它们列表显示。例如,[[organism|_G529], [being|_G520]] 是单词 dog 的上位词链,因此,上位词链还有 [[animal|_G616], [animate, being|_G607], [beast|_G595], [brute|_G586], ... 。

记住,只有动词和名词可作上位词。只有同类的词能成为上位词,用户必须在第二个形参指定类别。例如,你若查找名词 dog 的上位词,会发现单词 mammal。你当然不是要找单词 to move,即动词 to dog(跟踪)的上位词。

谓词 find_hyp(+Word,+Cat,-HypList) 查询单词的全部上位词,并以列表返回。

谓词 find_ent_chains(+Word) 和 find_ent(+Word,-EntList) 是用于找蕴含关系词。不同的是,不必指定词类,因为蕴含关系仅适用于动词。上述4个谓词定义在文件 hyp_ent.pl 中。

这4个谓词很相似,find_hyp_chains/2 和 find_ent_chains/1 都调用通常程序谓词 find_chain/3,并以第4个形参确定是上位关系还是蕴含关系。同样,find_chain/3 和 find_ent/1 则调用通常程序谓词 find/4,并以第3个形参确定是上位关系还是蕴含关系。

谓词 find_sim_meanings(+Word) 为一形容词查找全部相似意思,予以显示。与之类似的谓词 find_sim(+Word,-SimList) 返回一列表,内为与参数Word相类似的词。相类似的词,不一定是上位关系或蕴含关系。因此,查找全部相类似的办法,是用内部谓词 find_all。它不用递归循环去寻找相似关系链。

如前所说,文件 wn_mm.pl, wn_ms.pl 和 wn_mp.pl 描述“部分”与“整体”之间产生的几种关系。以下的谓词,是表示和处理这些关系的接口。“部分”与“整体”之间的关系,只产生于名词。

谓词 member_of(+Word,-GroupList) 的输入变元是 Word,用于查找包含成员 Word 的集合,将其以列表 GroupList 输出。例如:

?- member_of(faculty,X).
X = [school|_G413]

得到的结果,faculty(全体教职员)是 school 的组成部分。

谓词 has_member(+Word,-MemberList) 查找在集合中的成员,以列表输出。例如:

?-has_member(faculty,X).
X = [professor|_G407]

得到的结果,professor(教授)是 faculty(全体教职员)的组成部分。

谓词 substance_of(+Word,-List) 和 has_substance(+Word,-SubstanceList) 查找属于Word的物质名词,或者包含该物质的名词,以列表返回。例如:

?- substance_of(water,X).
X = [tear|_G407]

? has_substance(water,X).
X = [h2o|_G407]

水是构成眼泪的物质,水分子是构成水的物质。

谓词 part_of(+Word,-WholeList) 和 has_part(+Word,-PartList) 返回是 Word 一部分的词汇列表。例如:

?- part_of(leg,X).
X = [table|_G407]

? has_part(leg,X).
X = [knee|_G407]

单词 leg(腿)是 table(桌)的一部分,knee(膝)是 leg 的一部分。

输入变元可以是“原子”或开放式列表,输出变元是开放列表。2个谓词在文件 meronym_holonym.pl 中定义。

谓词 member_of/2, substance_of/2 和 part_of/2 调用通常程序 all_one/4,并以第3个变元指定相应的文件扩展名 mm, ms 和 mp。

首先,我们用它们作为通用操作符构成相应的谓词,其次,调用内建谓词 find_all/3 获得答案。再用 list/2 查找属于同义词集合标识的全部单词,并将它们存入列表。还有另外2个定义可供选择,一是原子,二是开放式列表。谓词 all_two/4 与之相似,但不是匹配第1变元与返回第2变元,它是以对第2变元进行合一。这个谓词配合 has_member/2, has_substance/2 和 has_part/2 的处理。

最后,谈谈谓词 cause(+Verb,-CauseList)。

这个谓词的输入变元 Verb 给定一个动词,并返回它产生的动词列表。例如,动词 leak 是动词 break, get out, get around 产生的结果。这个谓词定义在文件 cause.pl 中,并且这个谓词只有一行代码。它与谓词 member_of/2 的机制完全相同。它以第3个变元调用谓词 all_one/4。现在,我们知道了为何谓词 all_one/4 需要第4个变元指定类别。由于表示和处理“部分-整体”关系,只能用名词,却还要指定类别,似乎不可思议。但我们是重用谓词于因果关系,为了能处理动词,需要引入新变元。

(5)如何处理不在 WordNet 数据库中的普通单词

本节是关于无法从WordNet发现的词汇的。当你面对以WordNet作为自然语言处理工具的数据库时,这是个重要问题。

谓词 lookup_text(+FileName) 试图查找文本中的全部单词,发现不在 WordNet 中的词,显示出来。调用这个谓词,你会看到一些词不在 WordNet 数据库中,如 this, which, whether, of, from, the, my, is 等。如何处理这些词呢?这取决于你所遇到的问题。扩展知识库是一个办法。如果 lookup_text/1 返回单词列表,而不作屏显,那它是很有用处的。它的新形式是 lookup_text(+FileName,-List)。

(6)为 ProNTo 语态学分析器提供的接口

Jason Schlachter 设计的 ProNTo 是 独立的 Prolog 自然语言处理工具,可单独使用也可集成使用。如果集成使用,WordNet 数据库必须有语态学分析工具的接口。ProNTo 有几种输出,需要 WordNet 检查是否单词。ProNTo 只能一次分析一个单词。它的输出是一列表,包含单独的语态学分析结果。通过回溯,可以得到全部分析结果,如 [[walk,-ed]]。后来,ProNTo 的输出结果扩展为包括如何分割单词的列表,如 [[walked],[walke,-d],[walk,-ed]]。现在,要检查语态学的说明解释是否单词,可以调用谓词 morph_atoms_lookup(+Morph)。若在 WordNet 中找到该单词,则调用成功,反之则失败。但语态学分析器也解释较长的词组或语句,例如,分析的结果是[[[he]],[[walked],[walke,-ed],[walk,-ed]],[[slowly],[slow,-ly]]]。

这个例子是谓词 morph_bag_lookup(+Morph) 处理的结果。如果在 WordNet 中发现至少一个单词列表,该谓词执行成功,否则它失败。对于要使用ProNTo工具的人来说,这些谓词很有用处。谓词执行的成败还不够,更有用的是它输出的信息。因此,我设计了以下几个谓词 morph_atoms_lookup(Morph,Result) 和 morph_bag_lookup(Morph,Result),它们有同样的输入变元,但以第2变元返回一单词列表,而不管成败。如果找不到输入的词,它返回这样的列表 [word,synset_ID,w_num,category]。

例如:

?- morph_atoms_lookup([[talk,-ed]],R).
R = [[talk, 100677091, 1, n]] ;
R = [[talk, 105953501, 1, n]]

?- morph_bag_lookup([[[he]],[[talked],[talke,-d],[talk,-ed]]],R).
R = [[he, 105716399, 1, n], [talk, 100677091, 1, n]] ;
R = [[he, 105716399, 1, n], [talk, 105953501, 1, n]]

若想更多了解这些谓词是如何工作的,请查看文件 morph lookup.pl。

4、结论

本文是为了给 Prolog 版本的 WordNet 做份好文档。本文给出的知识,会简化 PrologWordNet 数据库的编程工作。当然,列出的谓词可由用户根据实际需要作出扩展。