Набор инструментов для естественного языка - преобразование фрагментов

Зачем преобразовывать чанки?

До сих пор у нас есть отрывки или фразы из предложений, но что нам с ними делать? Одна из важных задач - их преобразовать. Но почему? Это сделать следующее -

  • грамматическая коррекция и
  • перестановка фраз

Фильтрация несущественных / бесполезных слов

Предположим, что если вы хотите оценить значение фразы, то есть много часто используемых слов, таких как «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