我正在使用Stanford CoreNLP解析器来运行一些文本,并且有日期短语,例如“10月的第二个星期一”和“过去的一年”。该库将适当地将每个标记标记为DATE命名实体,但是有没有办法以编程方式获取整个日期短语?并且不只是日期,组织命名实体也会这样做(例如,“国际奥林匹克委员会”可能是在给定文本示例中确定的一个)。
String content = "Thanksgiving, or Thanksgiving Day (Canadian French: Jour de"
+ " l'Action de grâce), occurring on the second Monday in October, is"
+ " an annual Canadian holiday which celebrates the harvest and other"
+ " blessings of the past year.";
Properties p = new Properties();
p.setProperty("annotators", "tokenize, ssplit, pos, lemma, ner, parse");
StanfordCoreNLP pipeline = new StanfordCoreNLP(p);
Annotation document = new Annotation(content);
pipeline.annotate(document);
for (CoreMap sentence : document.get(CoreAnnotations.SentencesAnnotation.class)) {
for (CoreLabel token : sentence.get(CoreAnnotations.TokensAnnotation.class)) {
String word = token.get(CoreAnnotations.TextAnnotation.class);
String ne = token.get(CoreAnnotations.NamedEntityTagAnnotation.class);
if (ne.equals("DATE")) {
System.out.println("DATE: " + word);
}
}
}
在斯坦福注释器和分类器加载之后,将产生输出:
DATE: Thanksgiving
DATE: Thanksgiving
DATE: the
DATE: second
DATE: Monday
DATE: in
DATE: October
DATE: the
DATE: past
DATE: year
我觉得图书馆必须识别这些短语并将它们用于命名实体标记,所以问题是数据是通过api以某种方式保存和提供的吗?
谢谢, 凯文
答案 0 :(得分:1)
在邮件列表上讨论后,我发现api不支持这个。我的解决方案是保持最后一个NE的状态,并在必要时构建一个字符串。来自nlp邮件列表的John B.有助于回答我的问题。
答案 1 :(得分:0)
非常感谢,我也会这样做。但是,斯坦福NER API支持classifyToCharOffset
(或类似的东西)来获取整个短语。我不知道,也许这只是你想法的实现:D。
答案 2 :(得分:0)
命名实体标记器和词性标记器是CoreNLP管道中的不同算法,似乎API使用者负责集成它们。
请原谅我的C#,但这是一个简单的课程:
public class NamedNounPhrase
{
public NamedNounPhrase()
{
Phrase = string.Empty;
Tags = new List<string>();
}
public string Phrase { get; set; }
public IList<string> Tags { get; set; }
}
和一些代码来查找所有顶级名词短语及其相关的命名实体标签:
private void _monkey()
{
...
var nounPhrases = new List<NamedNounPhrase>();
foreach (CoreMap sentence in sentences.toArray())
{
var tree =
(Tree)sentence.get(new TreeCoreAnnotations.TreeAnnotation().getClass());
if (null != tree)
_walk(tree, nounPhrases);
}
foreach (var nounPhrase in nounPhrases)
Console.WriteLine(
"{0} ({1})",
nounPhrase.Phrase,
string.Join(", ", nounPhrase.Tags)
);
}
private void _walk(Tree tree, IList<NamedNounPhrase> nounPhrases)
{
if ("NP" == tree.value())
{
var nounPhrase = new NamedNounPhrase();
foreach (Tree leaf in tree.getLeaves().toArray())
{
var label = (CoreLabel) leaf.label();
nounPhrase.Phrase += (string) label.get(new CoreAnnotations.TextAnnotation().getClass()) + " ";
nounPhrase.Tags.Add((string) label.get(new CoreAnnotations.NamedEntityTagAnnotation().getClass()));
}
nounPhrases.Add(nounPhrase);
}
else
{
foreach (var child in tree.children())
{
_walk(child, nounPhrases);
}
}
}
希望有所帮助!