积极的? 颓丧的? 中性的? 使用斯坦福 CoreNLP 组件以及几行代码便可对句子进行分析。
本文先容何如使用集成到斯坦福 CoreNLP(一个用于当然说话科罚的开源库)中的热诚用具在 Java 中达成此类任务。
斯坦福 CoreNLP 热诚分类器要践诺热诚分析,您需要一个热诚分类器,这是一种不错确认从磨炼数据联接学习的展望来识别热诚信息的用具。
在斯坦福 CoreNLP 中,热诚分类器开导在递归神经辘集 (RNN) 深度学习模子之上,该模子在斯坦福热诚树库 (SST) 上进行磨炼。
SST 数据集是一个带有热诚标签的语料库,从数千个使用的句子中推导出每个句法上可能的短语,从而允许拿获文本中热诚的组成浪漫。浮浅来说,这允许模子确认单词何如组成短语的含义来识别心理,而不单是是通过孤当场评估单词。
为了更好地了解 SST 数据集的结构,您可从斯坦福 CoreNLP 热诚分析页面下载数据集文献。
在 Java 代码中,Stanford CoreNLP 热诚分类器使用如下。
领先,您通过添加践诺热诚分析所需的详确器(举例标记化、拆分、融会和热诚)来构建文本科罚管道。 就斯坦福 CoreNLP 而言,详确器是一个对详确对象进行操作的接口,其中后者示意文档中的一段文本。 举例,需要使用 ssplit 详确器将标记序列拆分为句子。
斯坦福 CoreNLP 以每个句子为基础计较心理。 因此,将文分内割成句子的进程恒久罢黜诳骗热诚详确器。
一朝文本被分红句子,融会详确器就会践诺句法依赖融会,为每个句子生成一个依赖示意。 然后,热诚详确器科罚这些依赖示意,将它们与底层模子进行比拟,以构建带有每个句子的热诚标签(详确)的二值化树。
浮浅来说,树的节点由输入句子的标记笃定,并包含详确,指点从句子导出的悉数短语的从越过颓丧到越过积极的五个热诚类别中的展望类别。 基于这些展望,热诚详确器计较通盘句子的热诚。
缔造斯坦福 CoreNLP在动手使用斯坦福 CoreNLP 之前,您需要进行以下缔造:
要运行斯坦福 CoreNLP,您需要 Java 1.8 或更高版块。
下载 Stanford CoreNLP 包并将该包解压缩到您机器上的土产货文献夹中。
下载地址:
https://nlp.stanford.edu/software/stanford-corenlp-latest.zip
本文以将上述代码解压到如下目次为例:
c:/softwareInstall/corenlp/stanford-corenlp-4.3.2
完成上述设施后,您就不错创建运行斯坦福 CoreNLP 管道来科罚文本的 Java 圭表了。
领先新建一个maven花式,并手动将stanford-corenlp-4.3.2添加到Libraries中:

