Zestaw narzędzi języka naturalnego - przekształcanie fragmentów

Po co przekształcać kawałki?

Do tej pory mamy fragmenty lub frazy ze zdań, ale co mamy z nimi zrobić. Jednym z ważnych zadań jest ich przekształcenie. Ale dlaczego? Ma to na celu:

  • poprawka gramatyczna i
  • przestawianie fraz

Filtrowanie nieistotnych / bezużytecznych słów

Załóżmy, że jeśli chcesz ocenić znaczenie frazy, istnieje wiele powszechnie używanych słów, takich jak „the”, „a”, które są nieistotne lub bezużyteczne. Na przykład zobacz następującą frazę -

'Film był dobry'.

Tutaj najważniejsze słowa to „film” i „dobry”. Innymi słowy, „to” i „było” są bezużyteczne lub nieistotne. To dlatego, że bez nich również możemy uzyskać to samo znaczenie tego wyrażenia. 'Dobry film'.

Z poniższego przepisu na Pythona dowiemy się, jak usuwać niepotrzebne / nieistotne słowa i zachować znaczące słowa za pomocą tagów POS.

Przykład

Po pierwsze, przeglądając treebankkorpusu odrzucanych słów musimy zdecydować, które znaczniki części mowy są istotne, a które nie. Spójrzmy na poniższą tabelę nieistotnych słów i tagów -

Słowo Etykietka
za DT
Wszystko PDT
Na DT
I CC
Lub CC
Że WDT
Plik DT

Z powyższej tabeli widzimy inne niż CC, wszystkie pozostałe tagi kończą się na DT, co oznacza, że ​​możemy odfiltrować nieistotne słowa, patrząc na sufiks tagu.

W tym przykładzie użyjemy funkcji o nazwie filter()która pobiera pojedynczy fragment i zwraca nowy fragment bez żadnych nieznaczących oznaczonych słów. Ta funkcja odfiltrowuje wszystkie tagi, które kończą się na DT lub CC.

Przykład

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)

Teraz użyjmy tej funkcji filter () w naszym przepisie w Pythonie, aby usunąć nieistotne słowa -

from chunk_parse import filter
filter([('the', 'DT'),('good', 'JJ'),('movie', 'NN')])

Wynik

[('good', 'JJ'), ('movie', 'NN')]

Korekta czasownika

Wiele razy w prawdziwym języku widzimy nieprawidłowe formy czasowników. Na przykład „wszystko w porządku?” nie jest poprawne. Forma czasownika nie jest poprawna w tym zdaniu. Zdanie powinno brzmieć „wszystko w porządku?” NLTK zapewnia nam sposób na poprawienie takich błędów poprzez tworzenie odwzorowań korekcji czasowników. Te odwzorowania korekcji są używane w zależności od tego, czy w porcji znajduje się rzeczownik w liczbie mnogiej czy pojedynczej.

Przykład

Aby zaimplementować przepis w Pythonie, musimy najpierw zdefiniować odwzorowania korekcji czasowników. Utwórzmy dwa odwzorowania w następujący sposób -

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')
}

Jak widać powyżej, każde odwzorowanie ma oznaczony czasownik, który odwzorowuje inny oznaczony czasownik. Początkowe mapowania w naszym przykładzie obejmują podstawy mapowaniais to are, was to were, i wzajemnie.

Następnie zdefiniujemy funkcję o nazwie verbs(), w którym można przekazać szczelinę z nieprawidłową formą czasownika i otrzymać z powrotem poprawiony fragment. Aby to zrobić,verb() funkcja używa funkcji pomocniczej o nazwie index_chunk() który przeszuka porcję pod kątem pozycji pierwszego słowa ze znacznikiem.

Zobaczmy te funkcje -

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

Zapisz te funkcje w pliku Pythona w katalogu lokalnym, w którym jest zainstalowany Python lub Anaconda, i uruchom go. Zapisałem to jakoverbcorrect.py.

A teraz zadzwońmy verbs() funkcja w oznaczonym punkcie sprzedaży is you fine kawałek -

from verbcorrect import verbs
verbs([('is', 'VBZ'), ('you', 'PRP$'), ('fine', 'VBG')])

Wynik

[('are', 'VBP'), ('you', 'PRP$'), ('fine','VBG')]

Eliminacja biernego głosu ze zwrotów

Kolejnym przydatnym zadaniem jest wyeliminowanie biernego głosu ze zwrotów. Można to zrobić za pomocą zamiany słów wokół czasownika. Na przykład,‘the tutorial was great’ można przekształcić w ‘the great tutorial’.

Przykład

Aby to osiągnąć, definiujemy funkcję o nazwie eliminate_passive()która zamieni prawą stronę fragmentu na lewą, używając czasownika jako punktu obrotu. Aby znaleźć czasownik do obrócenia, użyje równieżindex_chunk() funkcja zdefiniowana powyżej.

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]

A teraz zadzwońmy eliminate_passive() funkcja w oznaczonym punkcie sprzedaży the tutorial was great kawałek -

from passiveverb import eliminate_passive
eliminate_passive(
   [
      ('the', 'DT'), ('tutorial', 'NN'), ('was', 'VBD'), ('great', 'JJ')
   ]
)

Wynik

[('great', 'JJ'), ('the', 'DT'), ('tutorial', 'NN')]

Zamiana rzeczowników kardynałów

Jak wiemy, słowo kardynalne, takie jak 5, jest oznaczone jako CD w kawałku. Te kardynalne słowa często występują przed rzeczownikiem lub po nim, ale w celu normalizacji dobrze jest umieszczać je zawsze przed rzeczownikiem. Na przykład dataJanuary 5 można zapisać jako 5 January. Zrozummy to na następującym przykładzie.

Przykład

Aby to osiągnąć, definiujemy funkcję o nazwie swapping_cardinals()który zamieni każdy kardynał występujący bezpośrednio po rzeczowniku na rzeczownik. Dzięki temu kardynał wystąpi bezpośrednio przed rzeczownikiem. W celu porównania równości z danym znacznikiem używa funkcji pomocniczej, którą nazwaliśmy jakotag_eql().

def tag_eql(tag):
   def f(wt):
      return wt[1] == tag
   return f

Teraz możemy zdefiniować 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

A teraz zadzwońmy swapping_cardinals() funkcjonować na randce “January 5” -

from Cardinals import swapping_cardinals()
swapping_cardinals([('Janaury', 'NNP'), ('5', 'CD')])

Wynik

[('10', 'CD'), ('January', 'NNP')]
10 January