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