当前位置:   article > 正文

将Stanford CoreNLP的解析结果构造为json格式_stanfordcorenlp将句法分析结果以json储存

stanfordcorenlp将句法分析结果以json储存

首次处理英文语料,需要进行一些基础的NLP处理,首选工具当然是Stanford CoreNLP。由于Stanford CoreNLP官方示例的解析结果不宜直接使用,所以我在它的基础上进行修改,最终将解析结果转为json格式,并依照哈工大ltp的解析结果的格式,将依存句法的解析结果也添加到json中。

1、Stanford CoreNLP的安装

最新版的Stanford CoreNLP仅支持jdk1.8,这比较奇葩,因为目前多数机器的jdk还只是1.6或1.7,最以我下载了支持jdk1.6的最后一个版本,地址:http://nlp.stanford.edu/software/stanford-corenlp-full-2014-08-27.zip 。下载完成后,将解压后的所有内容放到(Eclipse)项目的根目录下,通过Build Path将所有的jar包添加到项目库中,即可完成安装配置。解压后的目录中有一个名为StanfordCoreNlpDemo.java的示例文件,简洁地展示了如何使用此工具,但是它使用的结果显示方式是prettyPrint,这种结果只便于人来看,而不便于机器来获取。所以我以 http://www.cnblogs.com/tec-vegetables/p/4153144.html所示的例子来基础来改写代码。
2、代码,有详细解释
  1. import java.util.ArrayList;
  2. import java.util.HashMap;
  3. import java.util.List;
  4. import java.util.Map;
  5. import java.util.Properties;
  6. import java.util.regex.Matcher;
  7. import java.util.regex.Pattern;
  8. import net.sf.json.JSONArray;
  9. import edu.stanford.nlp.dcoref.CorefChain;
  10. import edu.stanford.nlp.ling.CoreAnnotations.CharacterOffsetBeginAnnotation;
  11. import edu.stanford.nlp.ling.CoreAnnotations.CharacterOffsetEndAnnotation;
  12. import edu.stanford.nlp.ling.CoreAnnotations.LemmaAnnotation;
  13. import edu.stanford.nlp.ling.CoreAnnotations.NamedEntityTagAnnotation;
  14. import edu.stanford.nlp.ling.CoreAnnotations.PartOfSpeechAnnotation;
  15. import edu.stanford.nlp.ling.CoreAnnotations.SentencesAnnotation;
  16. import edu.stanford.nlp.ling.CoreAnnotations.TextAnnotation;
  17. import edu.stanford.nlp.ling.CoreAnnotations.TokensAnnotation;
  18. import edu.stanford.nlp.ling.CoreLabel;
  19. import edu.stanford.nlp.pipeline.Annotation;
  20. import edu.stanford.nlp.pipeline.StanfordCoreNLP;
  21. import edu.stanford.nlp.semgraph.SemanticGraph;
  22. import edu.stanford.nlp.semgraph.SemanticGraphCoreAnnotations.CollapsedCCProcessedDependenciesAnnotation;
  23. import edu.stanford.nlp.trees.Tree;
  24. import edu.stanford.nlp.trees.TreeCoreAnnotations.TreeAnnotation;
  25. import edu.stanford.nlp.util.CoreMap;
  26. public class TestCoreNLP
  27. {
  28. //参数text为需要处理的句子
  29. public static void run(String text)
  30. {
  31. //创建一个corenlp对象,设置需要完成的任务。
  32. //tokenize: 分词;ssplit:分句;pos:词性标注;lemma:获取词原型;parse:句法解析(含依存句法);dcoref:同义指代
  33. Properties props = new Properties();
  34. props.put("annotators", "tokenize, ssplit, pos, lemma, ner, parse, dcoref");
  35. StanfordCoreNLP pipeline = new StanfordCoreNLP(props);
  36. // 创建一个基于参数句子的标注对象
  37. Annotation document = new Annotation(text);
  38. // 将上述标注对象将对corenlp进行处理
  39. pipeline.annotate(document);
  40. // 获取处理结果
  41. List<CoreMap> sentences = document.get(SentencesAnnotation.class);
  42. //遍历所有句子,输出每一句的处理结果
  43. for(CoreMap sentence: sentences)
  44. {
  45. //遍历句子中每一个词,获取其解析结果并构造json数据
  46. JSONArray jsonSent = new JSONArray(); //创建一个json数组,用于保存当前句子的最终所有解析结果
  47. int id=1;//当前词在句子中的id,从1开始,因为原始的解析结果就是从1开始的。
  48. //先获取当前句子的依存句法分析结果
  49. SemanticGraph dependencies = sentence.get(CollapsedCCProcessedDependenciesAnnotation.class);
  50. //遍历每一个词
  51. for (CoreLabel token: sentence.get(TokensAnnotation.class))
  52. {
  53. //获取每个词的分析结果
  54. Map mapWord = new HashMap();//创建一个map对象,用于保存当前词的解析结果
  55. mapWord.put("id", id);// 添加id值
  56. mapWord.put("cont", token.get(TextAnnotation.class));//添加词内容
  57. mapWord.put("pos", token.get(PartOfSpeechAnnotation.class));//添加词性标注值
  58. mapWord.put("ner", token.get(NamedEntityTagAnnotation.class));//添加实体识别值
  59. mapWord.put("lemma", token.get(LemmaAnnotation.class));//添加词原型
  60. mapWord.put("charBegin",token.get(CharacterOffsetBeginAnnotation.class));//添加词在句子中的起始位置
  61. mapWord.put("charEnd",token.get(CharacterOffsetEndAnnotation.class));//添加词在句子中的结束位置
  62. //查找每个词对应的依存关系。由于原始的解析结果中,依存关系是单独地集中在另一个字符串变量中的,形如: 依存关系名(被依赖词-被依赖词id,依赖词-依赖词id)\n 依存关系名(被依赖词-被依赖词id,依赖词-依赖词id)\n......需要对其进行解析,这里采用的方法是依据\n进行分割,然后再用正则表达式进行匹配,来逐一获取每一个词的依赖词和依存关系名
  63. int flag=0;//设置标志位,用于保存当前词的依存关系是否已经处理过,0未处理,1已处理
  64. String[] dArray= (dependencies.toString(SemanticGraph.OutputFormat.LIST)).split("\n");//根据\n进行分割,结果保存为字符串数组
  65. for (int i=0;i<dArray.length;i++) //遍历字符串数组
  66. {
  67. if(flag==1) //检查当前词的依存关系是否已经处理过,如果已处理,则直接退出遍历过程
  68. break;
  69. ArrayList dc=getDependencyContnet(dArray[i]);//获取数组中第i项,并从中获取依存关系名,被依赖词id和依赖词id,放到一个ArrayList中
  70. if( Integer.parseInt(String.valueOf(dc.get(2)))==id) //如果当前词id等于当前依存关系中的依赖词id,则说明找到对应的关系结构
  71. {
  72. mapWord.put("relation",dc.get(0));//添加依存关系名
  73. mapWord.put("parent",dc.get(1));//添加被依赖词id
  74. flag=1; // 将当前词依存关系标志设为1
  75. break;//退出遍历
  76. }
  77. }
  78. jsonSent.add( mapWord );//将上述结果全部添加到当前句中
  79. id++;//词id自增
  80. }
  81. System.out.println(jsonSent);
  82. // // 获取并打印句法解析树
  83. // Tree tree = sentence.get(TreeAnnotation.class);
  84. // System.out.println("\n"+tree.toString());
  85. // // 获取并打印依存句法的结果
  86. // System.out.println("\nDependency Graph:\n " +dependencies.toString(SemanticGraph.OutputFormat.LIST));
  87. // // 获取并打印实体指代结果
  88. // Map<Integer, CorefChain> graph = document.get(CorefChainAnnotation.class);
  89. // System.out.println(graph);
  90. }
  91. }
  92. //解析依存关系值的方法。如,从root(abc-1, efg-3)中获取一个ArrayList,值为[root,1,3]
  93. public static ArrayList getDependencyContnet(String sent)
  94. {
  95. String str=sent;
  96. ArrayList result=new ArrayList();
  97. String patternName="(.*)\\(";
  98. String patternGid="\\(.*-([0-9]*)\\,";
  99. String patternDid=".*-([0-9]*)\\)";
  100. Pattern r = Pattern.compile(patternName);
  101. Matcher m = r.matcher(str);
  102. if(m.find())
  103. {
  104. result.add(m.group(1));
  105. }
  106. r=Pattern.compile(patternGid);
  107. m = r.matcher(str);
  108. if(m.find())
  109. {
  110. result.add(m.group(1));
  111. }
  112. r=Pattern.compile(patternDid);
  113. m = r.matcher(str);
  114. if(m.find())
  115. {
  116. result.add(m.group(1));
  117. }
  118. return (result);
  119. }
  120. }

以“Beijing is the capital of China.”为例,结果为:
[{"id":1,"lemma":"Beijing","relation":"nsubj","parent":"4","ner":"LOCATION","charEnd":7,"cont":"Beijing","charBegin":0,"pos":"NNP"},{"id":2,"lemma":"be","relation":"cop","parent":"4","ner":"O","charEnd":10,"cont":"is","charBegin":8,"pos":"VBZ"},{"id":3,"lemma":"the","relation":"det","parent":"4","ner":"O","charEnd":14,"cont":"the","charBegin":11,"pos":"DT"},{"id":4,"lemma":"capital","relation":"root","parent":"0","ner":"O","charEnd":22,"cont":"capital","charBegin":15,"pos":"NN"},{"id":5,"lemma":"of","ner":"O","charEnd":25,"cont":"of","charBegin":23,"pos":"IN"},{"id":6,"lemma":"China","relation":"prep_of","parent":"4","ner":"LOCATION","charEnd":31,"cont":"China","charBegin":26,"pos":"NNP"},{"id":7,"lemma":".","ner":"O","charEnd":32,"cont":".","charBegin":31,"pos":"."}]


声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/笔触狂放9/article/detail/342407
推荐阅读
相关标签
  

闽ICP备14008679号