Набор инструментов для естественного языка - преобразование фрагментов
Зачем преобразовывать чанки?
До сих пор у нас есть отрывки или фразы из предложений, но что нам с ними делать? Одна из важных задач - их преобразовать. Но почему? Это сделать следующее -
- грамматическая коррекция и
- перестановка фраз
Фильтрация несущественных / бесполезных слов
Предположим, что если вы хотите оценить значение фразы, то есть много часто используемых слов, таких как «the», «a», которые не имеют значения или бесполезны. Например, см. Следующую фразу -
«Фильм был хорош».
Здесь наиболее значимы слова «кино» и «хорошо». Другими словами, «то» и «было» бесполезны или незначительны. Это потому, что без них мы можем получить то же значение фразы. 'Хорошее кино'.
В следующем рецепте Python мы узнаем, как удалить ненужные / несущественные слова и сохранить значимые слова с помощью тегов POS.
пример
Во-первых, просмотрев treebankКорпус для стоп-слов нам нужно решить, какие теги части речи значимы, а какие нет. Давайте посмотрим на следующую таблицу несущественных слов и тегов -
слово | Тег |
---|---|
а | DT |
Все | Тихоокеанское летнее время |
An | DT |
И | CC |
Или же | CC |
Тот | WDT |
В | DT |
Из приведенной выше таблицы мы видим, что все остальные теги, кроме CC, заканчиваются на DT, что означает, что мы можем отфильтровать несущественные слова, посмотрев на суффикс тега.
В этом примере мы собираемся использовать функцию с именем filter()который берет один фрагмент и возвращает новый фрагмент без каких-либо несущественных помеченных слов. Эта функция отфильтровывает любые теги, заканчивающиеся на DT или CC.
пример
import nltk
def filter(chunk, tag_suffixes=['DT', 'CC']):
significant = []
for word, tag in chunk:
ok = True
for suffix in tag_suffixes:
if tag.endswith(suffix):
ok = False
break
if ok:
significant.append((word, tag))
return (significant)
Теперь давайте используем эту функцию filter () в нашем рецепте Python для удаления незначительных слов -
from chunk_parse import filter
filter([('the', 'DT'),('good', 'JJ'),('movie', 'NN')])
Вывод
[('good', 'JJ'), ('movie', 'NN')]
Исправление глагола
Часто в реальном языке мы видим неправильные формы глаголов. Например, «все в порядке?» не является правильным. Глагольная форма в этом предложении неправильная. Предложение должно быть "все в порядке?" NLTK предоставляет нам способ исправить такие ошибки, создав сопоставления исправлений глаголов. Эти корректирующие сопоставления используются в зависимости от того, есть ли в фрагменте существительное во множественном или единственном числе.
пример
Чтобы реализовать рецепт Python, нам сначала нужно определить сопоставления исправлений глаголов. Давайте создадим два сопоставления следующим образом -
Plural to Singular mappings
plural= {
('is', 'VBZ'): ('are', 'VBP'),
('was', 'VBD'): ('were', 'VBD')
}
Singular to Plural mappings
singular = {
('are', 'VBP'): ('is', 'VBZ'),
('were', 'VBD'): ('was', 'VBD')
}
Как видно выше, каждое сопоставление имеет помеченный глагол, который сопоставляется с другим помеченным глаголом. Первоначальные отображения в нашем примере охватывают основные отображенияis to are, was to were, и наоборот.
Далее мы определим функцию с именем verbs(), в котором вы можете передать фрагмент с неправильной формой глагола и получить исправленный фрагмент обратно. Чтобы это сделать,verb() функция использует вспомогательную функцию с именем index_chunk() который будет искать во фрагменте позицию первого помеченного слова.
Давайте посмотрим на эти функции -
def index_chunk(chunk, pred, start = 0, step = 1):
l = len(chunk)
end = l if step > 0 else -1
for i in range(start, end, step):
if pred(chunk[i]):
return i
return None
def tag_startswith(prefix):
def f(wt):
return wt[1].startswith(prefix)
return f
def verbs(chunk):
vbidx = index_chunk(chunk, tag_startswith('VB'))
if vbidx is None:
return chunk
verb, vbtag = chunk[vbidx]
nnpred = tag_startswith('NN')
nnidx = index_chunk(chunk, nnpred, start = vbidx+1)
if nnidx is None:
nnidx = index_chunk(chunk, nnpred, start = vbidx-1, step = -1)
if nnidx is None:
return chunk
noun, nntag = chunk[nnidx]
if nntag.endswith('S'):
chunk[vbidx] = plural.get((verb, vbtag), (verb, vbtag))
else:
chunk[vbidx] = singular.get((verb, vbtag), (verb, vbtag))
return chunk
Сохраните эти функции в файле Python в вашем локальном каталоге, где установлен Python или Anaconda, и запустите его. Я сохранил это какverbcorrect.py.
Теперь позвольте нам позвонить verbs() функция на торговой точке с тегами is you fine кусок -
from verbcorrect import verbs
verbs([('is', 'VBZ'), ('you', 'PRP$'), ('fine', 'VBG')])
Вывод
[('are', 'VBP'), ('you', 'PRP$'), ('fine','VBG')]
Устранение пассивного залога из фраз
Еще одна полезная задача - исключить из фраз пассивный залог. Это можно сделать, поменяв местами слова вокруг глагола. Например,‘the tutorial was great’ может быть преобразован в ‘the great tutorial’.
пример
Для этого мы определяем функцию с именем eliminate_passive()который заменит правую часть блока на левую, используя глагол в качестве точки поворота. Чтобы найти глагол для поворота, он также будет использоватьindex_chunk() функция, определенная выше.
def eliminate_passive(chunk):
def vbpred(wt):
word, tag = wt
return tag != 'VBG' and tag.startswith('VB') and len(tag) > 2
vbidx = index_chunk(chunk, vbpred)
if vbidx is None:
return chunk
return chunk[vbidx+1:] + chunk[:vbidx]
Теперь позвольте нам позвонить eliminate_passive() функция на торговой точке с тегами the tutorial was great кусок -
from passiveverb import eliminate_passive
eliminate_passive(
[
('the', 'DT'), ('tutorial', 'NN'), ('was', 'VBD'), ('great', 'JJ')
]
)
Вывод
[('great', 'JJ'), ('the', 'DT'), ('tutorial', 'NN')]
Замена существительных кардиналов
Как мы знаем, кардинальное слово, такое как 5, помечается как CD в блоке. Эти кардинальные слова часто встречаются до или после существительного, но для нормализации полезно всегда ставить их перед существительным. Например, датаJanuary 5 можно записать как 5 January. Давайте разберемся с этим на следующем примере.
пример
Для этого мы определяем функцию с именем swapping_cardinals()это заменит любой кардинал, следующий сразу после существительного, на существительное. При этом кардинал будет стоять непосредственно перед существительным. Чтобы провести сравнение равенства с данным тегом, он использует вспомогательную функцию, которую мы назвали какtag_eql().
def tag_eql(tag):
def f(wt):
return wt[1] == tag
return f
Теперь мы можем определить swapping_cardinals () -
def swapping_cardinals (chunk):
cdidx = index_chunk(chunk, tag_eql('CD'))
if not cdidx or not chunk[cdidx-1][1].startswith('NN'):
return chunk
noun, nntag = chunk[cdidx-1]
chunk[cdidx-1] = chunk[cdidx]
chunk[cdidx] = noun, nntag
return chunk
Теперь позвольте нам позвонить swapping_cardinals() функционировать на свидании “January 5” -
from Cardinals import swapping_cardinals()
swapping_cardinals([('Janaury', 'NNP'), ('5', 'CD')])
Вывод
[('10', 'CD'), ('January', 'NNP')]
10 January