tipos signos párrafos puntuacion parrafos introduccion ejercicios ejemplos desarrollo cortos clasificacion java parsing artificial-intelligence nlp stanford-nlp

java - signos - ¿Cómo puedo dividir un texto en oraciones usando el analizador de Stanford?



tipos de parrafos y ejemplos (11)

Con la API simple proporcionada por Stanford CoreNLP versión 3.6.0 o 3.7.0.

Aquí hay un ejemplo con 3.6.0. Funciona exactamente igual con 3.7.0.

Fragmento de código de 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); } }

Rendimientos:

El párrafo de texto.

Otra oración

Sin embargo, otra oración.

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>

¿Cómo puedo dividir un texto o párrafo en oraciones usando el analizador de Stanford ?

¿Hay algún método que pueda extraer oraciones, como getSentencesFromString() como se proporciona para Ruby ?


Hay un par de problemas con la respuesta aceptada. Primero, el tokenizer transforma algunos caracteres, como el carácter "en los dos caracteres` `. Segundo, unir el texto tokenizado junto con el espacio en blanco no devuelve el mismo resultado que antes. Por lo tanto, el texto de ejemplo de la respuesta aceptada transforma el texto de entrada de formas no triviales.

Sin embargo, la clase CoreLabel que utiliza el tokenizer realiza un seguimiento de los caracteres fuente a los que están asignados, por lo que es trivial reconstruir la cadena adecuada, si tiene el original.

El Enfoque 1 a continuación muestra el enfoque de respuestas aceptadas, el Enfoque 2 muestra mi enfoque, que supera estos problemas.

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, " _ "));

Esto produce:

My 1st sentence . _ `` Does it work for questions ? '''' _ My third sentence . My 1st sentence. _ “Does it work for questions?” _ My third sentence.


Otro elemento, no abordado excepto en algunas respuestas downvoted, es cómo establecer los delimitadores de oraciones? La forma más común, la predeterminada, es depender de los signos de puntuación comunes que indican el final de una oración. Hay otros formatos de documento que uno podría enfrentar al dibujar en corpus recopilados, uno de los cuales siendo cada línea es su propia oración.

Para establecer sus delimitadores para DocumentPreprocessor como en las respuestas aceptadas, debería usar setSentenceDelimiter(String) . Para usar el enfoque de canalización sugerido como en la respuesta de @Kevin, uno trabajaría con las propiedades de ssplit. Por ejemplo, para usar el esquema de fin de línea propuesto en el párrafo anterior, uno establecería la propiedad ssplit.eolonly en true


Puede usar Bastante fácil el etiquetador de Stanford para esto.

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 }


Puede usar el preprocesador de documentos . Es realmente fácil. Solo dale un nombre de archivo.

for (List<HasWord> sentence : new DocumentPreprocessor(pathto/filename.txt)) { //sentence is a list of words in a sentence }


Puede verificar la clase DocumentPreprocessor. A continuación hay un pequeño fragmento. Creo que puede haber otras formas de hacer lo que quieras.

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); }


Sé que ya hay una respuesta aceptada ... pero normalmente solo tomarías las SentenceAnnotations de un documento anotado.

// 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); } }

Fuente - http://nlp.stanford.edu/software/corenlp.shtml (a mitad de camino)

Y si solo busca oraciones, puede soltar los pasos posteriores como "analizar" y "dcoref" desde la inicialización de la interconexión, esto le ahorrará algo de carga y tiempo de procesamiento. Rock and roll. ~ K


Una variación en la respuesta @Kevin que resolverá la pregunta es la siguiente:

for(CoreMap sentence: sentences) { String sentenceText = sentence.get(TextAnnotation.class) }

que le proporciona la información de la oración sin molestarse con las otras anotaciones.


Usa expresiones regulares para dividir texto en oraciones, en uso Regex pero en java no lo sé.

código

string [] sentences = Regex.Split (text, @ "(? <= [''" "a-za-z] [/)] [/. /! /?]) / s + (? = [AZ])" );

90% funciona


Uso del paquete .net C #: Esto dividirá las oraciones, corregirá los paréntesis y conservará los espacios y la puntuación originales:

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)); } }

Entrada: - Los caracteres de esta oración poseen cierto encanto, uno que a menudo se encuentra en la puntuación y la prosa. Esta es una segunda oración? Ciertamente así es.

Salida: 3 oraciones (''?'' Se considera un delimitador al final de la oración)

Nota: para una frase como "la clase de la Sra. Havisham era impecable (¡hasta donde se podía ver!) En todos los aspectos". El tokenizer discernirá correctamente que el período al final de Mrs. no es un EOS, ¡sin embargo marcará incorrectamente! dentro de los paréntesis como una EOS y dividir "en todos los aspectos". como una segunda oración.


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+"); } }