coreNLP的使用

最近考虑做些英文词语词干化的工作,听说coreNLP这个工具不错,就拿来用了。

coreNLP是斯坦福大学开发的一套关于自然语言处理的工具(toolbox),使用简单功能强大,有;命名实体识别、词性标注、词语词干化、语句语法树的构造还有指代关系等功能,使用起来比较方便。

coreNLP是使用Java编写的,运行环境需要在JDK1.8,1.7貌似都不支持。这是需要注意的

 

coreNLP官方文档不多,但是给的几个示例文件也差不多能摸索出来怎么用,刚才摸索了一下,觉得还挺顺手的。

 

环境:

window7 64位

JDK1.8

 

需要引进的ar包:



说明:这里只是测试了英文的,所以使用的Stanford-corenlp-3.6.0.models.jar文件,如果使用中文的需要在官网上下对应中文的model jar包,然后引进项目即可。

 

直接看代码比较简单:

[java] view plain copy
  1. package com.luchi.corenlp;  
  2.   
  3. import java.util.List;  
  4. import java.util.Map;  
  5. import java.util.Properties;  
  6.   
  7. import edu.stanford.nlp.hcoref.CorefCoreAnnotations.CorefChainAnnotation;  
  8. import edu.stanford.nlp.hcoref.data.CorefChain;  
  9. import edu.stanford.nlp.ling.CoreAnnotations;  
  10. import edu.stanford.nlp.ling.CoreAnnotations.LemmaAnnotation;  
  11. import edu.stanford.nlp.ling.CoreAnnotations.NamedEntityTagAnnotation;  
  12. import edu.stanford.nlp.ling.CoreAnnotations.PartOfSpeechAnnotation;  
  13. import edu.stanford.nlp.ling.CoreAnnotations.SentencesAnnotation;  
  14. import edu.stanford.nlp.ling.CoreAnnotations.TextAnnotation;  
  15. import edu.stanford.nlp.ling.CoreAnnotations.TokensAnnotation;  
  16. import edu.stanford.nlp.ling.CoreLabel;  
  17. import edu.stanford.nlp.pipeline.Annotation;  
  18. import edu.stanford.nlp.pipeline.StanfordCoreNLP;  
  19. import edu.stanford.nlp.semgraph.SemanticGraph;  
  20. import edu.stanford.nlp.semgraph.SemanticGraphCoreAnnotations;  
  21. import edu.stanford.nlp.trees.Tree;  
  22. import edu.stanford.nlp.trees.TreeCoreAnnotations.TreeAnnotation;  
  23. import edu.stanford.nlp.util.CoreMap;  
  24.   
  25. public class TestNLP {  
  26.       
  27.     public void test(){  
  28.         //构造一个StanfordCoreNLP对象,配置NLP的功能,如lemma是词干化,ner是命名实体识别等  
  29.         Properties props = new Properties();  
  30.         props.setProperty("annotators""tokenize, ssplit, pos, lemma, ner, parse, dcoref");  
  31.         StanfordCoreNLP pipeline = new StanfordCoreNLP(props);  
  32.   
  33.         // 待处理字符串  
  34.         String text = "judy has been to china . she likes people there . and she went to Beijing ";// Add your text here!  
  35.   
  36.         // 创造一个空的Annotation对象  
  37.         Annotation document = new Annotation(text);  
  38.   
  39.         // 对文本进行分析  
  40.         pipeline.annotate(document);  
  41.           
  42.         //获取文本处理结果  
  43.         List<CoreMap> sentences = document.get(SentencesAnnotation.class);  
  44.         for(CoreMap sentence: sentences) {  
  45.               // traversing the words in the current sentence  
  46.               // a CoreLabel is a CoreMap with additional token-specific methods  
  47.               for (CoreLabel token: sentence.get(TokensAnnotation.class)) {  
  48.                 // 获取句子的token(可以是作为分词后的词语)  
  49.                 String word = token.get(TextAnnotation.class);  
  50.                 System.out.println(word);  
  51.                 //词性标注  
  52.                 String pos = token.get(PartOfSpeechAnnotation.class);  
  53.                 System.out.println(pos);  
  54.                 // 命名实体识别  
  55.                 String ne = token.get(NamedEntityTagAnnotation.class);  
  56.                 System.out.println(ne);  
  57.                 //词干化处理  
  58.                 String lema=token.get(LemmaAnnotation.class);  
  59.                 System.out.println(lema);  
  60.               }  
  61.   
  62.               // 句子的解析树  
  63.               Tree tree = sentence.get(TreeAnnotation.class);  
  64.               tree.pennPrint();  
  65.   
  66.              // 句子的依赖图  
  67.               SemanticGraph graph = sentence.get(SemanticGraphCoreAnnotations.CollapsedCCProcessedDependenciesAnnotation.class);  
  68.               System.out.println(graph.toString(SemanticGraph.OutputFormat.LIST));  
  69.                 
  70.                 
  71.             }  
  72.   
  73.             // 指代词链  
  74.             //每条链保存指代的集合  
  75.             // 句子和偏移量都从1开始  
  76.             Map<Integer, CorefChain> corefChains =  document.get(CorefChainAnnotation.class);  
  77.             if (corefChains == null) { return; }  
  78.               for (Map.Entry<Integer,CorefChain> entry: corefChains.entrySet()) {  
  79.                 System.out.println("Chain " + entry.getKey() + " ");  
  80.                 for (CorefChain.CorefMention m : entry.getValue().getMentionsInTextualOrder()) {  
  81.                   // We need to subtract one since the indices count from 1 but the Lists start from 0  
  82.                   List<CoreLabel> tokens = sentences.get(m.sentNum - 1).get(CoreAnnotations.TokensAnnotation.class);  
  83.                   // We subtract two for end: one for 0-based indexing, and one because we want last token of mention not one following.  
  84.                   System. out.println("  " + m + ", i.e., 0-based character offsets [" + tokens.get(m.startIndex - 1).beginPosition() +  
  85.                           ", " + tokens.get(m.endIndex - 2).endPosition() + ")");  
  86.                 }  
  87.               }  
  88.     }  
  89.     public static void main(String[]args){  
  90.         TestNLP nlp=new TestNLP();  
  91.         nlp.test();  
  92.     }  
  93.   
  94. }  

 具体的注释都给出来了,我们可以直接看结果就知道代码的作用了:

