diff --git a/.ipynb_checkpoints/AJN-checkpoint.ipynb b/.ipynb_checkpoints/AJN-checkpoint.ipynb new file mode 100644 index 0000000..8f87484 --- /dev/null +++ b/.ipynb_checkpoints/AJN-checkpoint.ipynb @@ -0,0 +1,303 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "![Logo 1](https://git.wmi.amu.edu.pl/AITech/Szablon/raw/branch/master/Logotyp_AITech1.jpg)\n", + "
\n", + "

Systemy Dialogowe

\n", + "

7. Parsing semantyczny z wykorzystaniem gramatyk [laboratoria]

\n", + "

Marek Kubis (2021)

\n", + "
\n", + "\n", + "![Logo 2](https://git.wmi.amu.edu.pl/AITech/Szablon/raw/branch/master/Logotyp_AITech2.jpg)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Parsing semantyczny z wykorzystaniem gramatyk\n", + "=============================================\n", + "\n", + "Wartości slotów możemy wydobywać z wypowiedzi użytkownika korzystając z takich technik, jak:\n", + "\n", + " - wyszukiwanie słów kluczowych w tekście,\n", + "\n", + " - dopasowywanie wzorców zbudowanych przy użyciu wyrażeń regularnych,\n", + "\n", + " - parsery regułowe (temat dzisiejszych zajęć),\n", + "\n", + " - uczenie maszynowe (temat kolejnych zajęć)." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Przykłady parserów regułowych\n", + "-----------------------------\n", + "\n", + " - [Phoenix](http://wiki.speech.cs.cmu.edu/olympus/index.php/Phoenix_Server) — parser gramatyk\n", + " bezkontekstowych whodzący w skład systemu dialogowego [Olympus](http://wiki.speech.cs.cmu.edu/olympus/index.php/Olympus)\n", + "\n", + " - Parsery [DCG](https://www.swi-prolog.org/pldoc/man?section=DCG) (Definite Clause Grammars) języka [Prolog](https://www.swi-prolog.org/)\n", + "\n", + " - [JSpeech Grammar Format](https://www.w3.org/TR/jsgf/) (JSGF)\n", + "\n", + "Przykład\n", + "--------\n", + "Zapiszmy w JSGF gramatykę semantyczną dla aktu dialogowego reprezentującego zamiar rezerwacji\n", + "stolika w restauracji." + ] + }, + { + "cell_type": "code", + "execution_count": 51, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Overwriting book.jsgf\n" + ] + } + ], + "source": [ + "%%writefile book.jsgf\n", + "#JSGF V1.0 UTF-8 pl;\n", + "\n", + "grammar book;\n", + "\n", + "public = chciałbym zarezerwować [] [];\n", + "\n", + " = {ilosc} (bilety | biletów);\n", + "\n", + " = dwa | trzy | cztery |1|2|3|4|5|6;\n", + "\n", + " = na [film] {tytul};\n", + "\n", + " = Batman | Uncharted | Pitbull;\n", + "\n", + " = na {dzien};\n", + "\n", + " = dzisiaj | jutro | poniedziałek | wtorek | środę | czwartek | piątek | sobotę | niedzielę;\n", + "\n", + " = na [godzinę] {godzina};\n", + "\n", + " = [];\n", + "\n", + " = dziewiątą | dziesiątą | jedenastą | dwunastą;\n", + "\n", + " = pietnaście | trzydzieści;\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Parser akceptujący powyższą gramatykę utworzymy korzystając z biblioteki [pyjsgf](https://github.com/Danesprite/pyjsgf)." + ] + }, + { + "cell_type": "code", + "execution_count": 52, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "Grammar(version=1.0, charset=UTF-8, language=pl, name=book)" + ] + }, + "execution_count": 52, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "import jsgf\n", + "\n", + "book_grammar = jsgf.parse_grammar_file('book.jsgf')\n", + "book_grammar" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Wykorzystajmy gramatykę `book.jsgf` do analizy następującej wypowiedzi" + ] + }, + { + "cell_type": "code", + "execution_count": 53, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[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'))))]" + ] + }, + "execution_count": 53, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "utterance = 'chciałbym zarezerwować 1 biletów na film Pitbull'\n", + "matched = book_grammar.find_matching_rules(utterance)\n", + "matched" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Reprezentację znaczenia można wydobyć ze sparsowanej wypowiedzi na wiele sposobów. My do\n", + "wydobywania slotów wykorzystamy mechanizm tagów JSGF a za nazwę aktu dialogowego przyjmiemy nazwę\n", + "gramatyki. Wzorując się na [DSTC2](https://github.com/matthen/dstc) wynikową ramę zapiszemy korzystając ze słownika o polach `act` i `slots`." + ] + }, + { + "cell_type": "code", + "execution_count": 54, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{'act': 'book',\n", + " 'slots': [('ilosc', '1'),\n", + " ('tytul', 'Pitbull'),\n", + " ('dzien', None),\n", + " ('godzina', None)]}" + ] + }, + "execution_count": 54, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "def get_dialog_act(rule):\n", + " slots = []\n", + " get_slots(rule.expansion, slots)\n", + " return {'act': rule.grammar.name, 'slots': slots}\n", + "\n", + "def get_slots(expansion, slots):\n", + " if expansion.tag != '':\n", + " slots.append((expansion.tag, expansion.current_match))\n", + " return\n", + "\n", + " for child in expansion.children:\n", + " get_slots(child, slots)\n", + "\n", + " if not expansion.children and isinstance(expansion, jsgf.NamedRuleRef):\n", + " get_slots(expansion.referenced_rule.expansion, slots)\n", + "\n", + "get_dialog_act(matched[0])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Łącząc powyższe funkcje możemy zbudować prosty moduł NLU." + ] + }, + { + "cell_type": "code", + "execution_count": 41, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{'act': 'null', 'slots': []}" + ] + }, + "execution_count": 41, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "def nlu(utterance):\n", + " matched = book_grammar.find_matching_rules(utterance)\n", + "\n", + " if matched:\n", + " return get_dialog_act(matched[0])\n", + " else:\n", + " return {'act': 'null', 'slots': []}\n", + "\n", + "nlu('chciałbym zarezerwować dwa bilety na film Pitbull')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Problemy\n", + "--------\n", + "\n", + " - Co z normalizacją wyrażeń liczbowych takich, jak godziny, daty czy numery telefonów?\n", + "\n", + " - Co w przypadku gdy więcej niż jedna reguła zostanie dopasowana?" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Zadanie\n", + "-------\n", + "Zaimplementować analizator języka naturalnego (NLU) na potrzeby realizowanego agenta dialogowego.\n", + "\n", + "Moduł powinien być zbudowany z wykorzystaniem parsingu regułowego i/lub technik uczenia maszynowego.\n", + "\n", + "Przygotować skrypt `evaluate.py` wyznaczający *dokładność* (ang. accuracy) analizatora względem zgromadzonego korpusu eksperymentalnego,\n", + "tj. stosunek liczby wypowiedzi użytkownika, w których akty dialogowe zostały rozpoznane prawidłowo do liczby wszystkich wypowiedzi użytkownika w korpusie.\n", + "\n", + "Analizator języka naturalnego umieścić w gałęzi `master` repozytorium projektowego. Skrypt `evaluate.py` umieścić w katalogu głównym tej gałęzi.\n", + "\n", + "Termin: 4.05.2022, godz. 23:59." + ] + } + ], + "metadata": { + "author": "Marek Kubis", + "email": "mkubis@amu.edu.pl", + "jupytext": { + "cell_metadata_filter": "-all", + "main_language": "python", + "notebook_metadata_filter": "-all" + }, + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "lang": "pl", + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.7.3" + }, + "subtitle": "7.Parsing semantyczny z wykorzystaniem gramatyk[laboratoria]", + "title": "Systemy Dialogowe", + "year": "2021" + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/.ipynb_checkpoints/chatbot-checkpoint.ipynb b/.ipynb_checkpoints/chatbot-checkpoint.ipynb new file mode 100644 index 0000000..528b9a0 --- /dev/null +++ b/.ipynb_checkpoints/chatbot-checkpoint.ipynb @@ -0,0 +1,74 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 6, + "id": "978f5cd3-eb2e-45c4-ace8-f105ccd4cb74", + "metadata": {}, + "outputs": [ + { + "ename": "ModuleNotFoundError", + "evalue": "No module named 'jsgf'", + "output_type": "error", + "traceback": [ + "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[1;31mModuleNotFoundError\u001b[0m Traceback (most recent call last)", + "\u001b[1;32m~\\AppData\\Local\\Temp/ipykernel_12388/3924194050.py\u001b[0m in \u001b[0;36m\u001b[1;34m\u001b[0m\n\u001b[0;32m 1\u001b[0m \u001b[1;32mfrom\u001b[0m \u001b[0mmodules\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mDST\u001b[0m \u001b[1;32mimport\u001b[0m \u001b[0mDst\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 2\u001b[1;33m \u001b[1;32mfrom\u001b[0m \u001b[0mmodules\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mAJN\u001b[0m \u001b[1;32mimport\u001b[0m \u001b[0mAjn\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 3\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 4\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 5\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n", + "\u001b[1;32mD:\\Adi\\Szkoła\\Semestr 8\\Systemy dialogowe\\Projekt\\SystemyDialogowe\\modules\\AJN.py\u001b[0m in \u001b[0;36m\u001b[1;34m\u001b[0m\n\u001b[1;32m----> 1\u001b[1;33m \u001b[1;32mimport\u001b[0m \u001b[0mjsgf\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 2\u001b[0m \u001b[1;32mfrom\u001b[0m \u001b[0mos\u001b[0m \u001b[1;32mimport\u001b[0m \u001b[0mlistdir\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 3\u001b[0m \u001b[1;32mfrom\u001b[0m \u001b[0mos\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mpath\u001b[0m \u001b[1;32mimport\u001b[0m \u001b[0misfile\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mjoin\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 4\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 5\u001b[0m \u001b[0mmypath\u001b[0m \u001b[1;33m=\u001b[0m \u001b[1;34m\"./grammar/\"\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", + "\u001b[1;31mModuleNotFoundError\u001b[0m: No module named 'jsgf'" + ] + } + ], + "source": [ + "from modules.DST import Dst\n", + "from modules.AJN import Ajn\n", + "\n", + "\n", + "\n", + "if __name__ == \"__main__\":\n", + " nlg = nlg.Nlg()\n", + " nlu = nlu.Nlu()\n", + " dst = dst.Dst()\n", + "\n", + " next_question = dst.get_next_question()\n", + " while (next_question):\n", + " print(next_question)\n", + " response = input()\n", + " res_tokenized = nlu.tokenize(response)\n", + " dst.save_answer(res_tokenized['slots'])\n", + " next_question = dst.get_next_question()\n", + "\n", + " print(dst.checklist)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "bec70f0e-c4e9-488e-8748-6d976a67beae", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.7" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/.ipynb_checkpoints/eliza-checkpoint.py b/.ipynb_checkpoints/eliza-checkpoint.py new file mode 100644 index 0000000..626ef50 --- /dev/null +++ b/.ipynb_checkpoints/eliza-checkpoint.py @@ -0,0 +1,326 @@ +from nltk.chat.util import Chat, reflections + +pairs = ( + ( + r"I need (.*)", + ( + "Why do you need %1?", + "Would it really help you to get %1?", + "Are you sure you need %1?", + ), + ), + ( + r"who created you (.*)", + ( + "ELIZA was invented in 1966 by Weizenbaum. Why %1?", + + ), + ), + ( + r"Why don\'t you (.*)", + ( + "Do you really think I don't %1?", + "Perhaps eventually I will %1.", + "Do you really want me to %1?", + ), + ), + ( + r"Why can\'t I (.*)", + ( + "Do you think you should be able to %1?", + "If you could %1, what would you do?", + "I don't know -- why can't you %1?", + "Have you really tried?", + ), + ), + ( + r"I can\'t (.*)", + ( + "How do you know you can't %1?", + "Perhaps you could %1 if you tried.", + "What would it take for you to %1?", + ), + ), + ( + r"I am (.*)", + ( + "Did you come to me because you are %1?", + "How long have you been %1?", + "How do you feel about being %1?", + ), + ), + ( + r"I\'m (.*)", + ( + "How does being %1 make you feel?", + "Do you enjoy being %1?", + "Why do you tell me you're %1?", + "Why do you think you're %1?", + ), + ), + ( + r"Are you (.*)", + ( + "Why does it matter whether I am %1?", + "Would you prefer it if I were not %1?", + "Perhaps you believe I am %1.", + "I may be %1 -- what do you think?", + ), + ), + ( + r"What (.*)", + ( + "Why do you ask?", + "How would an answer to that help you?", + "What do you think?", + ), + ), + ( + r"How (.*)", + ( + "How do you suppose?", + "Perhaps you can answer your own question.", + "What is it you're really asking?", + ), + ), + ( + r"Because (.*)", + ( + "Is that the real reason?", + "What other reasons come to mind?", + "Does that reason apply to anything else?", + "If %1, what else must be true?", + ), + ), + ( + r"(.*) sorry (.*)", + ( + "There are many times when no apology is needed.", + "What feelings do you have when you apologize?", + ), + ), + ( + r"Hello(.*)", + ( + "Hello... I'm glad you could drop by today.", + "Hi there... how are you today?", + "Hello, how are you feeling today?", + ), + ), + ( + r"I think (.*)", + ("Do you doubt %1?", "Do you really think so?", "But you're not sure %1?"), + ), + ( + r"(.*) friend (.*)", + ( + "Tell me more about your friends.", + "When you think of a friend, what comes to mind?", + "Why don't you tell me about a childhood friend?", + ), + ), + (r"Yes", ("You seem quite sure.", "OK, but can you elaborate a bit?")), + ( + r"(.*) computer(.*)", + ( + "Are you really talking about me?", + "Does it seem strange to talk to a computer?", + "How do computers make you feel?", + "Do you feel threatened by computers?", + ), + ), + ( + r"Is it (.*)", + ( + "Do you think it is %1?", + "Perhaps it's %1 -- what do you think?", + "If it were %1, what would you do?", + "It could well be that %1.", + ), + ), + ( + r"It is (.*)", + ( + "You seem very certain.", + "If I told you that it probably isn't %1, what would you feel?", + ), + ), + ( + r"Can you (.*)", + ( + "What makes you think I can't %1?", + "If I could %1, then what?", + "Why do you ask if I can %1?", + ), + ), + ( + r"Czy mogę (.*)", + ( + "Być może nie chcesz %1.", + "Czy chcesz mieć możliwość %1?", + "Gdybyś mógł %1, czy byś?", + ), + ), + ( + r"Ty jesteś (.*)", + ( + "Jak myślisz, dlaczego jestem %1?", + "Czy cieszy cię myśl, że jestem %1?", + "Być może chciałbyś, żebym był %1.", + "Może naprawdę mówisz o sobie?", + ), + ), + ( + r"Jesteś (.*)", + ( + "Dlaczego mówisz, że jestem %1?", + "Jak myślisz, dlaczego jestem %1?", + "Mówimy o tobie, czy o mnie?", + ), + ), + ( + r"Ja nie (.*)", + ("Czy naprawdę nie %1?", "Dlaczego nie %1?", "Czy chcesz %1?"), + ), + ( + r"Ja czuję (.*)", + ( + "Dobrze, powiedz mi więcej o tych uczuciach.", + "Czy często czujesz %1?", + "Kiedy zwykle czujesz %1?", + "Kiedy czujesz % 1, co robisz?", + ), + ), + ( + r"Mam (.*)", + ( + "Dlaczego mówisz mi, że masz %1?", + "Czy naprawdę masz %1?", + "Teraz, kiedy masz %1, co zrobisz dalej?", + ), + ), + ( + r"Ja chcę (.*)", + ( + "Czy możesz wyjaśnić, dlaczego chcesz %1?", + "Dlaczego %1?", + "Kto jeszcze wie, że chcesz %1?", + ), + ), + ( + r"Jest (.*)", + ( + "Myślisz, że jest %1?", + "Prawdopodobnie istnieje %1.", + "Czy chciałbyś, aby był %1?", + ), + ), + ( + r"Mój (.*)", + ( + "Rozumiem, twój %1.", + "Dlaczego mówisz, że twój %1?", + "Kiedy Twój %1, jak się czujesz?", + ), + ), + ( + r"Ty (.*)", + ( + "Powinniśmy rozmawiać o Tobie, nie o mnie.", + "Dlaczego tak o mnie mówisz?", + "Dlaczego obchodzi cię, czy ja %1?", + ), + ), + (r"Dlaczego (.*)", ("Powiedz mi dlaczego %1?", "Wydaje ci się że, %1?")), + ( + r"Ja chcę (.*)", + ( + "Co by dla ciebie znaczyło, gdybyś dostał %1?", + "Dlaczego chcesz %1?", + "Co byś zrobił, gdybyś dostał %1?", + "Jeśli masz %1, co byś zrobił?", + ), + ), + ( + r"(.*) mother(.*)", + ( + "Tell me more about your mother.", + "What was your relationship with your mother like?", + "How do you feel about your mother?", + "How does this relate to your feelings today?", + "Good family relations are important.", + ), + ), + ( + r"(.*) father(.*)", + ( + "Tell me more about your father.", + "How did your father make you feel?", + "How do you feel about your father?", + "Does your relationship with your father relate to your feelings today?", + "Do you have trouble showing affection with your family?", + ), + ), + ( + r"(.*) child(.*)", + ( + "Did you have close friends as a child?", + "What is your favorite childhood memory?", + "Do you remember any dreams or nightmares from childhood?", + "Did the other children sometimes tease you?", + "How do you think your childhood experiences relate to your feelings today?", + ), + ), + ( + r"(.*)\?", + ( + "Why do you ask that?", + "Please consider whether you can answer your own question.", + "Perhaps the answer lies within yourself?", + "Why don't you tell me?", + ), + ), + ( + r"quit", + ( + "Thank you for talking with me.", + "Good-bye.", + "Thank you, that will be $150. Have a good day!", + ), + ), + ( + r"(.*)", + ( + "Please tell me more.", + "Let's change focus a bit... Tell me about your family.", + "Can you elaborate on that?", + "Why do you say that %1?", + "I see.", + "Very interesting.", + "%1.", + "I see. And what does that tell you?", + "How does that make you feel?", + "How do you feel when you say that?", + ), + ), +) + +eliza_chatbot = Chat(pairs, reflections) + + +def eliza_chat(): + print("Psychiatrist\n---------") + print("Talk to the program by typing in plain English, using normal upper-") + print('and lower-case letters and punctuation. Enter "quit" when done.') + print("=" * 72) + print("Hello. My name is Eliza.\nHow are you feeling today?") + + eliza_chatbot.converse() + + +def demo(): + eliza_chat() + + +if __name__ == "__main__": + demo() diff --git a/AJN.ipynb b/AJN.ipynb index 8f87484..f13c471 100644 --- a/AJN.ipynb +++ b/AJN.ipynb @@ -277,7 +277,7 @@ "notebook_metadata_filter": "-all" }, "kernelspec": { - "display_name": "Python 3", + "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" }, @@ -292,7 +292,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.7.3" + "version": "3.7.13" }, "subtitle": "7.Parsing semantyczny z wykorzystaniem gramatyk[laboratoria]", "title": "Systemy Dialogowe", diff --git a/chatbot.ipynb b/chatbot.ipynb new file mode 100644 index 0000000..ee3b22d --- /dev/null +++ b/chatbot.ipynb @@ -0,0 +1,163 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 2, + "id": "encouraging-december", + "metadata": {}, + "outputs": [ + { + "name": "stdin", + "output_type": "stream", + "text": [ + ">>> chce 2 bilety\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "tytul\n", + "{'ilosc': '2', 'tytul': None, 'dzien': None, 'godzina': None}\n", + "Na jaki film ma zostać dokonana rezerwacja?\n" + ] + }, + { + "name": "stdin", + "output_type": "stream", + "text": [ + ">>> chce na film batman\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "ilosc\n", + "{'ilosc': None, 'tytul': 'Batman', 'dzien': None, 'godzina': None}\n", + "Ile biletów ma zostać zarezerwowanych?\n" + ] + }, + { + "name": "stdin", + "output_type": "stream", + "text": [ + ">>> chce 2 bilety\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "tytul\n", + "{'ilosc': '2', 'tytul': None, 'dzien': None, 'godzina': None}\n", + "Na jaki film ma zostać dokonana rezerwacja?\n" + ] + }, + { + "name": "stdin", + "output_type": "stream", + "text": [ + ">>> chce 2 bilety na film batman\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "dzien\n", + "{'ilosc': '2', 'tytul': 'Batman', 'dzien': None, 'godzina': None}\n", + "Na który dzień ma być dokonana rezerwacja?\n" + ] + }, + { + "name": "stdin", + "output_type": "stream", + "text": [ + ">>> chce na jutro\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "ilosc\n", + "{'ilosc': None, 'tytul': None, 'dzien': 'jutro', 'godzina': None}\n", + "Ile biletów ma zostać zarezerwowanych?\n" + ] + }, + { + "ename": "KeyboardInterrupt", + "evalue": "Interrupted by user", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mKeyboardInterrupt\u001b[0m Traceback (most recent call last)", + "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[1;32m 12\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 13\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 14\u001b[0;31m \u001b[0mtext\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0minput\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'>>>'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 15\u001b[0m \u001b[0mframe\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0majn\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mtext\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 16\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m/usr/local/lib/python3.7/dist-packages/ipykernel/kernelbase.py\u001b[0m in \u001b[0;36mraw_input\u001b[0;34m(self, prompt)\u001b[0m\n\u001b[1;32m 849\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_parent_ident\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 850\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_parent_header\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 851\u001b[0;31m \u001b[0mpassword\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;32mFalse\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 852\u001b[0m )\n\u001b[1;32m 853\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m/usr/local/lib/python3.7/dist-packages/ipykernel/kernelbase.py\u001b[0m in \u001b[0;36m_input_request\u001b[0;34m(self, prompt, ident, parent, password)\u001b[0m\n\u001b[1;32m 890\u001b[0m \u001b[0;32mexcept\u001b[0m \u001b[0mKeyboardInterrupt\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 891\u001b[0m \u001b[0;31m# re-raise KeyboardInterrupt, to truncate traceback\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 892\u001b[0;31m \u001b[0;32mraise\u001b[0m \u001b[0mKeyboardInterrupt\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"Interrupted by user\"\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;32mfrom\u001b[0m \u001b[0;32mNone\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 893\u001b[0m \u001b[0;32mexcept\u001b[0m \u001b[0mException\u001b[0m \u001b[0;32mas\u001b[0m \u001b[0me\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 894\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mlog\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mwarning\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"Invalid Message:\"\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mexc_info\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;32mTrue\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;31mKeyboardInterrupt\u001b[0m: Interrupted by user" + ] + } + ], + "source": [ + "from DST import Dst\n", + "from AJN import *\n", + "from NLG import nlg\n", + "\n", + "\n", + "\n", + "if __name__ == \"__main__\":\n", + " \n", + " dst = Dst()\n", + " next_question = dst.get_next_question()\n", + " while (next_question):\n", + " \n", + " \n", + " text = input('>>>')\n", + " frame = ajn(text)\n", + " \n", + " dst.save_answer(frame['slots'])\n", + " \n", + " next_question = dst.get_next_question()\n", + " print(next_question)\n", + " print(dst.checklist)\n", + "# print(frame['act'])\n", + " nlg(next_question)\n", + "\n", + " \n", + " \n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "yellow-acquisition", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.7.3" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/modules/.ipynb_checkpoints/AJN-checkpoint.py b/modules/.ipynb_checkpoints/AJN-checkpoint.py new file mode 100644 index 0000000..4ace0dd --- /dev/null +++ b/modules/.ipynb_checkpoints/AJN-checkpoint.py @@ -0,0 +1,50 @@ +import jsgf +from os import listdir +from os.path import isfile, join + +mypath = "./grammar/" +onlyfiles = [f for f in listdir(mypath) if isfile(join(mypath, f))] + +grammars = [] + +for grammarFile in onlyfiles: + grammar = jsgf.parse_grammar_file(mypath + grammarFile) + grammars.append(grammar) + +class Ajn: + + + + def __init__(self, grammars = None): + self.grammars = grammars + + 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) + + def nlu(utterance): + matched = None + for grammar in grammars: + matched = grammar.find_matching_rules(utterance) + if matched: + break + + if matched: + return get_dialog_act(matched[0]) + else: + return {'act': 'null', 'slots': []} + + +ajn = Ajn() \ No newline at end of file diff --git a/modules/.ipynb_checkpoints/DST-checkpoint.py b/modules/.ipynb_checkpoints/DST-checkpoint.py new file mode 100644 index 0000000..7b516f6 --- /dev/null +++ b/modules/.ipynb_checkpoints/DST-checkpoint.py @@ -0,0 +1,27 @@ +class Dst: + def __init__(self): + self.messages = [] + self.checklist = { + "ilosc": None, + "tytul": None, + "dzien": None, + "godzina": None + } + self.history = [] + + def store(self, message): + self.messages.append(message) + + def get_messages(self): + return self.messages + + def get_next_question(self): + for key, value in self.checklist.items(): + if value == None: + return key + + def save_answer(self, slots): + for slot in slots: + self.checklist[slot[0]] = slot[1] + + self.messages.append(slots) \ No newline at end of file diff --git a/modules/NLG.py b/modules/NLG.py new file mode 100644 index 0000000..2947fd2 --- /dev/null +++ b/modules/NLG.py @@ -0,0 +1,10 @@ +def nlg(query): + if query == 'dzien': + print("Na który dzień ma być dokonana rezerwacja?") + if query == 'godzina': + print("Na którą godzinę ma być dokonana rezerwacja?") + if query == 'ilosc': + print("Ile biletów ma zostać zarezerwowanych?") + if query == 'tytul': + print("Na jaki film ma zostać dokonana rezerwacja?") + diff --git a/modules/__pycache__/AJN.cpython-37.pyc b/modules/__pycache__/AJN.cpython-37.pyc new file mode 100644 index 0000000..71e2e7b Binary files /dev/null and b/modules/__pycache__/AJN.cpython-37.pyc differ diff --git a/modules/__pycache__/AJN.cpython-39.pyc b/modules/__pycache__/AJN.cpython-39.pyc new file mode 100644 index 0000000..4b28b6b Binary files /dev/null and b/modules/__pycache__/AJN.cpython-39.pyc differ diff --git a/modules/__pycache__/DST.cpython-37.pyc b/modules/__pycache__/DST.cpython-37.pyc new file mode 100644 index 0000000..22ba353 Binary files /dev/null and b/modules/__pycache__/DST.cpython-37.pyc differ diff --git a/modules/__pycache__/DST.cpython-39.pyc b/modules/__pycache__/DST.cpython-39.pyc new file mode 100644 index 0000000..8c28b85 Binary files /dev/null and b/modules/__pycache__/DST.cpython-39.pyc differ