python - tutorial - Cómo ajustar el tokenizador de oraciones NLTK
nltk tokenize (4)
Así que tuve un problema similar y probé la solución de vpekar anterior.
Quizás el mío es un caso de ventaja, pero observé el mismo comportamiento después de aplicar los reemplazos, sin embargo, cuando intenté reemplazar la puntuación con las citas colocadas delante de ellos, obtuve la salida que estaba buscando. Presumiblemente, la falta de adherencia al MLA es menos importante que mantener la cita original como una sola oración.
Para ser más claro:
text = text.replace(''?"'', ''"?'').replace(''!"'', ''"!'').replace(''."'', ''".'')
Si el MLA es importante, siempre podría regresar y revertir estos cambios donde sea que cuente.
Estoy usando NLTK para analizar algunos textos clásicos y me estoy dando problemas para tokenizar el texto por frase. Por ejemplo, esto es lo que obtengo por un fragmento de Moby Dick :
import nltk
sent_tokenize = nltk.data.load(''tokenizers/punkt/english.pickle'')
''''''
(Chapter 16)
A clam for supper? a cold clam; is THAT what you mean, Mrs. Hussey?" says I, "but
that''s a rather cold and clammy reception in the winter time, ain''t it, Mrs. Hussey?"
''''''
sample = ''A clam for supper? a cold clam; is THAT what you mean, Mrs. Hussey?" says I, "but that/'s a rather cold and clammy reception in the winter time, ain/'t it, Mrs. Hussey?"''
print "/n-----/n".join(sent_tokenize.tokenize(sample))
''''''
OUTPUT
"A clam for supper?
-----
a cold clam; is THAT what you mean, Mrs.
-----
Hussey?
-----
" says I, "but that/'s a rather cold and clammy reception in the winter time, ain/'t it, Mrs.
-----
Hussey?
-----
"
''''''
No espero perfección aquí, considerando que la sintaxis de Melville está un poco pasada de moda, pero NLTK debería ser capaz de manejar comillas dobles y títulos como "Sra." Sin embargo, dado que el tokenizador es el resultado de un entrenamiento no supervisado, no puedo encontrar la manera de jugar con él.
¿Alguien tiene recomendaciones para un mejor tokenizador de oraciones? Prefiero una heurística simple que pueda piratear en lugar de tener que entrenar a mi propio analizador.
Debes proporcionar una lista de abreviaturas al tokenizer, así:
from nltk.tokenize.punkt import PunktSentenceTokenizer, PunktParameters
punkt_param = PunktParameters()
punkt_param.abbrev_types = set([''dr'', ''vs'', ''mr'', ''mrs'', ''prof'', ''inc''])
sentence_splitter = PunktSentenceTokenizer(punkt_param)
text = "is THAT what you mean, Mrs. Hussey?"
sentences = sentence_splitter.tokenize(text)
oraciones es ahora:
[''is THAT what you mean, Mrs. Hussey?'']
Actualización: esto no funciona si la última palabra de la oración tiene un apóstrofe o una comilla adjunta (como Hussey? '' ). Entonces, una forma rápida y sucia de esto es colocar espacios delante de los apóstrofos y las comillas que siguen a los símbolos de la frase final (.!?):
text = text.replace(''?"'', ''? "'').replace(''!"'', ''! "'').replace(''."'', ''. "'')
Puede decirle al método PunktSentenceTokenizer.tokenize
que incluya comillas dobles "terminales" con el resto de la oración estableciendo el parámetro realign_boundaries
en True
. Vea el código de abajo para un ejemplo.
No conozco una manera limpia de evitar que texto como la Mrs. Hussey
se divida en dos oraciones. Sin embargo, aquí hay un hack que
- Derrota todas las ocurrencias de la
Mrs. Hussey
a laMrs. Hussey
, - luego divide el texto en oraciones con
sent_tokenize.tokenize
, - luego, para cada oración, destraba a
Mrs._Hussey
vuelta a laMrs. Hussey
Ojalá supiera una mejor manera, pero esto podría funcionar en caso de apuro.
import nltk
import re
import functools
mangle = functools.partial(re.sub, r''([MD]rs?[.]) ([A-Z])'', r''/1_/2'')
unmangle = functools.partial(re.sub, r''([MD]rs?[.])_([A-Z])'', r''/1 /2'')
sent_tokenize = nltk.data.load(''tokenizers/punkt/english.pickle'')
sample = ''''''"A clam for supper? a cold clam; is THAT what you mean, Mrs. Hussey?" says I, "but that/'s a rather cold and clammy reception in the winter time, ain/'t it, Mrs. Hussey?"''''''
sample = mangle(sample)
sentences = [unmangle(sent) for sent in sent_tokenize.tokenize(
sample, realign_boundaries = True)]
print u"/n-----/n".join(sentences)
rendimientos
"A clam for supper?
-----
a cold clam; is THAT what you mean, Mrs. Hussey?"
-----
says I, "but that''s a rather cold and clammy reception in the winter time, ain''t it, Mrs. Hussey?"
Puede modificar el tokenizador de oraciones en inglés preformado de NLTK para reconocer más abreviaturas agregándolo al conjunto _params.abbrev_types
. Por ejemplo:
extra_abbreviations = [''dr'', ''vs'', ''mr'', ''mrs'', ''prof'', ''inc'', ''i.e'']
sentence_tokenizer = nltk.data.load(''tokenizers/punkt/english.pickle'')
sentence_tokenizer._params.abbrev_types.update(extra_abbreviations)
Tenga en cuenta que las abreviaturas deben especificarse sin el período final, pero incluyen cualquier período interno, como en ''i.e''
arriba. Para obtener más información sobre los otros parámetros del tokenizer, consulte la documentación relevante.