systemy_dialogowe/data/parsing_semantyczny.ipynb

9.4 KiB

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

grammar book;

public <rezerwuj> = chcialbym zarezerwowac stolik <dzien_rezerwacji> <godzina_rezerwacji> <liczba_osob> ;

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

<dzien> = dzisiaj | jutro | poniedzialek | wtorek | srode | czwartek | piatek | sobote | niedziele;

<godzina_rezerwacji> = na [godzine] <godzina_z_minutami> {hour};

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

<godzina> = dziewiata | dziesiata | jedenasta | dwunasta;

<minuty> = pietnascie | trzydziesci;

<liczba_osob> = (na | dla) <liczba> {size} osob;

<liczba> = dwie | dwoch | trzy | trzech | cztery | czterech | piec | pieciu;
Overwriting book.jsgf
%%writefile order.jsgf
#JSGF V1.0 UTF-8 pl;

grammar order;

public <zamow> = (chcialbym | chcialabym)  zamowic <danie> <stolik>;

<danie> = <potrawa> {dish};

<potrawa> = pizza peperoni | spaghetti carbonara | burger szefa;

<stolik> = (do stolika | na stolik ) <numer_stolika> {stolik};

<numer_stolika> = 100 | 101 | 102 | 103 | 104 | 105;
Overwriting order.jsgf
%%writefile recommend.jsgf
#JSGF V1.0 UTF-8 pl;

grammar recommend;

public <polec_ogolny> = (jakie|jaki|jaka|jakiego) <jedzenie_napoj> polecasz;

<jedzenie_napoj> = <jedzenie_napoj_opcje> {food_or_drink};

<jedzenie_napoj_opcje> = jedzenia | picia | napoj | danie | dania;

public <polec_danie> = ((jakie|jaki|jaka|jakiego)  <danie>) *;

public <polec_napoj> = ((jakie|jaki|jaka|jakiego)  <napoj>) *;

<danie> = <dania> {dish};

<dania> = makarony | makaron | pizze | pizza | burgery | burger | salatki | salatka | deser | desery;

<napoj> = <napoje> {drink};

<napoje> = piwo | piwa | wino | wina | sok | soki | smoothie | kawe | kawy | kawe | herbate | herbata | herbaty;
Overwriting recommend.jsgf
import jsgf

book_grammar = jsgf.parse_grammar_file('book.jsgf')
order_grammar = jsgf.parse_grammar_file('order.jsgf')
recommend_grammar = jsgf.parse_grammar_file('recommend.jsgf')
order_grammar
Grammar(version=1.0, charset=UTF-8, language=pl, name=order)
utterance = 'chcialbym zarezerwowac stolik na jutro na godzine dwunasta trzydziesci na piec osob'
matched = book_grammar.find_matching_rules(utterance)
if not matched:
    matched = order_grammar.find_matching_rules(utterance)
if not matched:
    matched = recommend_grammar.find_matching_rules(utterance)
matched
[Rule(name='rezerwuj', visible=True, expansion=Sequence(Literal('chcialbym zarezerwowac stolik'), NamedRuleRef('dzien_rezerwacji'), NamedRuleRef('godzina_rezerwacji'), NamedRuleRef('liczba_osob')))]
utterance = 'chcialbym zamowic burger szefa do stolika 104'
matched = book_grammar.find_matching_rules(utterance)
if not matched:
    matched = order_grammar.find_matching_rules(utterance)
if not matched:
    matched = recommend_grammar.find_matching_rules(utterance)
matched
[Rule(name='zamow', visible=True, expansion=Sequence(ParsedAlternativeSet(Literal('chcialbym'), Literal('chcialabym')), Literal('zamowic'), NamedRuleRef('danie'), NamedRuleRef('stolik')))]
utterance = 'jakie makarony polecasz'
matched = book_grammar.find_matching_rules(utterance)
if not matched:
    matched = order_grammar.find_matching_rules(utterance)
if not matched:
    matched = recommend_grammar.find_matching_rules(utterance)
matched
[Rule(name='polec_danie', visible=True, expansion=KleeneStar(RequiredGrouping(Sequence(RequiredGrouping(ParsedAlternativeSet(Literal('jakie'), Literal('jaki'), Literal('jaka'), Literal('jakiego'))), NamedRuleRef('danie'))))),
 Rule(name='polec_napoj', visible=True, expansion=KleeneStar(RequiredGrouping(Sequence(RequiredGrouping(ParsedAlternativeSet(Literal('jakie'), Literal('jaki'), Literal('jaka'), Literal('jakiego'))), NamedRuleRef('napoj')))))]
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': 'recommend', 'slots': [('dish', 'makarony')]}
def nlu(utterance):
    matched = book_grammar.find_matching_rules(utterance)
    if not matched:
        matched = order_grammar.find_matching_rules(utterance)
    if not matched:
        matched = recommend_grammar.find_matching_rules(utterance)

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

nlu('chcialbym zarezerwowac stolik na jutro na godzine dziesiata dla trzech osob')
{'act': 'book',
 'slots': [('day', 'jutro'), ('hour', 'dziesiata'), ('size', 'trzech')]}
nlu('jakie makarony polecasz')
{'act': 'recommend', 'slots': [('dish', 'makarony')]}