在以下示例中,您将达成一个浮浅的 Java 圭表,该圭表运行斯坦福 CoreNLP 管道,以对包含多个句子的文本进行热诚分析。
领先,达成一个NlpPipeline类,该类提供动手化管道的步调和使用此管道将提交的文本拆分为句子然后对每个句子的热诚进行分类的步调。 底下是NlpPipeline类代码:
package com.zh.ch.corenlp; import edu.stanford.nlp.ling.CoreAnnotations; import edu.stanford.nlp.neural.rnn.RNNCoreAnnotations; import edu.stanford.nlp.pipeline.Annotation; import edu.stanford.nlp.pipeline.StanfordCoreNLP; import edu.stanford.nlp.sentiment.SentimentCoreAnnotations; import edu.stanford.nlp.trees.Tree; import edu.stanford.nlp.util.CoreMap; import java.util.Properties; public class NlpPipeline { StanfordCoreNLP pipeline = null; public void init() { Properties props = new Properties(); props.setProperty("annotators", "tokenize, ssplit, parse, sentiment"); pipeline = new StanfordCoreNLP(props); } public void estimatingSentiment(String text) { int sentimentInt; String sentimentName; Annotation annotation = pipeline.process(text); for(CoreMap sentence : annotation.get(CoreAnnotations.SentencesAnnotation.class)) { Tree tree = sentence.get(SentimentCoreAnnotations.SentimentAnnotatedTree.class); sentimentInt = RNNCoreAnnotations.getPredictedClass(tree); sentimentName = sentence.get(SentimentCoreAnnotations.SentimentClass.class); System.out.println(sentimentName + "\t" + sentimentInt + "\t" + sentence); } } }
init() 步更正手化StanfordCoreNLP 管道,它还动手化使用该热诚用具所需的分词器、依赖融会器和句子拆分器。 要动手化管道,请将带有相应详确器列表的 Properties 对象传递给 StanfordCoreNLP() 构造函数。 这将创建一个定制的管道,准备好对文本践诺热诚分析。
在NlpPipeline类的estimatingSentiment()步调中,调用之前创建的管道对象的process()步调,传入文本进行科罚。 process() 步调复返一个详确对象,该对象存储对提交的文本的分析。
接下来,迭代详确对象,在每次迭代中取得一个句子级 CoreMap 对象。关于这些对象中的每一个,获取一个包含用于笃定底层句子心理的心理详确的 Tree 对象。
将 Tree 对象传递给 RNNCoreAnnotations 类的 getPredictedClass() 步调,以索要对应句子的展望心理的编号代码。然后,获取展望心理的称呼并打印浪漫。
要测试上述功能,请使用调用 init() 步调的 main() 步调达成一个类,然后调用 nlpPipeline 类的 estimatingSentiment() 步调,将示例文本传递给后者。
在以下达成中,为了浮浅起见,平直指定text文本。示例句子旨在涵盖斯坦福 CoreNLP 可用的通盘心理评分边界:越过积极、积极、中立、颓丧和越过颓丧。
package com.zh.ch.corenlp; import java.io.FileReader; import java.io.IOException; public class Main { static NlpPipeline nlpPipeline = null; public static void processText(String text) { nlpPipeline.estimatingSentiment(text); } public static void main(String[] args) { String text = "This is an excellent book. I enjoy reading it. I can read on Sundays. Today is only Tuesday. Can't wait for next Sunday. The working week is unbearably long. It's awful."; nlpPipeline = new NlpPipeline(); nlpPipeline.init(); processText(text); } }
践诺浪漫:

分析在线客户驳斥
正如您从前边的示例中了解到的,Stanford CoreNLP 不错复返句子的心理。 接洽词,有好多用例需要分析多段文本的心理,每段文本可能包含不啻一个句子。 举例,您可能想要分析来自电子商务网站的推文或客户驳斥的心理。
要使用斯坦福 CoreNLP 计较多句文本样本的心理,您可能会使用几种不同的本事。
在科罚推文时,您可能会分析推文中每个句子的心理,若是有一些正面或负面的句子,您不错永别对通盘推文进行名次,忽略带有中性心理的句子。 若是推文中的悉数(或果然悉数)句子都是中性的,则该推文不错被列为中性。
接洽词,无意您致使不消分析每个句子来料想通盘文本的心理。 举例,在分析客户驳斥时,您不错依赖他们的标题,标题频频由一个句子组成。
要完成以下示例,您需要一组客户驳斥。 您不错使用本文随附的 NlpBookReviews.csv 文献中的驳斥。 该文献包含在 Amazon Review Export 的匡助下从 Amazon 网页下载的一组实质驳斥,这是一个 Google Chrome 浏览器彭胀圭表,允许您将居品驳斥偏激标题和评级下载到逗号分隔值 (CSV) 文献中 . (您不错使用该用具探索一组不同的驳斥以进行分析。)
将下述代码添加到NlpPipeline中
public String findSentiment(String text) { int sentimentInt = 2; String sentimentName = "NULL"; if (text != null && text.length() > 0) { Annotation annotation = pipeline.process(text); CoreMap sentence = annotation .get(CoreAnnotations.SentencesAnnotation.class).get(0); Tree tree = sentence .get(SentimentCoreAnnotations.SentimentAnnotatedTree.class); sentimentInt = RNNCoreAnnotations.getPredictedClass(tree); sentimentName = sentence.get(SentimentCoreAnnotations.SentimentClass.class); } return sentimentName; }
您可能会羁系到,上头的代码访佛于上一节中界说的 estimatingSentiment() 步调中的代码。 唯独的涌现区别是此次您莫得迭代输入文本中的句子。 相背,您只会得到第一句话,因为在大多量情况下,驳斥的标题由一个句子组成。
下述代码将从 CSV 文献中读取驳斥并将它们传递给新创建的 findSentiment() 进行科罚,如下所示:
public static void processCsvComment(String csvCommentFilePath) { try (CSVReader reader = new CSVReaderBuilder(new FileReader(csvCommentFilePath)).withSkipLines(1).build()) { String[] row; while ((row = reader.readNext()) != null) { System.out.println("Review: " + row[1] + "\t" + " Amazon rating: " + row[4] + "\t" + " Sentiment: " + nlpPipeline.findSentiment(row[1])); } } catch (IOException | CsvValidationException e) { e.printStackTrace(); } }
践诺浪漫:

