我有一个数据集,在底层文本上有多层注释,例如 part-of-tags , chunks from a shallow parser , name entities , 和其他来自各种 natural language processing (自然语言处理)工具。对于像 The man went to the store
这样的句子,注释可能如下所示:
Word POS Chunk NER ==== === ===== ======== The DT NP Person man NN NP Person went VBD VP - to TO PP - the DT NP Location store NN NP Location
我想使用 Lucene 为一堆带有注释的文档编制索引,然后跨不同层执行搜索。一个简单查询的示例是检索所有将 Washington 标记为 person 的文档。虽然我并不完全遵守该表示法,但从句法上讲,最终用户可能会按如下方式输入查询:
查询:Word=Washington,NER=Person
我还想做更复杂的查询,涉及跨不同层的注释的顺序,例如找到所有文档,其中有一个标记为 person 的词,后面跟着 arrived at
后面跟着一个标记为 location 的词.这样的查询可能看起来像:
查询:"NER=Person Word=arrived Word=at NER=Location"
用 Lucene 解决这个问题的好方法是什么?是否有索引和搜索包含结构化标记的文档字段?
有效负载
一个建议是尝试使用 Lucene payloads .但是,我认为有效载荷只能用于调整文档的排名,而不是用于选择返回哪些文档。
后者很重要,因为对于某些用例,包含模式的文档数确实是我想要的。
此外,仅检查与查询匹配的术语的有效负载。这意味着有效负载甚至只能帮助第一个示例查询的排名,Word=Washington,NER=Person
,因此我们只想确保术语Washingonton
被标记为 Person
。然而,对于第二个示例查询,"NER=Person Word=arrived Word=at NER=Location"
,我需要检查未指定的标签,因此不匹配的术语。
最佳答案
也许实现您所要求的一种方法是在同一位置(即 Word、POS、Chunk、NER)为每个注释类编制索引,并在每个注释前加上一个唯一的字符串。不要为单词的前缀而烦恼。您将需要一个自定义分析器来保留前缀,但是您应该能够使用您想要的语法进行查询。
具体来说,我的建议是在指定位置索引以下标记:
Position Word POS Chunk NER
======== ==== === ===== ========
1 The POS=DT CHUNK=NP NER=Person
2 man POS=NN CHUNK=NP NER=Person
3 went POS=VBD CHUNK=VP -
4 to POS=TO CHUNK=PP -
5 the POS=DT CHUNK=NP NER=Location
6 store POS=NN CHUNK=NP NER=Location
要获取语义,请使用 SpanQuery或 SpanTermQuery以保留 token 序列。
我还没有尝试过,但是在同一位置索引不同类别的术语应该允许位置敏感的查询做正确的事情来评估表达式,例如
NER=Person arrived at NER=Location
请注意与您的示例的不同之处:我删除了 Word= 前缀以将其视为默认值。此外,您选择的前缀语法(例如,“class=”)可能会限制您正在索引的文档的内容。确保文档不包含短语,或者在预处理中以某种方式转义它们。当然,这与您需要使用的分析器有关。
更新:我使用这种技术来索引文本中的句子和段落边界(使用 break=sen
和 break=para
标记)所以我可以决定在哪里中断短语查询匹配。似乎工作正常。
关于java - 在 Lucene 中对词级注释层进行索引和搜索,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2883012/