如何在 OpenNLP 中创建一个好的 NER 训练模型?

Posted

技术标签:

【中文标题】如何在 OpenNLP 中创建一个好的 NER 训练模型?【英文标题】:How to create a good NER training model in OpenNLP? 【发布时间】:2015-11-07 19:14:04 【问题描述】:

我刚刚开始使用 OpenNLP。我需要创建一个简单的训练模型来识别名称实体。

在这里阅读文档https://opennlp.apache.org/docs/1.8.0/apidocs/opennlp-tools/opennlp/tools/namefind 我看到了这个简单的文本来训练模型:

<START:person> Pierre Vinken <END> , 61 years old , will join the board as a nonexecutive director Nov. 29 .
Mr . <START:person> Vinken <END> is chairman of Elsevier N.V. , the Dutch publishing group .
<START:person> Rudolph Agnew <END> , 55 years old and former chairman of Consolidated Gold Fields PLC ,
    was named a director of this British industrial conglomerate .

问题有两个:

为什么我必须将人名放在文本(短语)上下文中?为什么不在每一行写一个人的名字呢?喜欢:

<START:person> Robert <END>

<START:person> Maria <END>

<START:person> John <END>

如何向该名称添加额外信息? 例如,我想为每个名字保存男性/女性信息。

(我知道有些系统会尝试通过阅读最后一个字母来理解它,例如 Female 的“a”等,但我想自己添加)

谢谢。

【问题讨论】:

【参考方案1】:

您的第一个问题的答案是该算法适用于句子中的周围上下文(标记);它不仅仅是一个简单的查找机制。 OpenNLP 使用最大熵,这是一种多项逻辑回归的形式来构建其模型。这样做的原因是为了减少“词义歧义”,并在上下文中找到实体。例如,如果我的名字是四月,我很容易与四月混淆,如果我的名字是五月,那么我会与五月以及动词可能混淆。对于第一个问题的第二部分,您可以制作一个已知名称列表,并在程序中使用这些名称,该程序会查看您的句子并自动注释它们以帮助您创建训练集,但是制作名称列表单独没有上下文将无法充分或根本无法训练模型。事实上,有一个名为“modelbuilder addon”的 OpenNLP 插件就是为此而设计的:你给它一个名称文件,它使用名称和你的一些数据(句子)来训练模型。如果您正在寻找通常不含歧义的实体的特定名称,则最好使用列表和正则表达式之类的东西来发现名称而不是 NER。

关于你的第二个问题,有几个选项,但总的来说,我认为 NER 不是描述性别等事物的好工具,但是如果有足够的训练句子,你可能会得到不错的结果。由于 NER 使用基于句子训练集中周围标记的模型来确定命名实体的存在,因此它在识别性别方面做不了太多。您最好找到所有人名,然后参考您知道是男性或女性的姓名索引来进行匹配。此外,一些名字,比如 Pat,既有男性也有女性,在大多数文本数据中,没有任何迹象表明它既不是人类也不是机器。话虽如此,您可以分别创建男性和女性模型,也可以在同一模型中创建不同的实体类型。您可以使用这样的注释(使用不同的实体类型名称 male.person 和 female.person)。我从未尝试过,但它可能没问题,你必须在你的数据上进行测试。

<START:male.person> Pierre Vinken <END> , 61 years old , will join the board as a nonexecutive director Nov. 29 .
Mrs . <START:female.person> Maria <END> is chairman of Elsevier N.V. , the Dutch publishing group

NER= 命名实体识别

HTH

【讨论】:

谢谢!是的,我应该按照你的例子做 female.personmale.person,这里的问题是我有很多名字和姓氏(大约 200k)所以在这种情况下我应该一遍又一遍地用不同的名字写同样的句子?比如 Pierre Vinken , 61 岁 .. then John特拉沃尔塔 , 61 岁……等等等等? 我们需要这样吗? @Nuwanda 不,这实际上是不正确的。该模型基于您的注释句子,而分词器正是 opennlp 查看您的句子的方式。但是,NER 仅找到名称的一部分并不少见,即使您在带有空格的多部分名称上对其进行了训练...NLP 很难 :-) 好吧,我曾经组合了分块器的输出,所以如果你正在寻找人们的多部分名称,你可以检测一个名称,然后看看它是否在一个名词短语中,如果是的话,取整个名词短语,这可能会让你得到包括空格在内的整个名字......但即使这样我也必须对名词短语进行一些清理,并且分块器也可能是错误的,尤其是它没有经过类似训练的句子。否则,除了我刚才描述的不同启发式方法之外,你能做的就是更多的训练数据 @FredrikL 好问题,我实际上不确定实际名称在多大程度上影响了...。我必须对此进行测试。如果确实很重要,您也许可以用随机名称进行一些替换(美国人口普查是名字和姓氏的重要来源)

以上是关于如何在 OpenNLP 中创建一个好的 NER 训练模型?的主要内容,如果未能解决你的问题,请参考以下文章

如何在Haskell中创建函数minimax?

如何在 Visual C++ 中创建一个 dll? [关闭]

当值为文本时如何在 Power BI 中创建折线图(好的,不正确)?

如何在CAD中创建一个实体

text 在终端中创建一个好的密码

如何在 php 中创建安全的 mysql 准备语句?