我想创建一个自定义的NER模型。这就是我所做的:
培训数据(stanford-ner.tsv):
Hello O
! O
My O
name O
is O
Damiano PERSON
. O
物业(stanford-ner.prop):
trainFile = stanford-ner.tsv
serializeTo = ner-model.ser.gz
map = word=0,answer=1
maxLeft=1
useClassFeature=true
useWord=true
useNGrams=true
noMidNGrams=true
maxNGramLeng=6
usePrev=true
useNext=true
useDisjunctive=true
useSequences=true
usePrevSequences=true
useTypeSeqs=true
useTypeSeqs2=true
useTypeySequences=true
wordShape=chris2useLC
useGazettes=true
gazette=gazzetta.txt
cleanGazette=true
GAZZETTE gazzetta.txt):
PERSON John
PERSON Andrea
我通过命令行构建模型:
java -classpath "stanford-ner.jar:lib/*" edu.stanford.nlp.ie.crf.CRFClassifier -prop stanford-ner.prop
并测试:
java -classpath "stanford-ner.jar:lib/*" edu.stanford.nlp.ie.crf.CRFClassifier -loadClassifier ner-model.ser.gz -textFile test.txt
我用以下文本做了两次测试:
>>> TEST 1<<<
TEXT: 你好!我的名字是Damiano,这是一个值得测试的假文本。
OUTPUT 您好/ O!/ O. 我/ O名/ O是/ O Damiano / PERSON和/ O这/ O是/ O a / O假/ O文/ O到/ O测试/ O ./O
>>>测试2<<<
TEXT: 你好!我的名字是约翰,这是一个值得测试的假文本。
OUTPUT 您好/ O!/ O. 我/ O名称/ O是/ O John / O和/ O这个/ O是/ O a / O假/ O文本/ O到/ O测试/ O ./O
正如您所见,只有“Damiano”实体被发现。这个实体在我的训练数据中,但“John”(第二次测试)在gazzette内。所以问题是。
为什么John实体不被识别?
提前非常感谢你。
答案 0 :(得分:3)
正如Stanford FAQ所说,
顺便说一句,以“单元测试”的方式测试机器学习管道并不是一个好习惯,即只有一两个例子,因为它应该可以处理更大量的数据,更重要的是,它本质上是概率性的。如果使用公报,这并不能保证单词中的单词 公报总是被用作预期类的成员,它确实如此 不保证不会选择公报之外的词语。它 只是为CRF提供另一个功能来训练。如果 CRF对其他功能具有更高的权重,可能是公报特征 不知所措。
如果您想要将文本识别为类成员的内容 当且仅当它在单词列表中时,您可能更喜欢 Stanford CoreNLP中包含的regexner或tokensregex工具。该 CRF NER不保证接受公报中的所有单词作为一部分 预期的类,它也可能接受外面的单词 公报作为课程的一部分。
如果您想检查您的公报文件是否实际使用,最好采用现有示例(请参阅上面链接的austen.gaz.prop
和austen.gaz.txt
示例的页面底部)并替换多个你自己的名字,然后检查。如果失败,首先尝试更改您的测试,例如添加更多名称,重新制作文本等。
答案 1 :(得分:1)
gazzette只会帮助从训练数据中提取额外的功能,如果您在训练数据中没有出现这些单词或任何与标记的标记的连接,您的模型将无法从中受益。我建议的其中一个实验是将Damiano
添加到你的gazzette中。
答案 2 :(得分:0)
为什么John实体不被识别?
在我看来,你最小的例子应该最有可能添加" Damiano"作为PERSON类别的地名录。目前,训练数据允许模型学习" Damiano"是一个PERSON标签,但我认为这与地名词典类别无关(即两边都有PERSON是不够的)。