SystemyDialogowe/AJN.ipynb

8.8 KiB

Logo 1

Systemy Dialogowe

7. Parsing semantyczny z wykorzystaniem gramatyk [laboratoria]

Marek Kubis (2021)

Logo 2

Parsing semantyczny z wykorzystaniem gramatyk

Wartości slotów możemy wydobywać z wypowiedzi użytkownika korzystając z takich technik, jak:

  • wyszukiwanie słów kluczowych w tekście,

  • dopasowywanie wzorców zbudowanych przy użyciu wyrażeń regularnych,

  • parsery regułowe (temat dzisiejszych zajęć),

  • uczenie maszynowe (temat kolejnych zajęć).

Przykłady parserów regułowych

Przykład

Zapiszmy w JSGF gramatykę semantyczną dla aktu dialogowego reprezentującego zamiar rezerwacji stolika w restauracji.

%%writefile book.jsgf
#JSGF V1.0 UTF-8 pl;

grammar book;

public <rezerwuj> = chciałbym zarezerwować <ilosc_biletow> <tytul_filmu> [<dzien_rezerwacji>] [<godzina_rezerwacji>];

<ilosc_biletow> = <liczba> {ilosc} (bilety | biletów);

<liczba> = dwa | trzy | cztery |1|2|3|4|5|6;

<tytul_filmu> = na [film] <tytul> {tytul};

<tytul> = Batman | Uncharted | Pitbull;

<dzien_rezerwacji> = na <dzien> {dzien};

<dzien> = dzisiaj | jutro | poniedziałek | wtorek | środę | czwartek | piątek | sobotę | niedzielę;

<godzina_rezerwacji> = na [godzinę] <godzina_z_minutami> {godzina};

<godzina_z_minutami> = <godzina> [<minuty>];

<godzina> = dziewiątą | dziesiątą | jedenastą | dwunastą;

<minuty> = pietnaście | trzydzieści;
Overwriting book.jsgf

Parser akceptujący powyższą gramatykę utworzymy korzystając z biblioteki pyjsgf.

import jsgf

book_grammar = jsgf.parse_grammar_file('book.jsgf')
book_grammar
Grammar(version=1.0, charset=UTF-8, language=pl, name=book)

Wykorzystajmy gramatykę book.jsgf do analizy następującej wypowiedzi

utterance = 'chciałbym zarezerwować 1 biletów na film Pitbull'
matched = book_grammar.find_matching_rules(utterance)
matched
[Rule(name='rezerwuj', visible=True, expansion=Sequence(Literal('chciałbym zarezerwować'), NamedRuleRef('ilosc_biletow'), NamedRuleRef('tytul_filmu'), OptionalGrouping(NamedRuleRef('dzien_rezerwacji')), OptionalGrouping(NamedRuleRef('godzina_rezerwacji'))))]

Reprezentację znaczenia można wydobyć ze sparsowanej wypowiedzi na wiele sposobów. My do wydobywania slotów wykorzystamy mechanizm tagów JSGF a za nazwę aktu dialogowego przyjmiemy nazwę gramatyki. Wzorując się na DSTC2 wynikową ramę zapiszemy korzystając ze słownika o polach act i slots.

def get_dialog_act(rule):
    slots = []
    get_slots(rule.expansion, slots)
    return {'act': rule.grammar.name, 'slots': slots}

def get_slots(expansion, slots):
    if expansion.tag != '':
        slots.append((expansion.tag, expansion.current_match))
        return

    for child in expansion.children:
        get_slots(child, slots)

    if not expansion.children and isinstance(expansion, jsgf.NamedRuleRef):
        get_slots(expansion.referenced_rule.expansion, slots)

get_dialog_act(matched[0])
{'act': 'book',
 'slots': [('ilosc', '1'),
  ('tytul', 'Pitbull'),
  ('dzien', None),
  ('godzina', None)]}

Łącząc powyższe funkcje możemy zbudować prosty moduł NLU.

def nlu(utterance):
    matched = book_grammar.find_matching_rules(utterance)

    if matched:
        return get_dialog_act(matched[0])
    else:
        return {'act': 'null', 'slots': []}

nlu('chciałbym zarezerwować dwa bilety na film Pitbull')
{'act': 'null', 'slots': []}

Problemy

  • Co z normalizacją wyrażeń liczbowych takich, jak godziny, daty czy numery telefonów?

  • Co w przypadku gdy więcej niż jedna reguła zostanie dopasowana?

Zadanie

Zaimplementować analizator języka naturalnego (NLU) na potrzeby realizowanego agenta dialogowego.

Moduł powinien być zbudowany z wykorzystaniem parsingu regułowego i/lub technik uczenia maszynowego.

Przygotować skrypt evaluate.py wyznaczający _dokładność (ang. accuracy) analizatora względem zgromadzonego korpusu eksperymentalnego, tj. stosunek liczby wypowiedzi użytkownika, w których akty dialogowe zostały rozpoznane prawidłowo do liczby wszystkich wypowiedzi użytkownika w korpusie.

Analizator języka naturalnego umieścić w gałęzi master repozytorium projektowego. Skrypt evaluate.py umieścić w katalogu głównym tej gałęzi.

Termin: 4.05.2022, godz. 23:59.