Python para PNL: partes del etiquetado de voz y reconocimiento de entidades nombradas

    Este es el cuarto art铆culo de mi serie de art铆culos sobre Python para PNL. En mi art铆culo anterior, expliqu茅 c贸mo espacio La biblioteca se puede utilizar para realizar tareas como la coincidencia de vocabulario y frases.

    En este art铆culo, estudiaremos en detalle partes del etiquetado de voz y el reconocimiento de entidades con nombre. Veremos c贸mo se puede utilizar la biblioteca spaCy para realizar estas dos tareas.

    Etiquetado de partes del discurso (POS)

    El etiquetado de partes del discurso simplemente se refiere a asignar partes del discurso a palabras individuales en una oraci贸n, lo que significa que, a diferencia de la coincidencia de frases, que se realiza a nivel de oraci贸n o de varias palabras, el etiquetado de partes del discurso se realiza a nivel de token.

    Tomemos un ejemplo muy simple de etiquetado de partes del discurso.

    import spacy
    sp = spacy.load('en_core_web_sm')
    

    Como es habitual, en el script anterior importamos el modelo principal de spaCy English. A continuaci贸n, necesitamos crear un documento espacial que utilizaremos para realizar el etiquetado de partes del discurso.

    sen = sp(u"I like to play football. I hated it in my childhood though")
    

    El objeto de documento spaCy tiene varios atributos que se pueden usar para realizar una variedad de tareas. Por ejemplo, para imprimir el texto del documento, el text se utiliza el atributo. Del mismo modo, el pos_ El atributo devuelve la etiqueta POS de grano grueso. Para obtener etiquetas de punto de venta de grano fino, podr铆amos usar la tag_ atributo. Y finalmente, para obtener la explicaci贸n de una etiqueta, podemos usar el spacy.explain() m茅todo y pasarle el nombre de la etiqueta.

    Veamos esto en acci贸n:

    print(sen.text)
    

    El script anterior simplemente imprime el texto de la oraci贸n. La salida se ve as铆:

    I like to play football. I hated it in my childhood though
    

    A continuaci贸n, veamos pos_ atributo. Imprimiremos la etiqueta POS de la palabra “odiado”, que en realidad es el s茅ptimo token de la oraci贸n.

    print(sen[7].pos_)
    

    Salida:

    VERB
    

    Puede ver que la etiqueta POS devuelta para “odiado” es un “VERBO”, ya que “odiado” es un verbo.

    Ahora imprimamos la etiqueta de punto de venta detallada para la palabra “odiado”.

    print(sen[7].tag_)
    

    Salida:

    VBD
    

    Para ver lo que significa VBD, podemos usar spacy.explain() m茅todo como se muestra a continuaci贸n:

    print(spacy.explain(sen[7].tag_))
    

    Salida:

    verb, past tense
    

    La salida muestra que VBD es un verbo en tiempo pasado.

    Imprimamos el texto, las etiquetas de POS de grano grueso, las etiquetas de POS de grano fino y la explicaci贸n de las etiquetas de todas las palabras de la oraci贸n.

    for word in sen:
        print(f'{word.text:{12}} {word.pos_:{10}} {word.tag_:{8}} {spacy.explain(word.tag_)}')
    

    En el script anterior, mejoramos la legibilidad y el formato agregando 12 espacios entre el texto y la etiqueta de POS de grano grueso y luego otros 10 espacios entre las etiquetas de POS de grano grueso y las etiquetas de POS de grano fino.

    Salida:

    I            PRON       PRP      pronoun, personal
    like         VERB       VBP      verb, non-3rd person singular present
    to           PART       TO       infinitival to
    play         VERB       VB       verb, base form
    football     NOUN       NN       noun, singular or mass
    .            PUNCT      .        punctuation mark, sentence closer
    I            PRON       PRP      pronoun, personal
    hated        VERB       VBD      verb, past tense
    it           PRON       PRP      pronoun, personal
    in           ADP        IN       conjunction, subordinating or preposition
    my           ADJ        PRP$     pronoun, possessive
    childhood    NOUN       NN       noun, singular or mass
    though       ADP        IN       conjunction, subordinating or preposition
    

    UN lista completa de etiquetas para las partes del discurso y las etiquetas detalladas, junto con su explicaci贸n, est谩 disponible en la documentaci贸n oficial de spaCy.

    驴Por qu茅 es 煤til el etiquetado de puntos de venta?

    El etiquetado de POS puede ser realmente 煤til, especialmente si tiene palabras o tokens que pueden tener varias etiquetas de POS. Por ejemplo, la palabra “google” se puede utilizar tanto como sustantivo como como verbo, seg煤n el contexto. Al procesar el lenguaje natural, es importante identificar esta diferencia. Afortunadamente, la biblioteca spaCy viene predise帽ada con algoritmos de Machine Learning que, dependiendo del contexto (palabras circundantes), es capaz de devolver la etiqueta POS correcta para la palabra.

    Veamos esto en acci贸n. Ejecute el siguiente script:

    sen = sp(u'Can you google it?')
    word = sen[2]
    
    print(f'{word.text:{12}} {word.pos_:{10}} {word.tag_:{8}} {spacy.explain(word.tag_)}')
    

    En el script de arriba creamos un documento espaciado con el texto “驴Puedes buscarlo en Google?” Aqu铆 la palabra “google” se utiliza como verbo. A continuaci贸n, imprimimos la etiqueta POS de la palabra “google” junto con la explicaci贸n de la etiqueta. La salida se ve as铆:

    google       VERB       VB       verb, base form
    

    En la salida, puede ver que la palabra “google” se ha identificado correctamente como un verbo.

    Veamos ahora otro ejemplo:

    sen = sp(u'Can you search it on google?')
    word = sen[5]
    
    print(f'{word.text:{12}} {word.pos_:{10}} {word.tag_:{8}} {spacy.explain(word.tag_)}')
    

    Aqu铆, en el script anterior, la palabra “google” se usa como sustantivo como se muestra en el resultado:

    google       PROPN      NNP      noun, proper singular
    

    Encontrar el n煤mero de etiquetas POS

    Puede encontrar el n煤mero de apariciones de cada etiqueta POS llamando al count_by en el objeto de documento spaCy. El m茅todo toma spacy.attrs.POS como valor de par谩metro.

    sen = sp(u"I like to play football. I hated it in my childhood though")
    
    num_pos = sen.count_by(spacy.attrs.POS)
    num_pos
    

    Salida:

    {96: 1, 99: 3, 84: 2, 83: 1, 91: 2, 93: 1, 94: 3}
    

    En la salida, puede ver el ID de las etiquetas POS junto con sus frecuencias de aparici贸n. El texto de la etiqueta POS se puede mostrar pasando el ID de la etiqueta al vocabulario del documento spaCy real.

    for k,v in sorted(num_pos.items()):
        print(f'{k}. {sen.vocab[k].text:{8}}: {v}')
    

    Ahora, en la salida, ver谩 la ID, el texto y la frecuencia de cada etiqueta como se muestra a continuaci贸n:

    83. ADJ     : 1
    84. ADP     : 2
    91. NOUN    : 2
    93. PART    : 1
    94. PRON    : 3
    96. PUNCT   : 1
    99. VERB    : 3
    

    Visualizaci贸n de partes de etiquetas de voz

    Visualizar las etiquetas de POS de forma gr谩fica es extremadamente f谩cil. los displacy m贸dulo del spacy biblioteca se utiliza para este prop贸sito. Para visualizar las etiquetas POS dentro del cuaderno de Jupyter, debe llamar al render m茅todo del displacy m贸dulo y pasarle el documento espacial, el estilo de la visualizaci贸n, y establecer el jupyter atribuir a True Como se muestra abajo:

    from spacy import displacy
    
    sen = sp(u"I like to play football. I hated it in my childhood though")
    displacy.render(sen, style="dep", jupyter=True, options={'distance': 85})
    

    En la salida, deber铆a ver el siguiente 谩rbol de dependencia para las etiquetas POS.

    Puede ver claramente la dependencia de cada token en otro junto con la etiqueta POS.

    Si desea visualizar las etiquetas POS fuera del cuaderno de Jupyter, debe llamar al serve m茅todo. El gr谩fico de las etiquetas POS se imprimir谩 en formato HTML dentro de su navegador predeterminado. Ejecute el siguiente script:

    displacy.serve(sen, style="dep", options={'distance': 120})
    

    Una vez que ejecute el script anterior, ver谩 el siguiente mensaje:

    Serving on port 5000...
    Using the 'dep' visualizer
    

    Para ver el 谩rbol de dependencias, escriba la siguiente direcci贸n en su navegador: http://127.0.0.1:5000/. Ver谩 el siguiente 谩rbol de dependencias:

    Reconocimiento de entidad nombrada

    El reconocimiento de entidad con nombre se refiere a la identificaci贸n de palabras en una oraci贸n como una entidad, por ejemplo, el nombre de una persona, lugar, organizaci贸n, etc. Veamos c贸mo la biblioteca spaCy realiza el reconocimiento de entidad con nombre. Mira el siguiente gui贸n:

    import spacy
    sp = spacy.load('en_core_web_sm')
    
    sen = sp(u'Manchester United is looking to sign Harry Kane for $90 million')
    

    En la secuencia de comandos anterior, creamos un documento de espacio simple con algo de texto. Para encontrar la entidad nombrada podemos usar el ents atributo, que devuelve la lista de todas las entidades nombradas en el documento.

    print(sen.ents)
    

    Salida:

    (Manchester United, Harry Kane, $90 million)
    

    Puede ver que se identificaron tres entidades con nombre. Para ver el detalle de cada entidad nombrada, puede utilizar el text, label, y el spacy.explain m茅todo que toma el objeto de la entidad como par谩metro.

    for entity in sen.ents:
        print(entity.text + ' - ' + entity.label_ + ' - ' + str(spacy.explain(entity.label_)))
    

    En la salida, ver谩 el nombre de la entidad junto con el tipo de entidad y una peque帽a descripci贸n de la entidad como se muestra a continuaci贸n:

    Manchester United - ORG - Companies, agencies, institutions, etc.
    Harry Kane - PERSON - People, including fictional
    $90 million - MONEY - Monetary values, including unit
    

    Se puede ver que “Manchester United” ha sido correctamente identificado como organizaci贸n, empresa, etc. De igual forma, “Harry Kane” ha sido identificado como persona y finalmente, “$ 90 millones” se ha identificado correctamente como una entidad de tipo Dinero.

    Agregar nuevas entidades

    Tambi茅n puede agregar nuevas entidades a un documento existente. Por ejemplo, en el siguiente ejemplo, la biblioteca spaCy no identifica a “Nesfruita” como una empresa.

    sen = sp(u'Nesfruita is setting up a new company in India')
    for entity in sen.ents:
        print(entity.text + ' - ' + entity.label_ + ' - ' + str(spacy.explain(entity.label_)))
    

    Salida:

    India - GPE - Countries, cities, states
    

    En el resultado, puede ver que solo India se ha identificado como entidad.

    Ahora para agregar “Nesfruita” como una entidad de tipo “ORG” a nuestro documento, necesitamos ejecutar los siguientes pasos:

    from spacy.tokens import Span
    
    ORG = sen.vocab.strings[u'ORG']
    new_entity = Span(sen, 0, 1, label=ORG)
    sen.ents = list(sen.ents) + [new_entity]
    

    Primero, necesitamos importar el Span clase de la spacy.tokens m贸dulo. A continuaci贸n, necesitamos obtener el valor hash de la ORG tipo de entidad de nuestro documento. Despu茅s de eso, necesitamos asignar el valor hash de ORG al lapso. Dado que “Nesfruita” es la primera palabra del documento, el intervalo es 0-1. Finalmente, necesitamos agregar el nuevo intervalo de entidades a la lista de entidades. Ahora, si ejecuta el siguiente script, ver谩 “Nesfruita” en la lista de entidades.

    for entity in sen.ents:
        print(entity.text + ' - ' + entity.label_ + ' - ' + str(spacy.explain(entity.label_)))
    

    La salida del script anterior se ve as铆:

    Nesfruita - ORG - Companies, agencies, institutions, etc.
    India - GPE - Countries, cities, states
    

    Contando entidades

    En el caso de las etiquetas POS, podr铆amos contar la frecuencia de cada etiqueta POS en un documento usando un m茅todo especial sen.count_by. Sin embargo, para las entidades con nombre, no existe tal m茅todo. Podemos contar manualmente la frecuencia de cada tipo de entidad. Supongamos que tenemos el siguiente documento junto con sus entidades:

    sen = sp(u'Manchester United is looking to sign Harry Kane for $90 million. David demand 100 Million Dollars')
    for entity in sen.ents:
        print(entity.text + ' - ' + entity.label_ + ' - ' + str(spacy.explain(entity.label_)))
    

    Salida:

    Manchester United - ORG - Companies, agencies, institutions, etc.
    Harry Kane - PERSON - People, including fictional
    $90 million - MONEY - Monetary values, including unit
    David - PERSON - People, including fictional
    100 Million Dollars - MONEY - Monetary values, including unit
    

    Para contar las entidades de tipo de persona en el documento anterior, podemos usar el siguiente script:

    len([ent for ent in sen.ents if ent.label_=='PERSON'])
    

    En la salida, ver谩 2 ya que hay 2 entidades de tipo PERSONA en el documento.

    Visualizaci贸n de entidades nombradas

    Al igual que las etiquetas POS, tambi茅n podemos ver entidades con nombre dentro del cuaderno de Jupyter, as铆 como en el navegador.

    Para hacerlo, usaremos nuevamente el displacy objeto. Mira el siguiente ejemplo:

    from spacy import displacy
    
    sen = sp(u'Manchester United is looking to sign Harry Kane for $90 million. David demand 100 Million Dollars')
    displacy.render(sen, style="ent", jupyter=True)
    

    Puede ver que la 煤nica diferencia entre visualizar entidades con nombre y etiquetas POS es que aqu铆, en el caso de entidades con nombre, pasamos ent como el valor de la style par谩metro. La salida del script anterior se ve as铆:

    Puede ver en la salida que las entidades nombradas se han resaltado en diferentes colores junto con sus tipos de entidad.

    Tambi茅n puede filtrar qu茅 tipos de entidad mostrar. Para hacerlo, debe pasar el tipo de entidades que se mostrar谩n en una lista, que luego se pasa como un valor al ents clave de un diccionario. A continuaci贸n, el diccionario se pasa al options par谩metro de la render m茅todo del displacy m贸dulo como se muestra a continuaci贸n:

    filter = {'ents': ['ORG']}
    displacy.render(sen, style="ent", jupyter=True, options=filter)
    

    En el script anterior, especificamos que solo las entidades de tipo ORG deben mostrarse en la salida. La salida del script anterior se ve as铆:

    Por 煤ltimo, tambi茅n puede mostrar entidades con nombre fuera del cuaderno de Jupyter. El siguiente script mostrar谩 las entidades nombradas en su navegador predeterminado. Ejecute el siguiente script:

    displacy.serve(sen, style="ent")
    

    Ahora si vas a la direcci贸n http://127.0.0.1:5000/ en su navegador, deber铆a ver las entidades nombradas.

    Conclusi贸n

    Partes del etiquetado de voz y el reconocimiento de entidades con nombre son cruciales para el 茅xito de cualquier tarea de PNL. En este art铆culo, vimos c贸mo se puede usar la biblioteca spaCy de Python para realizar el etiquetado POS y el reconocimiento de entidades con nombre con la ayuda de diferentes ejemplos.

     

    Etiquetas:

    Deja una respuesta

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