Python para PNL: Introducci贸n a la biblioteca StanfordCoreNLP

    Este es el noveno art铆culo de mi serie de art铆culos sobre Python para PNL. En el art铆culo anterior, vimos c贸mo la biblioteca de patrones de Python se puede usar para realizar una variedad de tareas de PNL que van desde la tokenizaci贸n hasta el etiquetado de POS, y la clasificaci贸n de texto al an谩lisis de sentimientos. Antes de eso, exploramos la biblioteca TextBlob para realizar tareas similares de procesamiento del lenguaje natural.

    En este art铆culo, exploraremos StanfordCoreNLP biblioteca, que es otra biblioteca extremadamente 煤til para el procesamiento del lenguaje natural. Veremos diferentes caracter铆sticas de StanfordCoreNLP con la ayuda de ejemplos. Entonces, antes de perder m谩s tiempo, comencemos.

    Configurar el entorno

    El proceso de instalaci贸n de StanfordCoreNLP no es tan sencillo como las otras bibliotecas de Python. De hecho, StanfordCoreNLP es una biblioteca que est谩 escrita en Java. Por lo tanto, aseg煤rese de tener Java instalado en su sistema. Puede descargar el 煤ltima versi贸n de Java libremente.

    Una vez que haya instalado Java, debe descargar los archivos JAR para las bibliotecas StanfordCoreNLP. El archivo JAR contiene modelos que se utilizan para realizar diferentes tareas de PNL. Para descargar los archivos JAR para los modelos en ingl茅s, descargue y descomprima la carpeta ubicada en el sitio web oficial StanfordCoreNLP.

    Lo siguiente que debe hacer es ejecutar el servidor que atender谩 las solicitudes enviadas por el contenedor de Python a la biblioteca StanfordCoreNLP. Navegue hasta la ruta donde descomprimi贸 la carpeta de archivos JAR. Navegue dentro de la carpeta y ejecute el siguiente comando en el s铆mbolo del sistema:

    $ java -mx6g -cp "*" edu.stanford.nlp.pipeline.StanfordCoreNLPServer -timeout 10000
    

    El comando anterior inicia el servidor StanfordCoreNLP. El par谩metro -mx6g especifica que la memoria utilizada por el servidor no debe exceder los 6 gigabytes. Es importante mencionar que debe ejecutar un sistema de 64 bits para tener un mont贸n de hasta 6 GB. Si est谩 ejecutando un sistema de 32 bits, es posible que deba reducir el tama帽o de la memoria dedicada al servidor.

    Una vez que ejecute el comando anterior, deber铆a ver el siguiente resultado:

    [main] INFO CoreNLP - --- StanfordCoreNLPServer#main() called ---
    [main] INFO CoreNLP - setting default constituency parser
    [main] INFO CoreNLP - warning: cannot find edu/stanford/nlp/models/srparser/englishSR.ser.gz
    [main] INFO CoreNLP - using: edu/stanford/nlp/models/lexparser/englishPCFG.ser.gz instead
    [main] INFO CoreNLP - to use shift reduce parser download English models jar from:
    [main] INFO CoreNLP - http://stanfordnlp.github.io/CoreNLP/download.html
    [main] INFO CoreNLP -     Threads: 8
    [main] INFO CoreNLP - Starting server...
    [main] INFO CoreNLP - StanfordCoreNLPServer listening at /0:0:0:0:0:0:0:0:9000
    

    El servidor se ejecuta en el puerto 9000.

    Ahora, el paso final es instalar el contenedor de Python para la biblioteca StanfordCoreNLP. La envoltura que usaremos es pycorenlp. El siguiente script descarga la biblioteca contenedora:

    $ pip install pycorenlp
    

    Ahora estamos todos listos para conectarnos al servidor StanfordCoreNLP y realizar las tareas NLP deseadas.

    Para conectarnos al servidor, tenemos que pasar la direcci贸n del servidor StanfordCoreNLP que inicializamos antes al StanfordCoreNLP clase de la pycorenlp m贸dulo. El objeto devuelto se puede utilizar para realizar tareas de PNL. Mira el siguiente gui贸n:

    from pycorenlp import StanfordCoreNLP
    
    nlp_wrapper = StanfordCoreNLP('http://localhost:9000')
    

    Realizaci贸n de tareas de PNL

    En esta secci贸n, exploraremos brevemente el uso de la biblioteca StanfordCoreNLP para realizar tareas comunes de PNL.

    Lematizaci贸n, etiquetado POS y reconocimiento de entidades nombradas

    La lematizaci贸n, el etiquetado de partes del habla y el reconocimiento de entidades con nombre son las tareas m谩s b谩sicas de la PNL. La biblioteca StanfordCoreNLP admite la funcionalidad de canalizaci贸n que se puede utilizar para realizar estas tareas de forma estructurada.

    En el siguiente script, crearemos un anotador que primero divide un documento en oraciones y luego divide las oraciones en palabras o tokens. Luego, las palabras se anotan con el POS y las etiquetas de reconocimiento de entidad nombradas.

    doc = "Ronaldo has moved from Real Madrid to Juventus. While messi still plays for Barcelona"
    annot_doc = nlp_wrapper.annotate(doc,
        properties={
            'annotators': 'ner, pos',
            'outputFormat': 'json',
            'timeout': 1000,
        })
    

    En el gui贸n de arriba tenemos un documento con dos frases. Usamos el annotate m茅todo del objeto contenedor StanfordCoreNLP que inicializamos anteriormente. El m茅todo toma tres par谩metros. los annotator El par谩metro toma el tipo de anotaci贸n que queremos realizar en el texto. Pasamos 'ner, pos' como el valor de la annotator par谩metro que especifica que queremos anotar nuestro documento para etiquetas POS y entidades con nombre.

    los outputFormat La variable define el formato en el que desea el texto anotado. Los posibles valores son json para objetos JSON, xml para formato XML, text para texto sin formato, y serialize para datos serializados.

    El par谩metro final es el tiempo de espera en milisegundos, que define el tiempo que el contenedor debe esperar la respuesta del servidor antes de que se agote el tiempo.

    En la salida, deber铆a ver un objeto JSON de la siguiente manera:

    
    {'sentences': [{'index': 0,
       'entitymentions': [{'docTokenBegin': 0,
         'docTokenEnd': 1,
         'tokenBegin': 0,
         'tokenEnd': 1,
         'text': 'Ronaldo',
         'characterOffsetBegin': 0,
         'characterOffsetEnd': 7,
         'ner': 'PERSON'},
        {'docTokenBegin': 4,
         'docTokenEnd': 6,
         'tokenBegin': 4,
         'tokenEnd': 6,
         'text': 'Real Madrid',
         'characterOffsetBegin': 23,
         'characterOffsetEnd': 34,
         'ner': 'ORGANIZATION'},
        {'docTokenBegin': 7,
         'docTokenEnd': 8,
         'tokenBegin': 7,
         'tokenEnd': 8,
         'text': 'Juventus',
         'characterOffsetBegin': 38,
         'characterOffsetEnd': 46,
         'ner': 'ORGANIZATION'}],
       'tokens': [{'index': 1,
         'word': 'Ronaldo',
         'originalText': 'Ronaldo',
         'lemma': 'Ronaldo',
         'characterOffsetBegin': 0,
         'characterOffsetEnd': 7,
         'pos': 'NNP',
         'ner': 'PERSON',
         'before': '',
         'after': ' '},
        {'index': 2,
         'word': 'has',
         'originalText': 'has',
         'lemma': 'have',
         'characterOffsetBegin': 8,
         'characterOffsetEnd': 11,
         'pos': 'VBZ',
         'ner': 'O',
         'before': ' ',
         'after': ' '},
        {'index': 3,
         'word': 'moved',
         'originalText': 'moved',
         'lemma': 'move',
         'characterOffsetBegin': 12,
         'characterOffsetEnd': 17,
         'pos': 'VBN',
         'ner': 'O',
         'before': ' ',
         'after': ' '},
        {'index': 4,
         'word': 'from',
         'originalText': 'from',
         'lemma': 'from',
         'characterOffsetBegin': 18,
         'characterOffsetEnd': 22,
         'pos': 'IN',
         'ner': 'O',
         'before': ' ',
         'after': ' '},
        {'index': 5,
         'word': 'Real',
         'originalText': 'Real',
         'lemma': 'real',
         'characterOffsetBegin': 23,
         'characterOffsetEnd': 27,
         'pos': 'JJ',
         'ner': 'ORGANIZATION',
         'before': ' ',
         'after': ' '},
        {'index': 6,
         'word': 'Madrid',
         'originalText': 'Madrid',
         'lemma': 'Madrid',
         'characterOffsetBegin': 28,
         'characterOffsetEnd': 34,
         'pos': 'NNP',
         'ner': 'ORGANIZATION',
         'before': ' ',
         'after': ' '},
        {'index': 7,
         'word': 'to',
         'originalText': 'to',
         'lemma': 'to',
         'characterOffsetBegin': 35,
         'characterOffsetEnd': 37,
         'pos': 'TO',
         'ner': 'O',
         'before': ' ',
         'after': ' '},
        {'index': 8,
         'word': 'Juventus',
         'originalText': 'Juventus',
         'lemma': 'Juventus',
         'characterOffsetBegin': 38,
         'characterOffsetEnd': 46,
         'pos': 'NNP',
         'ner': 'ORGANIZATION',
         'before': ' ',
         'after': ''},
        {'index': 9,
         'word': '.',
         'originalText': '.',
         'lemma': '.',
         'characterOffsetBegin': 46,
         'characterOffsetEnd': 47,
         'pos': '.',
         'ner': 'O',
         'before': '',
         'after': ' '}]},
      {'index': 1,
       'entitymentions': [{'docTokenBegin': 14,
         'docTokenEnd': 15,
         'tokenBegin': 5,
         'tokenEnd': 6,
         'text': 'Barcelona',
         'characterOffsetBegin': 76,
         'characterOffsetEnd': 85,
         'ner': 'ORGANIZATION'}],
       'tokens': [{'index': 1,
         'word': 'While',
         'originalText': 'While',
         'lemma': 'while',
         'characterOffsetBegin': 48,
         'characterOffsetEnd': 53,
         'pos': 'IN',
         'ner': 'O',
         'before': ' ',
         'after': ' '},
        {'index': 2,
         'word': 'messi',
         'originalText': 'messi',
         'lemma': 'messus',
         'characterOffsetBegin': 54,
         'characterOffsetEnd': 59,
         'pos': 'NNS',
         'ner': 'O',
         'before': ' ',
         'after': ' '},
        {'index': 3,
         'word': 'still',
         'originalText': 'still',
         'lemma': 'still',
         'characterOffsetBegin': 60,
         'characterOffsetEnd': 65,
         'pos': 'RB',
         'ner': 'O',
         'before': ' ',
         'after': ' '},
        {'index': 4,
         'word': 'plays',
         'originalText': 'plays',
         'lemma': 'play',
         'characterOffsetBegin': 66,
         'characterOffsetEnd': 71,
         'pos': 'VBZ',
         'ner': 'O',
         'before': ' ',
         'after': ' '},
        {'index': 5,
         'word': 'for',
         'originalText': 'for',
         'lemma': 'for',
         'characterOffsetBegin': 72,
         'characterOffsetEnd': 75,
         'pos': 'IN',
         'ner': 'O',
         'before': ' ',
         'after': ' '},
        {'index': 6,
         'word': 'Barcelona',
         'originalText': 'Barcelona',
         'lemma': 'Barcelona',
         'characterOffsetBegin': 76,
         'characterOffsetEnd': 85,
         'pos': 'NNP',
         'ner': 'ORGANIZATION',
         'before': ' ',
         'after': ''}]}]}
    

    Si observa detenidamente el script anterior, puede encontrar las etiquetas POS, las entidades con nombre y la versi贸n lematizada de cada palabra.

    Lematizaci贸n

    Exploremos ahora los resultados anotados. Primero imprimiremos las lematizaciones de las palabras en las dos oraciones en nuestro conjunto de datos:

    for sentence in annot_doc["sentences"]:
        for word in sentence["tokens"]:
            print(word["word"] + " => " + word["lemma"])
    

    En el script anterior, el bucle externo recorre cada oraci贸n del documento y el bucle interno recorre cada palabra de la oraci贸n. Dentro del bucle interno, la palabra y su correspondiente forma lematizada est谩n impresas en la consola. La salida se ve as铆:

    Ronaldo=>Ronaldo
    has=>have
    moved=>move
    from=>from
    Real=>real
    Madrid=>Madrid
    to=>to
    Juventus=>Juventus
    .=>.
    While=>while
    messi=>messus
    still=>still
    plays=>play
    for=>for
    Barcelona=>Barcelona
    

    Por ejemplo, puede ver la palabra moved ha sido lematizado a move, de manera similar la palabra plays ha sido lematizado a play.

    Etiquetado POS

    De la misma forma, podemos encontrar las etiquetas POS para cada palabra. Mira el siguiente gui贸n:

    for sentence in annot_doc["sentences"]:
        for word in sentence["tokens"]:
            print (word["word"] + "=>" + word["pos"])
    

    En la salida, deber铆a ver los siguientes resultados:

    Ronaldo=>NNP
    has=>VBZ
    moved=>VBN
    from=>IN
    Real=>JJ
    Madrid=>NNP
    to=>TO
    Juventus=>NNP
    .=>.
    While=>IN
    messi=>NNS
    still=>RB
    plays=>VBZ
    for=>IN
    Barcelona=>NNP
    

    El conjunto de etiquetas utilizado para las etiquetas POS es el conjunto de etiquetas Penn Treebank y se puede encontrar Aqu铆.

    Reconocimiento de entidad nombrada

    Para encontrar entidades con nombre en nuestro documento, podemos usar el siguiente script:

    for sentence in annot_doc["sentences"]:
        for word in sentence["tokens"]:
            print (word["word"] + "=>" + word["ner"])
    

    La salida se ve as铆:

    Ronaldo=>PERSON
    has=>O
    moved=>O
    from=>O
    Real=>ORGANIZATION
    Madrid=>ORGANIZATION
    to=>O
    Juventus=>ORGANIZATION
    .=>O
    While=>O
    messi=>O
    still=>O
    plays=>O
    for=>O
    Barcelona=>ORGANIZATION
    

    Podemos ver eso Ronaldo ha sido identificado como un PERSON mientras Barcelona ha sido identificado como Organization, que en este caso es correcto.

    An谩lisis de los sentimientos

    Para encontrar el sentimiento de una oraci贸n, todo lo que tienes que hacer es aprobar sentiment como el valor de la annotators propiedad. Mira el siguiente gui贸n:

    doc = "I like this chocolate. This chocolate is not good. The chocolate is delicious. Its a very tasty chocolate. This is so bad"
    annot_doc = nlp_wrapper.annotate(doc,
        properties={
           'annotators': 'sentiment',
           'outputFormat': 'json',
           'timeout': 1000,
        })
    

    Para encontrar el sentimiento, podemos iterar sobre cada oraci贸n y luego usar sentimentValue propiedad para encontrar el sentimiento. los sentimentValue devuelve un valor entre 1 y 4, donde 1 corresponde a un sentimiento muy negativo mientras que 4 corresponde a un sentimiento muy positivo. los sentiment La propiedad se puede usar para obtener sentimientos en forma verbal, es decir positive, negative o neutral.

    El siguiente gui贸n encuentra el sentimiento para cada oraci贸n en el documento que definimos anteriormente.

    for sentence in annot_doc["sentences"]:
        print ( " ".join([word["word"] for word in sentence["tokens"]]) + " => " 
            + str(sentence["sentimentValue"]) + " = "+ sentence["sentiment"])
    

    Salida:

    I like this chocolate . => 2 = Neutral
    This chocolate is not good . => 1 = Negative
    The chocolate is delicious . => 3 = Positive
    Its a very tasty chocolate . => 3 = Positive
    This is so bad => 1 = Negative
    

    Conclusi贸n

    StanfordCoreNLP es otra biblioteca extremadamente 煤til para el procesamiento del lenguaje natural. En este art铆culo, estudiamos c贸mo configurar el entorno para ejecutar StanfordCoreNLP. Luego exploramos el uso de la biblioteca StanfordCoreNLP para tareas comunes de PNL como lematizaci贸n, etiquetado POS y reconocimiento de entidades nombradas y finalmente, completamos el art铆culo con an谩lisis sentimental utilizando StanfordCoreNLP.

     

    Etiquetas:

    Deja una respuesta

    Tu direcci贸n de correo electr贸nico no ser谩 publicada. Los campos obligatorios est谩n marcados con *