我修改了包含的 StanfordCoreNLPDemo.java 文件的代码,以满足我们的情感需求:
进口:
import java.io.*;
import java.util.*;
import edu.stanford.nlp.io.*;
import edu.stanford.nlp.ling.*;
import edu.stanford.nlp.neural.rnn.RNNCoreAnnotations;
import edu.stanford.nlp.neural.rnn.RNNCoreAnnotations.PredictedClass;
import edu.stanford.nlp.pipeline.*;
import edu.stanford.nlp.semgraph.SemanticGraph;
import edu.stanford.nlp.semgraph.SemanticGraphCoreAnnotations;
import edu.stanford.nlp.sentiment.SentimentCoreAnnotations;
import edu.stanford.nlp.trees.*;
import edu.stanford.nlp.util.*;
初始化管道。属性包括引理和情感:
public class StanfordCoreNlpDemo {
public static void main(String[] args) throws IOException {
PrintWriter out;
if (args.length > 1) {
out = new PrintWriter(args[1]);
} else {
out = new PrintWriter(System.out);
}
PrintWriter xmlOut = null;
if (args.length > 2) {
xmlOut = new PrintWriter(args[2]);
}
Properties props = new Properties();
props.put("annotators", "tokenize, ssplit, pos, lemma, parse, sentiment");
props.setProperty("tokenize.options","normalizeCurrency=false");
StanfordCoreNLP pipeline = new StanfordCoreNLP(props);
添加文本。这 3 句话取自您链接的网站的现场演示。我还打印了顶级注释的键,以查看您可以从中访问什么:
Annotation annotation;
if (args.length > 0) {
annotation = new Annotation(IOUtils.slurpFileNoExceptions(args[0]));
} else {
annotation = new Annotation("This movie doesn't care about cleverness, wit or any other kind of intelligent humor.Those who find ugly meanings in beautiful things are corrupt without being charming.There are slow and repetitive parts, but it has just enough spice to keep it interesting.");
}
pipeline.annotate(annotation);
pipeline.prettyPrint(annotation, out);
if (xmlOut != null) {
pipeline.xmlPrint(annotation, xmlOut);
}
// An Annotation is a Map and you can get and use the various analyses individually.
// For instance, this gets the parse tree of the first sentence in the text.
out.println();
// The toString() method on an Annotation just prints the text of the Annotation
// But you can see what is in it with other methods like toShorterString()
out.println("The top level annotation's keys: ");
out.println(annotation.keySet());
对于第一句话,我打印了它的键和情绪。然后,我遍历它的所有节点。对于每一个,我打印那个子树的叶子,这将是这个节点所指的句子的一部分,节点的名称,它的情绪,它的节点向量(我不知道那是什么)和它的预测。
情绪是一个整数,取值范围为 0 到 4。0 表示非常消极,1 表示消极,2 表示中立,3 表示积极,4 表示非常积极。预测是一个包含 4 个值的向量,每个值都包含该节点属于上述每个类别的可能性的百分比。第一个值是非常负面的类,等等。最高百分比是节点的情绪。
并非注释树的所有节点都有情绪。似乎句子的每个单词在树中都有两个节点。您可能希望单词是叶子,但它们只有一个子节点,这是一个带有标签的节点,其键中缺少预测注释。节点的名称是同一个词。
这就是为什么我在调用获取它的函数之前检查预测注释的原因。然而,正确的做法是忽略抛出的空指针异常,但我选择详细说明,以使此答案的读者明白没有缺少有关情绪的信息。
List<CoreMap> sentences = annotation.get(CoreAnnotations.SentencesAnnotation.class);
if (sentences != null && sentences.size() > 0) {
ArrayCoreMap sentence = (ArrayCoreMap) sentences.get(0);
out.println("Sentence's keys: ");
out.println(sentence.keySet());
Tree tree2 = sentence.get(SentimentCoreAnnotations.AnnotatedTree.class);
out.println("Sentiment class name:");
out.println(sentence.get(SentimentCoreAnnotations.ClassName.class));
Iterator<Tree> it = tree2.iterator();
while(it.hasNext()){
Tree t = it.next();
out.println(t.yield());
out.println("nodestring:");
out.println(t.nodeString());
if(((CoreLabel) t.label()).containsKey(PredictedClass.class)){
out.println("Predicted Class: "+RNNCoreAnnotations.getPredictedClass(t));
}
out.println(RNNCoreAnnotations.getNodeVector(t));
out.println(RNNCoreAnnotations.getPredictions(t));
}
最后,还有一些输出。打印依赖项。这里的依赖也可以被解析树(tree or tree2)的访问者访问:
out.println("The first sentence is:");
Tree tree = sentence.get(TreeCoreAnnotations.TreeAnnotation.class);
out.println();
out.println("The first sentence tokens are:");
for (CoreMap token : sentence.get(CoreAnnotations.TokensAnnotation.class)) {
ArrayCoreMap aToken = (ArrayCoreMap) token;
out.println(aToken.keySet());
out.println(token.get(CoreAnnotations.LemmaAnnotation.class));
}
out.println("The first sentence parse tree is:");
tree.pennPrint(out);
tree2.pennPrint(out);
out.println("The first sentence basic dependencies are:");
out.println(sentence.get(SemanticGraphCoreAnnotations.BasicDependenciesAnnotation.class).toString(SemanticGraph.OutputFormat.LIST));
out.println("The first sentence collapsed, CC-processed dependencies are:");
SemanticGraph graph = sentence.get(SemanticGraphCoreAnnotations.CollapsedCCProcessedDependenciesAnnotation.class);
out.println(graph.toString(SemanticGraph.OutputFormat.LIST));
}
}
}