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

P

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.

 

About the author

Ramiro de la Vega

Bienvenido a Pharos.sh

Soy Ramiro de la Vega, Estadounidense con raíces Españolas. Empecé a programar hace casi 20 años cuando era muy jovencito.

Espero que en mi web encuentres la inspiración y ayuda que necesitas para adentrarte en el fantástico mundo de la programación y conseguir tus objetivos por difíciles que sean.

Add comment

Sobre mi

Últimos Post

Etiquetas

Esta web utiliza cookies propias para su correcto funcionamiento. Al hacer clic en el botón Aceptar, aceptas el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Más información
Privacidad