我使用斯坦福核心 NLP 构建了一个 java 解析器。我发现在使用 CORENLP 对象获得一致结果方面存在问题。我正在为相同的输入文本获取不同的实体类型。对我来说,这在 CoreNLP 中似乎是一个错误。想知道是否有任何 StanfordNLP 用户遇到过这个问题并找到了解决方法。这是我正在实例化和重用的服务类。
class StanfordNLPService {
//private static final Logger logger = LogConfiguration.getInstance().getLogger(StanfordNLPServer.class.getName());
private StanfordCoreNLP nerPipeline;
/*
Initialize the nlp instances for ner and sentiments.
*/
public void init() {
Properties nerAnnotators = new Properties();
nerAnnotators.put("annotators", "tokenize,ssplit,pos,lemma,ner");
nerPipeline = new StanfordCoreNLP(nerAnnotators);
}
/**
* @param text Text from entities to be extracted.
*/
public void printEntities(String text) {
// boolean tracking = PerformanceMonitor.start("StanfordNLPServer.getEntities");
try {
// Properties nerAnnotators = new Properties();
// nerAnnotators.put("annotators", "tokenize,ssplit,pos,lemma,ner");
// nerPipeline = new StanfordCoreNLP(nerAnnotators);
Annotation document = nerPipeline.process(text);
// a CoreMap is essentially a Map that uses class objects as keys and has values with custom types
List<CoreMap> sentences = document.get(CoreAnnotations.SentencesAnnotation.class);
for (CoreMap sentence : sentences) {
for (CoreLabel token : sentence.get(CoreAnnotations.TokensAnnotation.class)) {
// Get the entity type and offset information needed.
String currEntityType = token.get(CoreAnnotations.NamedEntityTagAnnotation.class); // Ner type
int currStart = token.get(CoreAnnotations.CharacterOffsetBeginAnnotation.class); // token offset_start
int currEnd = token.get(CoreAnnotations.CharacterOffsetEndAnnotation.class); // token offset_end.
String currPos = token.get(CoreAnnotations.PartOfSpeechAnnotation.class); // POS type
System.out.println("(Type:value:offset)\t" + currEntityType + ":\t"+ text.substring(currStart,currEnd)+"\t" + currStart);
}
}
}catch(Exception e){
e.printStackTrace();
}
}
}
Discrepancy result: type changed from MISC to O from the initial use.
Iteration 1:
(Type:value:offset) MISC: Appropriate 100
(Type:value:offset) MISC: Time 112
Iteration 2:
(Type:value:offset) O: Appropriate 100
(Type:value:offset) O: Time 112
最佳答案
我已经查看了一些代码,这是解决此问题的可能方法:
你可以做些什么来解决这个问题是加载 3 个序列化的 CRF 中的每一个,并将 useKnownLCWords 设置为 false,然后再次序列化它们。然后将新的序列化 CRF 提供给您的 StanfordCoreNLP。
这是一个加载序列化 CRF 并将 useKnownLCWords 设置为 false 的命令,然后再次转储它:
java -mx600m -cp "*:."edu.stanford.nlp.ie.crf.CRFClassifier -loadClassifier 分类器/english.all.3class.distim.crf.ser.gz -useKnownLCWords false -serializeTo 分类器/new.english.all.3class.distim.crf.ser.gz
显然,输入您想要的任何名称!此命令假设您位于 stanford-corenlp-full-2015-04-20/并且有一个带有序列化 CRF 的目录分类器。根据您的设置进行适当更改。
此命令应加载序列化的 CRF,将 useKnownLCWords 设置为 false 进行覆盖,然后将 CRF 重新转储到 new.english.all.3class.dissim.crf.ser.gz
然后在您的原始代码中:
nerAnnotators.put("ner.model","comma-separated-list-of-paths-to-new-serialized-crfs");
请让我知道这是否有效或无效,我可以更深入地研究这个!
关于java - 斯坦福核心 NLP : Entity type non deterministic,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/31679761/