Comment puis-je diviser un texte en phrases à L'aide de L'analyseur Stanford?
Comment diviser un texte ou un paragraphe en phrases en utilisant Stanford parser ?
y a-t-il une méthode pour extraire des phrases, comme getSentencesFromString()
comme il est prévu pour Ruby ?
12 réponses
vous pouvez vérifier la classe DocumentPreprocessor. Ci-dessous, un court extrait. Je pense qu'il y a peut-être d'autres façons de faire ce que vous voulez.
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);
}
je sais qu'il y a déjà une réponse acceptée...mais en général, vous prendriez les annotations envoyées par un doc annoté.
// 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);
}
}
Source - http://nlp.stanford.edu/software/corenlp.shtml (à mi-chemin)
et si vous ne cherchez que des phrases, vous pouvez laisser tomber les étapes suivantes comme" parse "et" dcoref " de l'initialisation du pipeline, cela vous fera gagner du temps et du temps de traitement. Rock and roll. ~K
il y a quelques problèmes avec la réponse acceptée. Tout d'abord, le tokenizer transforme certains caractères, comme le caractère " en deux caractères `. Deuxième, de rejoindre le sous texte avec de l'espace ne renvoie pas le même résultat qu'avant. Par conséquent, le texte d'exemple de la réponse acceptée transforme le texte d'entrée de manière non triviale.
cependant, la classe CoreLabel
que le tokenizer utilise garde trace des caractères source ils sont mappés, donc il est trivial de reconstruire la chaîne appropriée, si vous avez l'original.
L'approche 1 ci-dessous montre l'approche des réponses acceptées, L'approche 2 montre mon approche, qui surmonte ces problèmes.
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, " _ "));
Ce sorties:
My 1st sentence . _ `` Does it work for questions ? '' _ My third sentence .
My 1st sentence. _ “Does it work for questions?” _ My third sentence.
utilisant le paquet .net c# : Cela permettra de diviser les phrases, d'obtenir les parenthèses correctes et de préserver les espaces originaux et la ponctuation:
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));
}
}
Entrée: - Les personnages de cette phrase possèdent un certain charme, que l'on retrouve souvent dans la ponctuation et la prose. C'est un deuxième phrase? Il est en effet.
sortie: 3 phrases ("?'est considéré comme un délimiteur de fin de phrase)
Note: pour une phrase comme " la classe de Mme Havisham était impeccable (autant qu'on pouvait voir!) dans tous les aspects."Le tokenizer correctement discerner que la période à la fin de Mme n'est pas un EOS, cependant il vous incorrectement ! dans les parenthèses comme EOS et split "dans tous les aspects."en tant que deuxième phrase.
avec la API Simple fournie par Stanford CoreNLP version 3.6.0 ou 3.7.0.
voici un exemple avec 3.6.0. Il fonctionne exactement de la même façon avec 3.7.0.
Code Java Snippet
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);
}
}
Donne:
le paragraphe de texte.
une autre phrase.
encore une autre phrase.
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>
vous pouvez assez facilement utiliser Stanford tagger pour cela.
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
}
vous pouvez utiliser le document preprocesseur . Il est vraiment facile. Juste de lui donner un nom de fichier.
for (List<HasWord> sentence : new DocumentPreprocessor(pathto/filename.txt)) {
//sentence is a list of words in a sentence
}
une variante de la réponse de @Kevin qui résoudra la question Est la suivante:
for(CoreMap sentence: sentences) {
String sentenceText = sentence.get(TextAnnotation.class)
}
qui vous donne les informations sur les phrases sans vous soucier des autres annotateurs.
un autre élément, qui n'est pas abordé sauf dans quelques réponses rétrogrades, est la façon de définir les délimiteurs de phrase? La manière la plus courante, la valeur par défaut, est de faire dépendre les signes de ponctuation communs qui indiquent la fin d'une phrase. Il y a d'autres formats de documents auxquels on pourrait faire face en dessinant sur des corps rassemblés, dont l'un étant chaque ligne est sa propre phrase.
pour définir vos délimiteurs pour le Documentpreprocesseur comme dans les réponses acceptées, vous utiliseriez setSentenceDelimiter(String)
. Pour utiliser l'approche de pipeline suggérée comme dans la réponse de @Kevin, on travaillerait avec les propriétés ssplit. Par exemple, pour utiliser le schéma de fin de ligne proposé dans le paragraphe précédent, on placerait la propriété ssplit.eolonly
à true
ajouter chemin pour Fichier d'entrée et de sortie dans le code ci-dessous: -
import java.util.*;
import edu.stanford.nlp.pipeline.*;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
public class NLPExample
{
public static void main(String[] args) throws IOException
{
PrintWriter out;
out = new PrintWriter("C:\Users\ACER\Downloads\stanford-corenlp-full-
2018-02-27\output.txt");
Properties props=new Properties();
props.setProperty("annotators","tokenize, ssplit, pos,lemma");
StanfordCoreNLP pipeline = new StanfordCoreNLP(props);
Annotation annotation;
String readString = null;
PrintWriter pw = null;
BufferedReader br = null;
br = new BufferedReader (new
FileReader("C:\Users\ACER\Downloads\stanford-
corenlp-full-2018-02-27\input.txt" ) ) ;
pw = new PrintWriter ( new BufferedWriter ( new FileWriter (
"C:\Users\ACER\Downloads\stanford-corenlp-full-2018-02-
27\output.txt",false
))) ;
String x = null;
while (( readString = br.readLine ()) != null)
{
pw.println ( readString ) ; String
xx=readString;x=xx;//System.out.println("OKKKKK");
annotation = new Annotation(x);
pipeline.annotate(annotation); //System.out.println("LamoohAKA");
pipeline.prettyPrint(annotation, out);
}
br.close ( ) ;
pw.close ( ) ;
System.out.println("Done...");
}
}
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+");
}
}
utiliser l'expression régulière pour séparer le texte en phrases, en utilisation Regex mais en java Je ne sais pas.
code
string[] phrases = Regex.Split(texte, @"(?<=['""A-za-z] [\)] [\.\!\?]) \s+(?= [A-Z])");
90% des œuvres