使用自定义数据的NLTK命名实体识别

50

我正在尝试使用NLTK从我的文本中提取命名实体。 我发现NLTK NER对我的目的来说不太准确,我还想添加一些自己的标签。 我一直在试图找到一种训练自己的NER的方法,但似乎找不到正确的资源。

  1. 我可以使用自己的数据来训练NLTK中的命名实体识别器吗?
  2. 如果可以使用自己的数据进行训练,那么named_entity.py文件是需要修改的文件吗?
  3. 输入文件格式是否必须为IOB,例如Eric NNP B-PERSON?
  4. 除了nltk cookbook和nlp with python之外,是否有其他资源可用?

我真的很感激您的帮助。

6个回答

24

您是否坚定使用NLTK/Python?我遇到了与您相同的问题,并且在使用斯坦福命名实体识别器时获得了更好的结果:http://nlp.stanford.edu/software/CRF-NER.shtml。在FAQ中,使用您自己的数据训练分类器的流程非常有文档记录。

如果您确实需要使用NLTK,我建议向邮件列表中的其他用户寻求帮助:http://groups.google.com/group/nltk-users

希望这可以帮到您!


1
浏览SNER网站时,我发现这里甚至有一个Python接口(在此处https://github.com/dat/pyner)。我不确定它的成熟度如何,但它可能会很有帮助。 - senderle
6
我有同样的问题,我分享了对我有用的方法。抱歉如果这让你生气了,兄弟 :( - jjdubs
7
斯坦福命名实体识别器已经被包含在NLTK 2.0中。阅读更多信息 - http://www.nltk.org/api/nltk.tag.html#module-nltk.tag.stanford - Jayesh
3
大家好,我写了一个脚本,可以下载并准备所有必需的内容,以使Python、NLTK和Stanford NER一起工作 -- https://gist.github.com/troyane/c9355a3103ea08679baf - tro
有人知道如何使用Python-Stanford NER接口来训练新的语料库吗? - user3314418
@blueblank 如果你的目的是用于生产环境,其实使用NLTK是没有多大意义的。Stanford CoreNLP作为一个工具包,采用传统的机器学习方法,已经更好了,更不用说现在生产环境中已经广泛使用了深度学习的技术。 - xji

14

您可以轻松地将Stanford NER与nltk一同使用。Python脚本如下:

from nltk.tag.stanford import NERTagger
import os
java_path = "/Java/jdk1.8.0_45/bin/java.exe"
os.environ['JAVAHOME'] = java_path
st = NERTagger('../ner-model.ser.gz','../stanford-ner.jar')
tagging = st.tag(text.split())   

要训练自己的数据并创建模型,您可以参考斯坦福NER FAQ中的第一个问题。

链接为http://nlp.stanford.edu/software/crf-faq.shtml


FAQ答案使用Java,有没有办法用Python实现? - Kitwradr
我不知道是否可以使用Python来训练模型。但是我们可以通过Python调用Java模块。 - Rohan Amrute
预测ner zip的唯一方法是将输入转换为TSV吗?有没有Java命令可以直接给出文本? - Kitwradr

1

nltk.chunk.named_entity 模块中有一些函数可以训练 NER 标记器。然而,它们专门为 ACE 语料库编写,且未完全清理,因此需要以其为参考编写自己的训练程序。

此外,还有两个相对较新的指南(1 2)详细介绍了使用 NLTK 训练 GMB 语料库的过程。

然而,正如上面的答案所提到的,现在有很多工具可用,如果需要简化的训练流程,就不需要再使用 NLTK。CoreNLP 和 spaCy 等工具包做得更好。由于使用 NLTK 与从头编写自己的训练代码没有太大区别,因此这样做并没有太多价值。NLTK 和 OpenNLP 可以被认为是在 NLP 最近的进展爆炸之前属于过去时代的一部分。


1
我也遇到了这个问题,但是我设法解决了。你可以使用自己的训练数据。我在我的github存储库中记录了主要的要求/步骤。
我使用了NLTK-trainer,所以基本上你需要以正确的格式获取训练数据(标记NNP B标签),然后运行训练脚本。请查看我的存储库以获取更多信息。

0

0
除了nltk cookbook和nlp with python之外,我还可以使用哪些资源?
您可以考虑使用spaCy来训练自己的自定义数据进行命名实体识别任务。这里有一个例子thread,可以在自定义训练集上训练模型以检测新实体ANIMAL。代码已经修复并更新以便更容易阅读。
import random
import spacy
from spacy.training import Example

LABEL = 'ANIMAL'
TRAIN_DATA = [
    ("Horses are too tall and they pretend to care about your feelings", {'entities': [(0, 6, LABEL)]}),
    ("Do they bite?", {'entities': []}),
    ("horses are too tall and they pretend to care about your feelings", {'entities': [(0, 6, LABEL)]}),
    ("horses pretend to care about your feelings", {'entities': [(0, 6, LABEL)]}),
    ("they pretend to care about your feelings, those horses", {'entities': [(48, 54, LABEL)]}),
    ("horses?", {'entities': [(0, 6, LABEL)]})
]
nlp = spacy.load('en_core_web_sm')  # load existing spaCy model
ner = nlp.get_pipe('ner')
ner.add_label(LABEL)

optimizer = nlp.create_optimizer()

# get names of other pipes to disable them during training
other_pipes = [pipe for pipe in nlp.pipe_names if pipe != "ner"]
with nlp.disable_pipes(*other_pipes):  # only train NER
    for itn in range(20):
        random.shuffle(TRAIN_DATA)
        losses = {}
        for text, annotations in TRAIN_DATA:
            doc = nlp.make_doc(text)
            example = Example.from_dict(doc, annotations)
            nlp.update([example], drop=0.35, sgd=optimizer, losses=losses)
        print(losses)

# test the trained model
test_text = 'Do you like horses?'
doc = nlp(test_text)
print("Entities in '%s'" % test_text)
for ent in doc.ents:
    print(ent.label_, " -- ", ent.text)

以下是输出结果:

{'ner': 9.60289144264557}
{'ner': 8.875474230820478}
{'ner': 6.370401408220459}
{'ner': 6.687456469517201}
... 
{'ner': 1.3796682589133492e-05}
{'ner': 1.7709562613218738e-05}

Entities in 'Do you like horses?'
ANIMAL  --  horses

请问您使用的是哪个版本的Spacy?在我的情况下,add_label方法会抛出一个错误。 - Daniel

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接