From 09abd92605620a91412d9bb884ef3d7545828ff0 Mon Sep 17 00:00:00 2001 From: s464961 Date: Tue, 7 May 2024 16:09:18 +0200 Subject: [PATCH 1/3] tmp --- data/02-01-01.tsv | 2 +- data/05-02-10.tsv | 2 +- grammars/request.jsgf | 21 +++++++++++++++++++++ grammars/welcomemsg.jsgf | 6 ++++++ 4 files changed, 29 insertions(+), 2 deletions(-) create mode 100644 grammars/request.jsgf create mode 100644 grammars/welcomemsg.jsgf diff --git a/data/02-01-01.tsv b/data/02-01-01.tsv index b334395..989e7a5 100644 --- a/data/02-01-01.tsv +++ b/data/02-01-01.tsv @@ -1,5 +1,5 @@ system Witamy w sklepie internetowym XYZ. W czym mogę pomóc? welcomemsg() -user Potrzbuje nowego biurka, czy jest cos specjalnego w ofercie, oczekuje biurka 3 metry na 1 metr request(items=biurka, size=3m x 1m) +user Potrzebuje nowego biurka, czy jest cos specjalnego w ofercie, oczekuje biurka 3 metry na 1 metr request(items=biurka, size=3m x 1m) system Obecne modele biurek o długości 3m: Biurko WMI 3m x 1m; Biurko ABCD 3m x 70cm. Uprzejmie informujemy, iż dodatkowo na promocji znajduje się obecnie biurko Ania 2.70m x 1m inform(models=[Biurko WMI 3m x 1m, Biurko ABCD 3m x 70cm])&offer(promotion=Biurko Ania 2.70m x 1m) user Z czego wykonane są te biurka i jakie są ceny request(material, price) system Biurko WMI - 2000ZL, drewno debowe premium; Biurko ABCD - 1000ZL sklejka; BIurko Ania - 900ZL z 1200ZL, metal; inform(items= {model= Biurko WMI, material=drewno debowe premium, price=2000ZL}, {model=Biurko ABCD, material=sklejka, price=1000ZL}, {model=Biurko Ania, material=metal, price=900ZL (z 1200ZL)}) diff --git a/data/05-02-10.tsv b/data/05-02-10.tsv index 6ea1174..e9f06ef 100644 --- a/data/05-02-10.tsv +++ b/data/05-02-10.tsv @@ -3,7 +3,7 @@ system Witam tutaj sklep wielobranzowy, w czym moge pomoc? user szukam kija, takiego do otwierania drzwi, czy mają Państwo coś takiego na stanie? system Niestety nie posiadamy kija w swojej ofercie, moge Panu zaproponowac miotłe user Tylko musi być metalowa, jest taka? -system Tak, posiadamy metalowe miotly w swojej ofercie, proponuje 1,5 metrową mitłe SUPER MAX (aktualnie jest w promocji do wyczerpania zapasów) +system Tak, posiadamy metalowe miotly w swojej ofercie, proponuje 1,5 metrową miotłe SUPER MAX (aktualnie jest w promocji do wyczerpania zapasów) user To poproszę jedną taką miotłę. user Macie może młotki? system ok, miotla zostala dodana do koszyka diff --git a/grammars/request.jsgf b/grammars/request.jsgf new file mode 100644 index 0000000..4e7997d --- /dev/null +++ b/grammars/request.jsgf @@ -0,0 +1,21 @@ +#JSGF V1.0 UTF-8 pl; + +grammar request; + +public = ; + + = (Cześć, | hej) chciałbym złożyć zamówienie na ( | ) | (chciałbym | chce) kupić ( | ) | ( | ) też mogą być? ; + + = narzędzia | meble ogrodowe | artykuły spożywcze | kosmetyki {category}; + + = lakiery do paznokci | perfumy; + + = młotek | miotła; + + = leżaki ogrodowe | parasole | donice | tuje; + + = mleko | jajka | cebula | czosnek | szpinak | marchewka; + +public = [] ( | | | ) {items}; + + = jedno | dwie | trzy | cztery | pięć | sześć | siedem | osiem | dziewięć | dziesięć; diff --git a/grammars/welcomemsg.jsgf b/grammars/welcomemsg.jsgf new file mode 100644 index 0000000..f7e06e2 --- /dev/null +++ b/grammars/welcomemsg.jsgf @@ -0,0 +1,6 @@ +#JSGF V1.0 UTF-8 pl; + +grammar welcomemsg; + +public = ; + = Witamy w sklepie internetowym XYZ. W czym mogę pomóc? | Witaj! W czym mogę Ci dzisiaj pomóc?| Witamy w sklepie internetowym XYZ. W swojej ofercie mamy artykuły ogrodowe, meblowe oraz kosmetyki. | Witam tutaj sklep wielobranzowy, w czym moge pomoc?; \ No newline at end of file From 43b80ffa36e598a11e09dcb2f4e2dc912370a7a7 Mon Sep 17 00:00:00 2001 From: s464961 Date: Tue, 7 May 2024 18:19:32 +0200 Subject: [PATCH 2/3] grammars --- grammars/affirm.jsgf | 7 +++++++ grammars/bye.jsgf | 7 +++++++ grammars/inform.jsgf | 26 ++++++++++++++++++++++++++ grammars/request.jsgf | 32 ++++++++++++++++++++------------ grammars/welcomemsg.jsgf | 2 +- main.py | 8 +++++++- 6 files changed, 68 insertions(+), 14 deletions(-) create mode 100644 grammars/affirm.jsgf create mode 100644 grammars/bye.jsgf create mode 100644 grammars/inform.jsgf diff --git a/grammars/affirm.jsgf b/grammars/affirm.jsgf new file mode 100644 index 0000000..7109a0b --- /dev/null +++ b/grammars/affirm.jsgf @@ -0,0 +1,7 @@ +#JSGF V1.0 UTF-8 pl; + +grammar affirm; + +public = ; + + = Tak zdecydowanie | Tak | Tak to brzmi świetnie | Potwierdzam; diff --git a/grammars/bye.jsgf b/grammars/bye.jsgf new file mode 100644 index 0000000..c7c88f3 --- /dev/null +++ b/grammars/bye.jsgf @@ -0,0 +1,7 @@ +#JSGF V1.0 UTF-8 pl; + +grammar bye; + +public = ; + + = Do widzenia | (Nie | Tak) to wszystko Dziękuję | Dziękujemy za zakupy Miłego dnia | Dziekujemy za zakupy w sklepie XYZ Milego dnia | Dziękuję Życzę miłego dnia | To wszystko; diff --git a/grammars/inform.jsgf b/grammars/inform.jsgf new file mode 100644 index 0000000..99af9db --- /dev/null +++ b/grammars/inform.jsgf @@ -0,0 +1,26 @@ +#JSGF V1.0 UTF-8 pl; + +grammar inform; + +public = Jaka jest cena produktu {produkt}*; +public = Jaki jest adres dostawy; +public = Jakie są dostępne metody płatności; + +public = dostępne | niedostępne; + +public = Cena produktu {produkt}* wynosi *; +public = Adres dostawy to ; +public = Dostępne metody płatności to *; + +public = zł; +public = jeden | dwie | trzy | cztery | pięć | sześć | siedem | osiem | dziewięć | dziesięć; + +public = ulica miasto kod pocztowy ; +public = ul. ; +public = ; +public = -; + +public = XYZ; +public = XYZ; +public = 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 0; +public = karta kredytowa | przelew bankowy | płatność przy odbiorze; diff --git a/grammars/request.jsgf b/grammars/request.jsgf index 4e7997d..ba0fac9 100644 --- a/grammars/request.jsgf +++ b/grammars/request.jsgf @@ -2,20 +2,28 @@ grammar request; -public = ; +public = kosmetyki | leżaki ogrodowe | artykuły spożywcze; - = (Cześć, | hej) chciałbym złożyć zamówienie na ( | ) | (chciałbym | chce) kupić ( | ) | ( | ) też mogą być? ; +public = szminka | krem do twarzy | szampon | balsam do ciała | maskara | leżak plażowy | leżak ogrodowy | parasol ogrodowy | grill | owoce | warzywa | mleko | jajka | pieczywo | ryby | mięso | woda mineralna | przekąski; - = narzędzia | meble ogrodowe | artykuły spożywcze | kosmetyki {category}; +public = Czy macie w ofercie {produkt}*; +public = Interesuje mnie zakup {produkt}*; +public = Interesuje mnie zakup {produkt} {kategorie}*; +public = Chciałbym kupić {produkt}*; +public = Chciałbym kupić {produkt} {kategorie}*; +public = Chciałabym kupić {produkt}*; +public = Chciałabym kupić {produkt} {kategorie}*; +public = Czy w sklepie dostępne są {produkt}*; +public = Czy w sklepie dostępne są {produkt} {kategorie}*; - = lakiery do paznokci | perfumy; +public = dostępne | niedostępne; - = młotek | miotła; +public = Tak mamy {produkt}*; +public = Tak mamy {produkt} {kategorie}*; +public = Niestety aktualnie nie mamy {produkt}*; +public = Niestety aktualnie nie mamy {produkt} {kategorie}*; - = leżaki ogrodowe | parasole | donice | tuje; - - = mleko | jajka | cebula | czosnek | szpinak | marchewka; - -public = [] ( | | | ) {items}; - - = jedno | dwie | trzy | cztery | pięć | sześć | siedem | osiem | dziewięć | dziesięć; +public = Tak w sklepie są {produkt}*; +public = Tak w sklepie są {produkt} {kategorie}*; +public = Niestety aktualnie nie ma {produkt}*; +public = Niestety aktualnie nie ma {produkt} {kategorie}*; diff --git a/grammars/welcomemsg.jsgf b/grammars/welcomemsg.jsgf index f7e06e2..e4e326d 100644 --- a/grammars/welcomemsg.jsgf +++ b/grammars/welcomemsg.jsgf @@ -3,4 +3,4 @@ grammar welcomemsg; public = ; - = Witamy w sklepie internetowym XYZ. W czym mogę pomóc? | Witaj! W czym mogę Ci dzisiaj pomóc?| Witamy w sklepie internetowym XYZ. W swojej ofercie mamy artykuły ogrodowe, meblowe oraz kosmetyki. | Witam tutaj sklep wielobranzowy, w czym moge pomoc?; \ No newline at end of file + = Witamy w sklepie internetowym XYZ W czym mogę pomóc | Witaj! W czym mogę Ci dzisiaj pomóc| Witamy w sklepie internetowym XYZ W swojej ofercie mamy artykuły ogrodowe meblowe oraz kosmetyki | Witam tutaj sklep wielobranzowy w czym moge pomoc; \ No newline at end of file diff --git a/main.py b/main.py index a53c62e..912c37d 100644 --- a/main.py +++ b/main.py @@ -1,5 +1,11 @@ +import jsgf + +request_grammar = jsgf.parse_grammar_file('./grammars/request.jsgf') + def main(): - pass + utterance = 'Czy macie w ofercie balsam do ciała' + matched = request_grammar.find_matching_rules(utterance) + print(matched) if __name__ == '__main__': From 6acdea331016c9542ec217ba8075a1074910b167 Mon Sep 17 00:00:00 2001 From: s464961 Date: Tue, 7 May 2024 19:25:33 +0200 Subject: [PATCH 3/3] evaluation --- chatbot/modules/nlu.py | 42 ++++++++++++++++++++++++++++++++++++++++ evaluate.py | 26 +++++++++++++++++++++++++ grammars/inform.jsgf | 2 +- grammars/welcomemsg.jsgf | 2 +- main.py | 1 + 5 files changed, 71 insertions(+), 2 deletions(-) create mode 100644 chatbot/modules/nlu.py create mode 100644 evaluate.py diff --git a/chatbot/modules/nlu.py b/chatbot/modules/nlu.py new file mode 100644 index 0000000..6e387ba --- /dev/null +++ b/chatbot/modules/nlu.py @@ -0,0 +1,42 @@ +import copy +from copy import deepcopy +import json +import os +import jsgf + + +class NLU: + def __init__(self): + self.grammars = [ + jsgf.parse_grammar_file(f"grammars/{file_name}") + for file_name in os.listdir("grammars") + ] + + def get_dialog_act(self, rule): + slots = [] + self.get_slots(rule.expansion, slots) + return {"act": rule.grammar.name, "slots": slots} + + def get_slots(self, expansion, slots): + if expansion.tag != "": + slots.append((expansion.tag, expansion.current_match)) + return + + for child in expansion.children: + self.get_slots(child, slots) + + if not expansion.children and isinstance(expansion, jsgf.NamedRuleRef): + self.get_slots(expansion.referenced_rule.expansion, slots) + + def match(self, utterance): + list_of_illegal_character = [",", ".", "'", "?", "!", ":", "-", "/"] + for illegal_character in list_of_illegal_character[:-2]: + utterance = utterance.replace(f"{illegal_character}", "") + for illegal_character in list_of_illegal_character[-2:]: + utterance = utterance.replace(f"{illegal_character}", " ") + + for grammar in self.grammars: + matched = grammar.find_matching_rules(utterance.lower()) + if matched: + return self.get_dialog_act(matched[0]) + return {"act": "null", "slots": []} diff --git a/evaluate.py b/evaluate.py new file mode 100644 index 0000000..e53292c --- /dev/null +++ b/evaluate.py @@ -0,0 +1,26 @@ +import os +import re +import pandas as pd +import numpy as np +from chatbot.modules.nlu import NLU + +rows = 0 +hits = 0 + +nlu = NLU() + +for file_name in os.listdir("data"): + df = pd.read_csv(f"data/{file_name}", sep="\t", names=["user", "sentence", "acts"]) + df = df[df.user == "user"] + data = np.array(df) + + for row in data: + rows += 1 + sentence = row[1] + cleaned_text = re.sub(r'\([^)]*\)', '', row[2]) + user_acts = cleaned_text.split("&") + nlu_match = nlu.match(sentence) + if nlu_match["act"] in user_acts: + hits += 1 + +print(f"Accuracy: {(hits / rows) * 100}") diff --git a/grammars/inform.jsgf b/grammars/inform.jsgf index 99af9db..68bc7c6 100644 --- a/grammars/inform.jsgf +++ b/grammars/inform.jsgf @@ -16,7 +16,7 @@ public = zł; public = jeden | dwie | trzy | cztery | pięć | sześć | siedem | osiem | dziewięć | dziesięć; public = ulica miasto kod pocztowy ; -public = ul. ; +public = ul ; public = ; public = -; diff --git a/grammars/welcomemsg.jsgf b/grammars/welcomemsg.jsgf index e4e326d..063f7b8 100644 --- a/grammars/welcomemsg.jsgf +++ b/grammars/welcomemsg.jsgf @@ -3,4 +3,4 @@ grammar welcomemsg; public = ; - = Witamy w sklepie internetowym XYZ W czym mogę pomóc | Witaj! W czym mogę Ci dzisiaj pomóc| Witamy w sklepie internetowym XYZ W swojej ofercie mamy artykuły ogrodowe meblowe oraz kosmetyki | Witam tutaj sklep wielobranzowy w czym moge pomoc; \ No newline at end of file + = Witamy w sklepie internetowym XYZ W czym mogę pomóc | Witaj W czym mogę Ci dzisiaj pomóc | Witamy w sklepie internetowym XYZ W swojej ofercie mamy artykuły ogrodowe meblowe oraz kosmetyki | Witam tutaj sklep wielobranzowy w czym moge pomoc | cześć chciałbym kupić {product}; \ No newline at end of file diff --git a/main.py b/main.py index 912c37d..9dc34fe 100644 --- a/main.py +++ b/main.py @@ -2,6 +2,7 @@ import jsgf request_grammar = jsgf.parse_grammar_file('./grammars/request.jsgf') + def main(): utterance = 'Czy macie w ofercie balsam do ciała' matched = request_grammar.find_matching_rules(utterance)