对于每个token的识别结果:





  

原句中的:

        judy 识别结果为:词性为NN,也就是名词,命名实体对象识别结果为O,词干识别为Judy

        注意到has识别的词干已经被识别出来了,是“have”

        而Beijing的命名实体标注识别结果为“Location”,也就意味着识别出了地名

 

然后我们看 解析树的识别(以第一句为例):



 

最后我们看一下指代的识别:



每个chain包含的是指代相同内容的词语,如chain1中两个she虽然在句子的不同位置,但是都指代的是第一句的“Judy”,这和原文的意思一致,表示识别正确,offsets表示的是该词语在句子中的位置

 

 当然我只是用到了coreNLP的词干化功能,所以只需要把上面代码一改就可以处理词干化了,测试代码如下:

[java] view plain copy
  1. package com.luchi.corenlp;  
  2.   
  3. import java.util.List;  
  4. import java.util.Properties;  
  5.   
  6. import edu.stanford.nlp.ling.CoreLabel;  
  7. import edu.stanford.nlp.ling.CoreAnnotations.LemmaAnnotation;  
  8. import edu.stanford.nlp.ling.CoreAnnotations.SentencesAnnotation;  
  9. import edu.stanford.nlp.ling.CoreAnnotations.TokensAnnotation;  
  10. import edu.stanford.nlp.pipeline.Annotation;  
  11. import edu.stanford.nlp.pipeline.StanfordCoreNLP;  
  12.   
  13. import edu.stanford.nlp.util.CoreMap;  
  14.   
  15. public class Lemma {  
  16.   
  17.     // 词干化  
  18.     public String stemmed(String inputStr) {  
  19.         Properties props = new Properties();  
  20.         props.setProperty("annotators""tokenize, ssplit, pos, lemma, ner, parse, dcoref");  
  21.         StanfordCoreNLP pipeline = new StanfordCoreNLP(props);  
  22.   
  23.         Annotation document = new Annotation(inputStr);  
  24.         pipeline.annotate(document);  
  25.         List<CoreMap> sentences = document.get(SentencesAnnotation.class);  
  26.   
  27.         String outputStr = "";  
  28.         for (CoreMap sentence : sentences) {  
  29.             // traversing the words in the current sentence  
  30.             // a CoreLabel is a CoreMap with additional token-specific methods  
  31.             for (CoreLabel token : sentence.get(TokensAnnotation.class)) {  
  32.                 String lema = token.get(LemmaAnnotation.class);  
  33.                 outputStr += lema+" ";  
  34.             }  
  35.   
  36.         }  
  37.         return outputStr;  
  38.     }  
  39.     public static void main(String[]args){  
  40.           
  41.         Lemma lemma=new Lemma();  
  42.         String input="jack had been to china there months ago. he likes china very much,and he is falling love with this country";  
  43.         String output=lemma.stemmed(input);  
  44.         System.out.print("原句    :");  
  45.         System.out.println(input);  
  46.         System.out.print("词干化:");  
  47.         System.out.println(output);  
  48.                   
  49.           
  50.     }  
  51.   
  52. }  

 输出结果为:

 

 结果还是很准确的

展开阅读全文

没有更多推荐了,返回首页