从非结构化信息中获得更多的价值。研究一个简单的文本挖掘应用程序如何使用 UIMA SDK 构建的文本分析引擎在文档中寻找人名。然后,另一个 UIMA 组件将结果写入 DB2® 数据库中的表。然后利用这些数据,使用 DB2 Intelligent Miner 寻找在文档中经常同时提到的人之间的强关联。简介人们越来越希望使用信息技术从组织中的非结构化信息中获得更大的价值。IBM 最近引入了新的 Unstructured Information Management Architecture(UIMA)框架(参见 参考资料),这个框架简化了分析非结构化媒体对象(比如文档)的系统的开发和部署,可以用来提供语义搜索和文本挖掘等功能。文本挖掘就是用于从文本中提取信息的数据挖掘技术。接下来,具体描述一个非常简单的文本挖掘应用程序。概述本文中描述的文本挖掘应用程序称为 PReston,它对文档进行分析,寻找提到的人名,并使用文本挖掘寻找经常同时提到的人。尽管这种技术只是众多有用的文本挖掘技术之一,但是它演示了这类应用程序的主要特性,并为介绍 UIMA 的使用提供了一个具体示例。它还演示了如何组合结构化数据库和文本挖掘。本文面对的读者是希望了解如何使用新的 UIMA 技术将非结构化和结构化信息联系在一起的人。图 1 给出了 Preston 的概况。这个程序对存储为 DB2 数据库表中的文本字段的文档进行分析。UIMA 框架中的组件从数据库读取并分析文档,寻找以某种格式提到的名称,然后将结果写到另一个数据库 Extracted Information Database(EIDB) 中。这些组件是使用 UIMA SDK 中的工具开发和部署的,UIMA SDK 可以从 developerWorks 获得(参见 参考资料)。对 EIDB 中的信息要进行分析后处理,以便预备进行文本挖掘,这是使用 DB2 Intelligent Miner 完成的。整个应用程序可以很轻易地在笔记本计算机上运行。图 1. 本文中描述的 Preston 文本挖掘应用程序的概况
在本文中作为示例使用的文档是来自 Internet Movie Database(IMDB)的演员和其他人员的传记信息(参见 参考资料)。为了进行说明,我使用 IMDB 内容的子集构建了一个 DB2 结构化数据库,将这些传记信息作为文本字段保存在数据库中。用 UIMA 进行文本分析UIMA 组件从源数据中的非结构化数据字段中提取出结构化的数据。不同的组件从源数据库中读取文档、分析文档来寻找提到的人名以及将结果保存到一个新数据库(Extracted Information Database,EIDB)中。文档是由 SQLReader 从源数据库中读取的,这个组件实现了 UIMA 的 CollectionReader 接口,是使用 SDK 开发的。当 UIMA 框架调用 SQLReader 的初始化方法时,它使用 JDBC™ 连接到数据库并发出一个 SQL SELECT 语句,这个语句在 SQLReader 存储的 ResultSet 对象中返回需要的数据,比如文本字符串。然后,这个框架使用 CollectionReader 接口的迭代器类方法(比如 getNext())实际地获取每个文档的文本和元数据。这些数据在一个 UIMA 定义的数据对象中返回给框架,这个对象称为 Common Analysis Structure(CAS)。实际上,因为正在分析文本文档,所以这个数据对象是文本 CAS(TCAS),但是为了简单,本文忽略这一区别,只讨论 CAS。当框架调用 getNext 时,它提供一个空的 CAS。SQLReader 用来自 ResultSet 中当前行的数据填充 CAS。所需代码的结构见 清单 1。它显示了如何将来自输入表的 TRIVIA 列的文档文本和一些元数据(比如文档的 URI)放进 CAS 中。SQLReader 还必须实现 hasNext() 方法(这里未显示)以便完成迭代器接口。清单 1. 在 SQLReader 的 getNext 方法中对 CAS 进行初始化。为了简单,省略了错误检查。Connection conn;ResultSet rs;
// Not shown: code to set up the Connection and to
// populate the ResultSet from the input database
public void getNext( CAS cas) {
// Not shown: code to check that the ResultSet contains more data
// Get the document text and put it into the CAS
String content = resultSet.getString( "TRIVIA"); //get document text
JCas jcas = cas.getJCas();
jcas.setDocumentText( content);// set document text
// Construct a URI for this document
String id = rs.getString( idColName);// get primary key
String url = conn.getMetaData().getURL();// database URL
String uri = url + "/" + tableName + "/" + idColName + "#" + id;
// set URI into a SourceDocumentInfo
SourceDocumentInfo docInfo = new SourceDocumentInfo( jcas);
docInfo.setURI( uri);// set uri feature value
docInfo.addToIndexes();
// Advance to next row in the ResultSet
nextRow();
}使用一个 xml 描述符文件让 UIMA 框架了解 SQLReader。每个 UIMA 组件都有这样的文件,可以使用 SDK 中的工具或手工创建这种文件。描述符指向组件的实现,在这种情况下是一个类文件,还包含组件需要的任何配置信息。对于 SQLReader,描述符包含源数据库的 URL 和登录所需的用户 id/密码等信息。在进行初始化时,使用 UIMA 提供的方法读取这些信息。描述符中另一个非常重要的信息是组件使用的类型系统的引用。CAS 将数据存储为有类型的结构,类型系统定义了类型以及类型之间的关系。图 2 显示 Preston 中使用的类型系统。类型系统是使用 SDK 工具定义的,这些工具还创建与类型系统中的类型对应的 java ™ 类。清单 1 中的 SourceDocumentInfo 就是这样的类。它的 URI 属性用于保存 SQLReader 创建的文档 URI。(在 UIMA 处理结束时,这个 URI 将从 CAS 复制到 EIDB 中。)图 2. Preston 使用的 UIMA 类型系统。内置的 UIMA 类型名显示为斜体。箭头指出继续关系。
当框架从 SQLReader 获得了 CAS 之后,将它传递给一个文本分析引擎(text analysis engine,TAE) 以便进行实际的分析。TAE 可以很复杂,由几个组件组成,包括其他 TAE。但是,在 Preston 中,TAE 只包含一个组件 NameReferenceAnnotator,这个组件实现了 UIMA 定义的 Annotator 接口。标注器是基本的文本分析组件。它的工作是使用提供给它的 CAS 中的信息(也就是文档文本),寻找一些新数据,然后将这些数据添加到 CAS 中。NameReferenceAnnotator 使用一个正则表达式寻找特定格式的人名,IMDB 文档中在提到人名时采用这种格式。(见 图 3。)人名放在单引号中,后面是 “(qv)”;很轻易用正则表达式寻找这种格式。人名中惟一的复杂情况是人名本身可能包含一个或多个撇号。这个图还说明了 IMDB 如何消除人名的二义性,比如这里的 John Barrymore,在数据库中可能有多个人都叫这个名字。这对于后面一个步骤是有意义的。图 3. 来自 IMDB 的文档示例,说明了源数据中人名使用的非凡格式。Son of actor 'John Barrymore (I)' (qv) and actress 'Dolores Costello' (qv).Annotator 接口中最重要的方法是 initialize 和 process。当框架调用 initialize 时,NameReferenceAnnotator 从描述符以字符串形式读取正则表达式并编译它。然后,当调用 process 时,它在从 CAS 收到的文档文本中寻找与正则表达式匹配的地方。每当找到匹配时,就将它作为图 2 所示的类型系统中的类型实例存储在 CAS 中。每个名字存储为一个 NameReference 对象,这个对象包含正则表达式找到的名字字符串,它的开头和结尾字符位置设置为 NameReference 从 Annotation 内置类型继续来 begin 和 end 整数特性。NameReference 还包含一个 DocumentEntity 引用。这个结构的功能是存储关于文档中提到的每个实体(人)的信息。假如多次提到一个实体,那么每次提到时都引用同一个文档实体。使 Preston 比较简单的一个因素是:在 IMDB 数据中,提到同一个人的所有地方都采用完全相同的形式。所以,很轻易识别适当的 DocumentEntity。假如必须对 Preston 进行扩展来处理其他类型的输入数据,那么必须能够处理同一名字的不同形式。例如,假如在 图 3 所示文档的较长版本中提到 “Mr Barrymore”,那么必须意识到这引用了与 “John Barrymore (I)” 一样的实体。进行这种连接所需的处理称为文档内共同引用(in-document co-reference)。在 Preston 中,不需要这种处理,因为 IMDB 数据非常一致。创建 Extracted Information Database为了在 NameReferenceAnnotator 从文档集合中发现的信息上进行文本挖掘,所有 CAS 中的提及信息和文档实体信息必须写入一个结构化数据库。这是在文档处理流程结束时进行的(参见 图 1)。在处理结束时接收每个 CAS 的组件称为 CAS 消费者,UIMA 为这个组件提供了 CasConsumer 接口。一个 UIMA 处理管道可以有多个 CAS 消费者,在从 Text Analysis Engine 退出时,这些 CAS 消费者依次接收每个 CAS。Preston 使用两个 CAS 消费者。一个称为 cas2jdbc,它将来自每个 CAS 的数据写到一个关系数据库(DB2)的表中;另一个称为 EidbManager,它忽略接收的 CAS,但是在每次运行开始时设置数据库,并在分析完所有文档之后对所有信息进行后期处理。图 4. Extracted Information Database(EIDB)的结构EIDB 使用的数据模型见 图 4。MENTIONS 表保存 NameReferenceAnnotator 探测到的对名字的各次提及, DOCENT 表保存文档实体。来自这些表的示例数据见 图 5。EIDB 中的其他表在后面讨论。尽管这个简单的模式对于我们现在的意图来说已经很好了,但是还可以让它更高效。例如,文档 URI 是长字符串,由一个不变的部分和一个与文档相关的部分组成。可以将不变的部分转移到一个单独的表中。在调用 EidbManager 的初始化方法时,它进行的数据库设置包括以 图 4 所示的模式创建四个表,所使用的 SQL 语句是从它的描述符文件中读取的。CAS 消费者 cas2jdbc 是 WebSphere® Information Integrator OmniFind Edition V8.3 的一部分,Preston 使用它填充 MENTIONS 和 DOCENT 表。它是一个通用组件,用于在 XML 配置文件的控制下将来自文本 CAS 的数据写入关系数据库表中。从 UIMA 类型系统到关系模式的映射由配置文件控制。Preston 中 cas2jdbc 的部分配置见 清单 2,这显示如何用 CAS 中的 NameReference 实例信息填充 MENTIONS 表的两列。关于如何构造映射文件的完整细节,请参考 cas2jdbc 的文档。如图 5 所示,EIDB 的 MENTIONS 和 DOCENT 表中的行是从文档 “He was married to 'Cicely Tyson' (qv) by 'Andrew Young (IV)' (qv) in the home of 'Bill Cosby' (qv). 'Bill Cosby' (qv) was the best man, and gave away the bride” 中产生的。注重,这里两次提到了 Bill Cosby,但是只有一个文档实体。为了简单,已经将键缩短了。图 5. MENTIONS 和 DOCENT 表中的行清单 2 中的代码段显示如何用 NameReference 标注的 name 特性填充 MENTIONS 表的 span 列,以及如何用 entity 特性填充 docent_id 列,这使用了 cas2jdbc 为 CAS 中的每个特性结构创建的惟一 ID。清单 2. Preston 中 CasConsumer cas2jdbc 的部分配置文件<explicitMappingRule applyToSubtypes="false"><type>com.ibm.fisc.preston.NameReference</type>
<table>MENTIONS</table>
<featureMappings>
<featureMapping>
<feature>name</feature>
<length>1024</length>
<column>SPAN</column>
</featureMapping>
<featureMapping>
<feature>
entity/com.ibm.fisc.preston.DocumentEntity:uniqueId()
</feature>
<column>DOCENT_ID</column>
</featureMapping>
</featureMappings>
</explicitMappingRule>在处理完最后一个文档之后,EIDB 中的 MENTIONS 和 DOCENT 表保存着找到的所有人名提及的信息。但是,给定的人名可能在多个文档中被提及。使用实例(instance) 这个术语表示在一个或多个文档中提到的一个实体。EIDB 中的 INSTANCES 表记录关于实例的信息,DE_INST 表维护从每个文档实体到对应的实例的链接。需要判定来自不同文档的哪些实体实际上是同一实例,这种处理称为跨文档共同引用(cross-document co-reference)。在 Preston 中,跨文档共同引用的处理是在框架调用 EidbManager CAS 消费者的 collectionProcessComplete 方法时执行的。在 Preston 中,这个任务相当简单,因为在 IMDB 中总是以完全相同的方式提到人名,所以很轻易判定不同文档中的哪些实体应该链接到同一实例。在其他生产应用程序中,跨文档共同引用可能非常复杂,实际上这个领域还有待研究。在 Preston 中,这种处理只需要两条 SQL 语句,它们在 INSTANCES 表中为 DOCENT 表中的每组独特人名创建一个条目,并在 DE_INST 表中创建对应的行。Extracted Information Database 已经完成了,可以用于数据挖掘了。为关联进行数据挖掘我们对 EIDB 中的数据进行数据挖掘,寻找高度相关的人。两个人之间有关联的证据是在同一个文档中提到了他们,也就是,他们被共同提及。还可以包含其他证据,这可以通过包含其他结构化数据(比如用数据库表记录哪些人为同一部电影工作过),或者通过进行更深入的文本分析。其他文本分析使我们能够根据文本中的语句寻找人们之间的其他关系。通过添加更多标注器来寻找这些关系,并在类型系统中添加更多可以存储在 CAS 中的类型,就能够创建包含 “实体-关系-实体” 三元组(也称为 “主体-谓词-对象” 三元组)的数据库表。为了便于以后提供这种功能,将 EIDB 中的共同提及数据转换为一个面向三元组的模式,实现的方法是在数据库上定义一个具有这种结构的视图。这个视图的模式称为 UIMA_RELATIONS,见 表 1。表 1. UIMA_RELATIONS 视图的模式。所有列的类型都是 VARCHAR。
列名
说明
subject_type
主体实体的类型,例如 NameReference。
subject_uri
主体实体的惟一标识符,采用 URI 形式。
predicate_type
谓词的类型,例如 Has_name。
object_type
对象的类型,比如 Document 或 String。
object_name
对象实体的 URI(假如它的类型是 Document),或者对象的字符串值(假如它的类型是 String)。
evidence_uri
应用程序用来获得这个关系的证据的 URI,例如文档的 URI。
这种模式称为垂直模式(vertical schema),它有两个主要优点。它非常灵活,因为通过在 predicate_type 列中使用不同的值,可以很轻松地插入新的关系。其次,它使关系和它们的语义变成显式的,而在标准的数据库模式中许多关系隐含在模式的设计中。垂直模式还更加接近于语义 Web 标准,比如 RDF。通过定义视图而不是显式的表,可以避免垂直模式的主要缺点,即许多查询要求它与本身进行联结,而这种操作是很昂贵的。将 UIMA_RELATIONS 视图创建为两个 SQL 选择语句的联合。一个选择语句为 “Mentioned_in” 谓词创建行,另一个为 “Has_name” 谓词创建行。第一个选择语句将人和文档联系起来。它从 EIDB 中的 INSTANCES 表中取出人实例,并通过与其他表进行联结,寻找提到这个人实例的文档。证据 URI 是文档 URI。第二个 SQL 选择语句为 “Has_name” 谓词创建行,它将人实例与他们的名字字符串联系起来。因为这个谓词所需的所有信息都在 INSTANCES 表中,因此构造一个证据 URI 指向这个表中的相关行。Preston 中的数据挖掘要寻找关联,它需要定义另一个视图 MINING_VIEW,这个视图的格式根据下面描述的 DB2 Intelligent Miner 工具的需求进行定义。它是通过对 UIMA_RELATIONS 视图进行自我联结建立的。挖掘视图只包含两列,见 表 2。第一个列是人可读的实体标识符,在这个例子中是人名。第二个列是出现此人的 “事务” 的惟一 ID。在这个例子中是提到此人的文档的 URI。表 2. MINING_VIEW 视图的模式。两个列的类型都是 VARCHAR。
列名
说明
name
一个描述实体的字符串,例如一个人实例的名字。
transaction_id
出现此实体的事务的惟一标识符,例如文档的 URI。
假如我们考虑到关联挖掘最初的动机 —— Market Basket Analysis,那么事务 ID 的重要性就很明显了。假如把购物篮(Market Basket,例如超级市场中的购物车)看作 “事务”,把它的标识符看作事务 ID,那么关联挖掘就可以用来寻找购物车中两个或多个商品之间的关联。在 Preston 中,文档相当于购物车,文档中提到的人相当于购物车中的商品。假如还有其他关系,尤其是采用 “人-关系-人” 形式的二元关系,那么关系实例相当于购物车,关系中的主体和对象是购物车中的商品,事务标识符是关系实例的标识符。关联挖掘的输出是一组采用以下形式的规则entity1, entity2 => entity 3这表示,在一个事务中假如同时存在 entity1 和 entity2,那么 entity3 可能以一定的概率存在。这个例子是一个长度为 3 的规则。在 Preston 中,我们寻找的规则只是将两个人联系起来,比如:personA => personB,这种规则的长度是 2。这个规则的强度表示 personA 和 personB 在同一个文档中一起出现的可能性。强度的几种度量由关联的挖掘算法进行计算。我们使用 DB2 Intelligent Miner 进行关联挖掘。安装了 DB2 之后,可以通过在 SQL 语句中调用存储过程来调用这个产品。清单 3 所示的调用使用了 Intelligent Miner 提供的一个 “简单挖掘过程”。在这个调用中,PRESTON 是创建的模型名,MINING_VIEW 是要挖掘的视图,下面两个数字参数为生成的规则的强度设置阈值,即最低支持度为 0.01%,最低可靠度是 1%。最后一个参数指定最大规则长度是 2。支持度 和可靠度 是关联规则强度的度量。支持度就是符合这一规则的事务的比例,可靠度度量包含 personA 的文档也提到 personB 的可能性。考虑共同提及的一种办法是定义一个网络或图,假如两个人在至少一个文档中被同时提到,那么在网络中就在他们之间建立链接。这个网络隐含在挖掘视图中。DB2 Intelligent Miner 的有用功能之一是能够在这个网络中寻找强连接的子图。这些子图中的人频繁地被同时提到。一个例子见 图 6,这是由 DB2 Intelligent Miner Visualization 绘制的。可以看到,通过对 IMDB 传记文档中的共同提及数据进行数据挖掘,找到了现实生活中一些闻名的关联。这里采用不同的颜色表示关联的强度,橙色比白色强,白色比蓝色强。这个子图指出了披头士乐队和与他们高度相关的人。清单 3. 这个 SQL 语句调用 “简单挖掘过程” 来进行关联挖掘。BuildRuleModel 是 DB2 Intelligent Miner 提供的一个用户定义函数。 CALL IDMMX.BuildRuleModel( 'PRESTON', 'MINING_VIEW',
'TRANSACTION_ID', 0.01, 1, 2)图 6. DB2 Intelligent Miner 在文本分析找到的共同提及关系网络中发现的强连接子图。
未来的方向本文描述了一个简单的应用程序 Preston,它使用 UIMA 中的文本分析在文档中寻找提到的人名,用找到的数据建立一个数据库,并调用针对关联的数据挖掘来在共同提及关系网络中寻找强连接子图。尽管这个应用程序非常简单,但是它说明了使用 UIMA 在非结构化数据和结构化数据之间建立联系的主要特性。对这个应用程序可能进行的一种扩展是,通过进行更复杂的文本分析,识别更多类型的实体以及实体之间的关系。来自不同来源的标注器或文本分析引擎可以轻松地插入 UIMA 框架。IBM 已经声明有几家业务合作伙伴正在开发与 UIMA 兼容的文本分析组件。与 UIMA 兼容的开放源码组件也可以从 University of Sheffield 的 GATE 项目获得(参见 参考资料)。另一个扩展是,不是将这个应用程序部署在 SDK 上的 UIMA 框架实现中,而是部署在支持的 IBM 产品上:WebSphere Information Integrator OmniFind Edition。OmniFind 支持 UIMA 并添加了其他支持,比如从许多不同类型的数据库中收集文档,以及集成文本分析和文本搜索来提供语义文本搜索。在这种情况下,一定要使用从 developerWorks 获得的兼容 OmniFind 的 SDK 版本。在 IBM Research 的推动下,UIMA 框架还在继续发展。尽管本文主要关注文本分析,但是 UIMA 还可以用于分析其他类型的非结构化信息,比如音频和图像。致谢作者希望感谢 IBM Hursley Laboratory 的 Graham Bent 将 DB2 Intelligent Miner 与文本分析组合起来,还要感谢 Internet Movie Database 答应使用其中的内容。