如何使用斯坦福分析器将文本分成几个句子?
如何使用斯坦福分析器将文本或段落分解成句子?
有什么方法可以提取句子,如为Ruby提供的getSentencesFromString()
?
您可以检查DocumentPreprocessor类。 下面是一个简短的片段。 我想可能有其他的方法来做你想做的事情。
String paragraph = "My 1st sentence. “Does it work for questions?” My third sentence."; Reader reader = new StringReader(paragraph); DocumentPreprocessor dp = new DocumentPreprocessor(reader); List<String> sentenceList = new ArrayList<String>(); for (List<HasWord> sentence : dp) { // SentenceUtils not Sentence String sentenceString = SentenceUtils.listToString(sentence); sentenceList.add(sentenceString); } for (String sentence : sentenceList) { System.out.println(sentence); }
我知道已经有一个被接受的答案了……但是通常你只需从注释的文档中获取SentenceAnnotations即可。
// creates a StanfordCoreNLP object, with POS tagging, lemmatization, NER, parsing, and coreference resolution Properties props = new Properties(); props.put("annotators", "tokenize, ssplit, pos, lemma, ner, parse, dcoref"); StanfordCoreNLP pipeline = new StanfordCoreNLP(props); // read some text in the text variable String text = ... // Add your text here! // create an empty Annotation just with the given text Annotation document = new Annotation(text); // run all Annotators on this text pipeline.annotate(document); // these are all the sentences in this document // a CoreMap is essentially a Map that uses class objects as keys and has values with custom types List<CoreMap> sentences = document.get(SentencesAnnotation.class); for(CoreMap sentence: sentences) { // traversing the words in the current sentence // a CoreLabel is a CoreMap with additional token-specific methods for (CoreLabel token: sentence.get(TokensAnnotation.class)) { // this is the text of the token String word = token.get(TextAnnotation.class); // this is the POS tag of the token String pos = token.get(PartOfSpeechAnnotation.class); // this is the NER label of the token String ne = token.get(NamedEntityTagAnnotation.class); } }
来源 – http://nlp.stanford.edu/software/corenlp.shtml (中途下降)
如果你只是在寻找句子,你可以从pipe道初始化中删除后面的步骤,比如“parse”和“dcoref”,它会为你节省一些负载和处理时间。 摇滚乐。 〜ķ
接受的答案有几个问题。 首先,标记器将一些字符,如字符“转换成两个字符”。 其次,将标记文本与空格连接在一起不会返回与以前相同的结果。 因此,来自接受答案的示例文本以不平凡的方式转换input文本。
但是,标记器使用的CoreLabel
类会跟踪它们映射到的源字符,因此,如果您有原始string,则重build正确的string也很简单。
下面的方法1显示了接受的答案方法,方法2显示了我的方法,它克服了这些问题。
String paragraph = "My 1st sentence. “Does it work for questions?” My third sentence."; List<String> sentenceList; /* ** APPROACH 1 (BAD!) ** */ Reader reader = new StringReader(paragraph); DocumentPreprocessor dp = new DocumentPreprocessor(reader); sentenceList = new ArrayList<String>(); for (List<HasWord> sentence : dp) { sentenceList.add(Sentence.listToString(sentence)); } System.out.println(StringUtils.join(sentenceList, " _ ")); /* ** APPROACH 2 ** */ //// Tokenize List<CoreLabel> tokens = new ArrayList<CoreLabel>(); PTBTokenizer<CoreLabel> tokenizer = new PTBTokenizer<CoreLabel>(new StringReader(paragraph), new CoreLabelTokenFactory(), ""); while (tokenizer.hasNext()) { tokens.add(tokenizer.next()); } //// Split sentences from tokens List<List<CoreLabel>> sentences = new WordToSentenceProcessor<CoreLabel>().process(tokens); //// Join back together int end; int start = 0; sentenceList = new ArrayList<String>(); for (List<CoreLabel> sentence: sentences) { end = sentence.get(sentence.size()-1).endPosition(); sentenceList.add(paragraph.substring(start, end).trim()); start = end; } System.out.println(StringUtils.join(sentenceList, " _ "));
这输出:
My 1st sentence . _ `` Does it work for questions ? '' _ My third sentence . My 1st sentence. _ “Does it work for questions?” _ My third sentence.
使用.net C#包:这将拆分句子,得到正确的括号并保留原始空格和标点符号:
public class NlpDemo { public static readonly TokenizerFactory TokenizerFactory = PTBTokenizer.factory(new CoreLabelTokenFactory(), "normalizeParentheses=false,normalizeOtherBrackets=false,invertible=true"); public void ParseFile(string fileName) { using (var stream = File.OpenRead(fileName)) { SplitSentences(stream); } } public void SplitSentences(Stream stream) { var preProcessor = new DocumentPreprocessor(new UTF8Reader(new InputStreamWrapper(stream))); preProcessor.setTokenizerFactory(TokenizerFactory); foreach (java.util.List sentence in preProcessor) { ProcessSentence(sentence); } } // print the sentence with original spaces and punctuation. public void ProcessSentence(java.util.List sentence) { System.Console.WriteLine(edu.stanford.nlp.util.StringUtils.joinWithOriginalWhiteSpace(sentence)); } }
input: – 这句话的人物具有一定的魅力,常常出现在标点和散文中。 这是第二句话? 真的是。
输出: 3个句子('?'被认为是句尾分隔符)
注意:对于像“郝薇香太太class”这样的句子来说,在所有方面都是无可挑剔的(就我们所能看到的而言)。“ 标记器将正确地辨别夫人年底的时间不是一个EOS,但它会错误地标记! 在括号内作为EOS分裂“各方面”。 作为第二句话。
你可以很容易地使用斯坦福标记为此。
String text = new String("Your text...."); //Your own text. List<List<HasWord>> tokenizedSentences = MaxentTagger.tokenizeText(new StringReader(text)); for(List<CoreLabel> act : tokenizedSentences) //Travel trough sentences { System.out.println(edu.stanford.nlp.ling.Sentence.listToString(act)); //This is your sentence }
使用斯坦福CoreNLP版本3.6.0或3.7.0( http://stanfordnlp.github.io/CoreNLP/#about )提供的Simple AIP,
这里有一个3.6.0的例子。 它和3.7.0完全一样。
Java代码片段
import java.util.List; import edu.stanford.nlp.simple.Document; import edu.stanford.nlp.simple.Sentence; public class TestSplitSentences { public static void main(String[] args) { Document doc = new Document("The text paragraph. Another sentence. Yet another sentence."); List<Sentence> sentences = doc.sentences(); sentences.stream().forEach(System.out::println); } }
产量:
文中的段落。
另一句话。
又一句话。
的pom.xml
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>stanfordcorenlp</groupId> <artifactId>stanfordcorenlp</artifactId> <version>1.0-SNAPSHOT</version> <properties> <maven.compiler.source>1.8</maven.compiler.source> <maven.compiler.target>1.8</maven.compiler.target> </properties> <dependencies> <!-- https://mvnrepository.com/artifact/edu.stanford.nlp/stanford-corenlp --> <dependency> <groupId>edu.stanford.nlp</groupId> <artifactId>stanford-corenlp</artifactId> <version>3.6.0</version> </dependency> <!-- https://mvnrepository.com/artifact/com.google.protobuf/protobuf-java --> <dependency> <groupId>com.google.protobuf</groupId> <artifactId>protobuf-java</artifactId> <version>2.6.1</version> </dependency> </dependencies> </project>
您可以使用文档预处理器 。 这很容易。 只要给它一个文件名。
for (List<HasWord> sentence : new DocumentPreprocessor(pathto/filename.txt)) { //sentence is a list of words in a sentence }
@Kevin答案将解决这个问题的变化如下:
for(CoreMap sentence: sentences) { String sentenceText = sentence.get(TextAnnotation.class) }
这可以让你获得句子信息,而不会受到其他注释者的困扰。
另一个因素,除了一些低估的答案,没有解决,是如何设置句子分隔符? 默认的最常见的方式是依靠标明句子结尾的常用标点符号。 还有其他的文档格式,可能会在绘制收集的语料库时面对,其中每一行都是它自己的语句。
要按照接受的答案设置DocumentPreprocessor的分隔符,可以使用setSentenceDelimiter(String)
。 要使用@Kevin的答案中提出的stream水线方法,可以使用ssplit属性。 例如,要使用上一段中提出的行尾scheme,可以将属性ssplit.eolonly
设置为true
public class k { public static void main(String a[]){ String str = "This program splits a string based on space"; String[] words = str.split(" "); for(String s:words){ System.out.println(s); } str = "This program splits a string based on space"; words = str.split("\\s+"); } }
使用正则expression式分割文本到句子,在使用正则expression式,但在Java我不知道。
码
string [] sentences = Regex.Split(text,@“(?<= ['”“a-za-z] [\]] [\。\!\?])\ s +(?= [AZ])” );
90%的作品