齐备代码:
NlpPipeline.java
package com.zh.ch.corenlp; import edu.stanford.nlp.ling.CoreAnnotations; import edu.stanford.nlp.neural.rnn.RNNCoreAnnotations; import edu.stanford.nlp.pipeline.Annotation; import edu.stanford.nlp.pipeline.StanfordCoreNLP; import edu.stanford.nlp.sentiment.SentimentCoreAnnotations; import edu.stanford.nlp.trees.Tree; import edu.stanford.nlp.util.CoreMap; import java.util.Properties; public class NlpPipeline { StanfordCoreNLP pipeline = null; public void init() { Properties props = new Properties(); props.setProperty("annotators", "tokenize, ssplit, parse, sentiment"); pipeline = new StanfordCoreNLP(props); } public void estimatingSentiment(String text) { int sentimentInt; String sentimentName; Annotation annotation = pipeline.process(text); for(CoreMap sentence : annotation.get(CoreAnnotations.SentencesAnnotation.class)) { Tree tree = sentence.get(SentimentCoreAnnotations.SentimentAnnotatedTree.class); sentimentInt = RNNCoreAnnotations.getPredictedClass(tree); sentimentName = sentence.get(SentimentCoreAnnotations.SentimentClass.class); System.out.println(sentimentName + "\t" + sentimentInt + "\t" + sentence); } } public String findSentiment(String text) { int sentimentInt = 2; String sentimentName = "NULL"; if (text != null && text.length() > 0) { Annotation annotation = pipeline.process(text); CoreMap sentence = annotation .get(CoreAnnotations.SentencesAnnotation.class).get(0); Tree tree = sentence .get(SentimentCoreAnnotations.SentimentAnnotatedTree.class); sentimentInt = RNNCoreAnnotations.getPredictedClass(tree); sentimentName = sentence.get(SentimentCoreAnnotations.SentimentClass.class); } return sentimentName; } }
Main.java
package com.zh.ch.corenlp; import com.opencsv.CSVReader; import com.opencsv.CSVReaderBuilder; import com.opencsv.exceptions.CsvValidationException; import java.io.FileReader; import java.io.IOException; public class Main { static NlpPipeline nlpPipeline = null; public static void processCsvComment(String csvCommentFilePath) { try (CSVReader reader = new CSVReaderBuilder(new FileReader(csvCommentFilePath)).withSkipLines(1).build()) { String[] row; while ((row = reader.readNext()) != null) { System.out.println("Review: " + row[1] + "\t" + " Amazon rating: " + row[4] + "\t" + " Sentiment: " + nlpPipeline.findSentiment(row[1])); } } catch (IOException | CsvValidationException e) { e.printStackTrace(); } } public static void processText(String text) { nlpPipeline.estimatingSentiment(text); } public static void main(String[] args) { String text = "This is an excellent book. I enjoy reading it. I can read on Sundays. Today is only Tuesday. Can't wait for next Sunday. The working week is unbearably long. It's awful."; nlpPipeline = new NlpPipeline(); nlpPipeline.init(); // processText(text); processCsvComment("src/main/resources/NlpBookReviews.csv"); } }