Solución:
Esto podría ayudarte.
from __future__ import unicode_literals
import spacy,en_core_web_sm
import textacy
nlp = en_core_web_sm.load()
sentence="The author is writing a new book."
pattern = r'<VERB>?<ADV>*<VERB>+'
doc = textacy.Doc(sentence, lang='en_core_web_sm')
lists = textacy.extract.pos_regex_matches(doc, pattern)
for list in lists:
print(list.text)
Producción:
is writing
Sobre cómo resaltar las frases verbales, consulte el enlace a continuación.
Resalte frases verbales usando spacy y html
Otro enfoque:
Textacy recientemente observado ha realizado algunos cambios en las coincidencias de expresiones regulares. Basándome en ese enfoque, lo intenté de esta manera.
from __future__ import unicode_literals
import spacy,en_core_web_sm
import textacy
nlp = en_core_web_sm.load()
sentence="The cat sat on the mat. He dog jumped into the water. The author is writing a book."
pattern = [{'POS': 'VERB', 'OP': '?'},
{'POS': 'ADV', 'OP': '*'},
{'POS': 'VERB', 'OP': '+'}]
doc = textacy.make_spacy_doc(sentence, lang='en_core_web_sm')
lists = textacy.extract.matches(doc, pattern)
for list in lists:
print(list.text)
Producción:
sat
jumped
writing
Revisé las coincidencias de POS en estos enlaces, parece que el resultado no es el esperado.
[https://explosion.ai/demos/matcher][1]
¿Alguien intentó enmarcar etiquetas POS en lugar del patrón Regexp para encontrar frases verbales?
Edición 2:
import spacy
from spacy.matcher import Matcher
from spacy.util import filter_spans
nlp = spacy.load('en_core_web_sm')
sentence="The cat sat on the mat. He quickly ran to the market. The dog jumped into the water. The author is writing a book."
pattern = [{'POS': 'VERB', 'OP': '?'},
{'POS': 'ADV', 'OP': '*'},
{'POS': 'AUX', 'OP': '*'},
{'POS': 'VERB', 'OP': '+'}]
# instantiate a Matcher instance
matcher = Matcher(nlp.vocab)
matcher.add("Verb phrase", None, pattern)
doc = nlp(sentence)
# call the matcher to find matches
matches = matcher(doc)
spans = [doc[start:end] for _, start, end in matches]
print (filter_spans(spans))
Producción:
[sat, quickly ran, jumped, is writing]
Basado en la ayuda de la respuesta de mdmjsh.
Edit3: Comportamiento extraño.
La siguiente oración para el siguiente patrón, la frase verbal se identifica correctamente en https://explosion.ai/demos/matcher
pattern = [{'POS': 'VERB', 'OP': '?'},
{'POS': 'ADV', 'OP': '*'},
{'POS': 'VERB', 'OP': '+'}]
El gato muy negro debe estar realmente maullando muy ruidoso en el patio.
Pero genera lo siguiente mientras se ejecuta desde el código.
[must, really meowing]
Las referencias de respuesta anteriores textacy
, todo esto es posible. Spacy
directamente con el Matcher, sin necesidad de la biblioteca contenedora.
import spacy
from spacy.matcher import Matcher
nlp = spacy.load('en_core_web_sm') # download model first
sentence="The author was staring pensively as she wrote"
pattern=[{'POS': 'VERB', 'OP': '?'},
{'POS': 'ADV', 'OP': '*'},
{'OP': '*'}, # additional wildcard - match any text in between
{'POS': 'VERB', 'OP': '+'}]
# instantiate a Matcher instance
matcher = Matcher(nlp.vocab)
# Add pattern to matcher
matcher.add("verb-phrases", None, pattern)
doc = nlp(sentence)
# call the matcher to find matches
matches = matcher(doc)
Nb, esto devuelve una lista de tuplas que contienen el ID de coincidencia y el índice de finalización inicial para cada coincidencia, por ejemplo:
[(15658055046270554203, 0, 4),
(15658055046270554203, 1, 4),
(15658055046270554203, 2, 4),
(15658055046270554203, 3, 4),
(15658055046270554203, 0, 8),
(15658055046270554203, 1, 8),
(15658055046270554203, 2, 8),
(15658055046270554203, 3, 8),
(15658055046270554203, 4, 8),
(15658055046270554203, 5, 8),
(15658055046270554203, 6, 8),
(15658055046270554203, 7, 8)]
Puede convertir estas coincidencias en intervalos utilizando los índices.
spans = [doc[start:end] for _, start, end in matches]
# output
"""
The author was staring
author was staring
was staring
staring
The author was staring pensively as she wrote
author was staring pensively as she wrote
was staring pensively as she wrote
staring pensively as she wrote
pensively as she wrote
as she wrote
she wrote
wrote
"""
Tenga en cuenta que agregué el adicional {'OP': '*'},
al patrón que sirve como comodín cuando la nota se especifica con un POS / DEP específico (es decir, coincidirá con cualquier texto). Esto es útil aquí ya que la pregunta es sobre frases verbales: el formato VERBO, ADV, VERBO es una estructura inusual (intente pensar en algunas oraciones de ejemplo), sin embargo VERBO, ADV, [other text], VERBO es probable (como se indica en la oración de ejemplo “La autora miraba pensativamente mientras escribía”). Opcionalmente, puede refinar el patrón para que sea más específico (desplazado es su amigo aquí).
Nota adicional, todas las permutaciones de la coincidencia se devuelven debido a la codicia del comparador. opcionalmente, puede reducir esto a la forma más larga usando filter_spans para eliminar duplicados o superposiciones.
from spacy.util import filter_spans
filter_spans(spans)
# output
[The author was staring pensively as she wrote]