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:
Te puede interesar:Python: compruebe si la variable es un númeroVERB
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.
Te puede interesar:Introducción a PyTorch para la clasificación¿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:
Te puede interesar:Python para PNL: Traducción automática neuronal con Seq2Seq en Keras83. 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:
Te puede interesar:Introducción a Python PyAutoGUIManchester 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.
Te puede interesar:Resolver sistemas de ecuaciones lineales con Python’s NumpyConclusió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.