diff --git a/.gitignore b/.gitignore index 7ded952..374c3c4 100644 --- a/.gitignore +++ b/.gitignore @@ -213,4 +213,6 @@ fabric.properties .idea -slot-model \ No newline at end of file +slot-model + +ConvLab-2 \ No newline at end of file diff --git a/lab/09-zarzadzanie-dialogiem-reguly.ipynb b/lab/09-zarzadzanie-dialogiem-reguly.ipynb index 6d59ed6..4032a32 100644 --- a/lab/09-zarzadzanie-dialogiem-reguly.ipynb +++ b/lab/09-zarzadzanie-dialogiem-reguly.ipynb @@ -9,7 +9,7 @@ "![Logo 1](https://git.wmi.amu.edu.pl/AITech/Szablon/raw/branch/master/Logotyp_AITech1.jpg)\n", "
\n", "

Systemy Dialogowe

\n", - "

9. Zarz\u0105dzanie dialogiem z wykorzystaniem regu\u0142 [laboratoria]

\n", + "

9. Zarządzanie dialogiem z wykorzystaniem reguł [laboratoria]

\n", "

Marek Kubis (2021)

\n", "
\n", "\n", @@ -20,30 +20,30 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "Zarz\u0105dzanie dialogiem z wykorzystaniem regu\u0142\n", + "Zarządzanie dialogiem z wykorzystaniem reguł\n", "============================================\n", "\n", - "Agent dialogowy wykorzystuje do zarz\u0105dzanie dialogiem dwa modu\u0142y:\n", + "Agent dialogowy wykorzystuje do zarządzanie dialogiem dwa moduły:\n", "\n", - " - monitor stanu dialogu (dialogue state tracker, DST) \u2014 modu\u0142 odpowiedzialny za \u015bledzenie stanu dialogu.\n", + " - monitor stanu dialogu (dialogue state tracker, DST) — moduł odpowiedzialny za śledzenie stanu dialogu.\n", "\n", - " - taktyk\u0119 prowadzenia dialogu (dialogue policy) \u2014 modu\u0142, kt\u00f3ry na podstawie stanu dialogu\n", - " podejmuje decyzj\u0119 o tym jak\u0105 akcj\u0119 (akt systemu) agent ma podj\u0105\u0107 w kolejnej turze.\n", + " - taktykę prowadzenia dialogu (dialogue policy) — moduł, który na podstawie stanu dialogu\n", + " podejmuje decyzję o tym jaką akcję (akt systemu) agent ma podjąć w kolejnej turze.\n", "\n", - "Oba modu\u0142y mog\u0105 by\u0107 realizowane zar\u00f3wno z wykorzystaniem regu\u0142 jak i uczenia maszynowego.\n", - "Mog\u0105 one zosta\u0107 r\u00f3wnie\u017c po\u0142\u0105czone w pojedynczy modu\u0142 zwany w\u00f3wczas *mened\u017cerem dialogu*.\n", + "Oba moduły mogą być realizowane zarówno z wykorzystaniem reguł jak i uczenia maszynowego.\n", + "Mogą one zostać również połączone w pojedynczy moduł zwany wówczas *menedżerem dialogu*.\n", "\n", - "Przyk\u0142ad\n", + "Przykład\n", "--------\n", "\n", - "Zaimplementujemy regu\u0142owe modu\u0142y monitora stanu dialogu oraz taktyki dialogowej a nast\u0119pnie\n", - "osadzimy je w \u015brodowisku *[ConvLab-2](https://github.com/thu-coai/ConvLab-2)*,\n", - "kt\u00f3re s\u0142u\u017cy do ewaluacji system\u00f3w dialogowych.\n", + "Zaimplementujemy regułowe moduły monitora stanu dialogu oraz taktyki dialogowej a następnie\n", + "osadzimy je w środowisku *[ConvLab-2](https://github.com/thu-coai/ConvLab-2)*,\n", + "które służy do ewaluacji systemów dialogowych.\n", "\n", - "**Uwaga:** Niekt\u00f3re modu\u0142y \u015brodowiska *ConvLab-2* nie s\u0105 zgodne z najnowszymi wersjami Pythona,\n", - "dlatego przed uruchomieniem poni\u017cszych przyk\u0142ad\u00f3w nale\u017cy si\u0119 upewni\u0107, \u017ce maj\u0105 Pa\u0144stwo interpreter\n", - "Pythona w wersji 3.7. W przypadku nowszych wersji Ubuntu Pythona 3.7 mo\u017cna zainstalowa\u0107 z\n", - "repozytorium `deadsnakes`, wykonuj\u0105c polecenia przedstawione poni\u017cej.\n", + "**Uwaga:** Niektóre moduły środowiska *ConvLab-2* nie są zgodne z najnowszymi wersjami Pythona,\n", + "dlatego przed uruchomieniem poniższych przykładów należy się upewnić, że mają Państwo interpreter\n", + "Pythona w wersji 3.7. W przypadku nowszych wersji Ubuntu Pythona 3.7 można zainstalować z\n", + "repozytorium `deadsnakes`, wykonując polecenia przedstawione poniżej.\n", "\n", "```\n", "sudo add-apt-repository ppa:deadsnakes/ppa\n", @@ -51,20 +51,20 @@ "sudo apt install python3.7 python3.7-dev python3.7-venv\n", "```\n", "\n", - "W przypadku innych system\u00f3w mo\u017cna skorzysta\u0107 np. z narz\u0119dzia [pyenv](https://github.com/pyenv/pyenv) lub \u015brodowiska [conda](https://conda.io).\n", + "W przypadku innych systemów można skorzystać np. z narzędzia [pyenv](https://github.com/pyenv/pyenv) lub środowiska [conda](https://conda.io).\n", "\n", - "Ze wzgl\u0119du na to, \u017ce *ConvLab-2* ma wiele zale\u017cno\u015bci zach\u0119cam r\u00f3wnie\u017c do skorzystania ze \u015brodowiska\n", - "wirtualnego `venv`, w kt\u00f3rym modu\u0142y zale\u017cne mog\u0105 zosta\u0107 zainstalowane.\n", - "W tym celu nale\u017cy wykona\u0107 nast\u0119puj\u0105ce polecenia\n", + "Ze względu na to, że *ConvLab-2* ma wiele zależności zachęcam również do skorzystania ze środowiska\n", + "wirtualnego `venv`, w którym moduły zależne mogą zostać zainstalowane.\n", + "W tym celu należy wykonać następujące polecenia\n", "\n", "```\n", - "python3.7 -m venv convenv # utworzenie nowego \u015brodowiska o nazwie convenv\n", - "source convenv/bin/activate # aktywacja \u015brodowiska w bie\u017c\u0105cej pow\u0142oce\n", - "pip install --ignore-installed jupyter # instalacja jupytera w \u015brodowisku convenv\n", + "python3.7 -m venv convenv # utworzenie nowego środowiska o nazwie convenv\n", + "source convenv/bin/activate # aktywacja środowiska w bieżącej powłoce\n", + "pip install --ignore-installed jupyter # instalacja jupytera w środowisku convenv\n", "```\n", "\n", - "Po skonfigurowaniu \u015brodowiska mo\u017cna przyst\u0105pi\u0107 do instalacji *ConvLab-2*, korzystaj\u0105c z\n", - "nast\u0119puj\u0105cych polece\u0144\n", + "Po skonfigurowaniu środowiska można przystąpić do instalacji *ConvLab-2*, korzystając z\n", + "następujących poleceń\n", "\n", "```\n", "mkdir -p l08\n", @@ -76,30 +76,54 @@ "cd ../..\n", "```\n", "\n", - "Po zako\u0144czeniu instalacji nale\u017cy ponownie uruchomi\u0107 notatnik w pow\u0142oce, w kt\u00f3rej aktywne jest\n", - "\u015brodowisko wirtualne *convenv*.\n", + "Po zakończeniu instalacji należy ponownie uruchomić notatnik w powłoce, w której aktywne jest\n", + "środowisko wirtualne *convenv*.\n", "\n", "```\n", "jupyter notebook 08-zarzadzanie-dialogiem-reguly.ipynb\n", "```\n", "\n", - "Dzia\u0142anie zaimplementowanych modu\u0142\u00f3w zilustrujemy, korzystaj\u0105c ze zbioru danych\n", - "[MultiWOZ](https://github.com/budzianowski/multiwoz) (Budzianowski i in., 2018), kt\u00f3ry zawiera\n", - "wypowiedzi dotycz\u0105ce m.in. rezerwacji pokoi hotelowych, zamawiania bilet\u00f3w kolejowych oraz\n", - "rezerwacji stolik\u00f3w w restauracji.\n", + "Działanie zaimplementowanych modułów zilustrujemy, korzystając ze zbioru danych\n", + "[MultiWOZ](https://github.com/budzianowski/multiwoz) (Budzianowski i in., 2018), który zawiera\n", + "wypowiedzi dotyczące m.in. rezerwacji pokoi hotelowych, zamawiania biletów kolejowych oraz\n", + "rezerwacji stolików w restauracji.\n", "\n", "### Monitor Stanu Dialogu\n", "\n", - "Do reprezentowania stanu dialogu u\u017cyjemy struktury danych wykorzystywanej w *ConvLab-2*." + "Do reprezentowania stanu dialogu użyjemy struktury danych wykorzystywanej w *ConvLab-2*." ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 3, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "{'user_action': [],\n", + " 'system_action': [],\n", + " 'belief_state': {'cinema': {'book': {'title': '',\n", + " 'date': '',\n", + " 'time': '',\n", + " 'quantity': '',\n", + " 'seats': '',\n", + " 'area': '',\n", + " 'interval': ''},\n", + " 'semi': {'goal': ''}}},\n", + " 'request_state': {},\n", + " 'terminated': False,\n", + " 'history': []}" + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ - "from convlab2.util.multiwoz.state import default_state\n", + "# from convlab2.util.multiwoz.state import default_state\n", + "from utils.state import default_state\n", "default_state()" ] }, @@ -107,19 +131,30 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "Metoda `update` naszego monitora stanu dialogu b\u0119dzie przyjmowa\u0107 akty u\u017cytkownika i odpowiednio\n", - "modyfikowa\u0107 stan dialogu.\n", - "W przypadku akt\u00f3w typu `inform` warto\u015bci slot\u00f3w zostan\u0105 zapami\u0119tane w s\u0142ownikach odpowiadaj\u0105cych\n", - "poszczeg\u00f3lnym dziedzinom pod kluczem `belief_state`.\n", - "W przypadku akt\u00f3w typu `request` sloty, o kt\u00f3re pyta u\u017cytkownik zostan\u0105 zapisane pod kluczem\n", + "Metoda `update` naszego monitora stanu dialogu będzie przyjmować akty użytkownika i odpowiednio\n", + "modyfikować stan dialogu.\n", + "W przypadku aktów typu `inform` wartości slotów zostaną zapamiętane w słownikach odpowiadających\n", + "poszczególnym dziedzinom pod kluczem `belief_state`.\n", + "W przypadku aktów typu `request` sloty, o które pyta użytkownik zostaną zapisane pod kluczem\n", "`request_state`.\n" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 34, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "\"\\nclass SimpleRuleDST(DST):\\n def __init__(self):\\n DST.__init__(self)\\n self.state = default_state()\\n self.value_dict = json.load(open('l08/ConvLab-2/data/multiwoz/value_dict.json'))\\n\\n def update(self, user_act=None):\\n for intent, domain, slot, value in user_act:\\n domain = domain.lower()\\n intent = intent.lower()\\n\\n if domain in ['unk', 'general', 'booking']:\\n continue\\n\\n if intent == 'inform':\\n k = REF_SYS_DA[domain.capitalize()].get(slot, slot)\\n\\n if k is None:\\n continue\\n\\n domain_dic = self.state['belief_state'][domain]\\n\\n if k in domain_dic['semi']:\\n nvalue = normalize_value(self.value_dict, domain, k, value)\\n self.state['belief_state'][domain]['semi'][k] = nvalue\\n elif k in domain_dic['book']:\\n self.state['belief_state'][domain]['book'][k] = value\\n elif k.lower() in domain_dic['book']:\\n self.state['belief_state'][domain]['book'][k.lower()] = value\\n elif intent == 'request':\\n k = REF_SYS_DA[domain.capitalize()].get(slot, slot)\\n\\n if domain not in self.state['request_state']:\\n self.state['request_state'][domain] = {}\\n if k not in self.state['request_state'][domain]:\\n self.state['request_state'][domain][k] = 0\\n\\n return self.state\\n\\n def init_session(self):\\n self.state = default_state()\\n\"" + ] + }, + "execution_count": 34, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "import json\n", "import os\n", @@ -127,7 +162,50 @@ "from convlab2.dst.rule.multiwoz.dst_util import normalize_value\n", "from convlab2.util.multiwoz.multiwoz_slot_trans import REF_SYS_DA\n", "\n", + "class SimpleRuleDST(DST):\n", + " def __init__(self):\n", + " DST.__init__(self)\n", + " self.state = default_state()\n", + " self.value_dict = json.load(open('utils/value_dict.json'))\n", "\n", + " def update(self, user_act=None):\n", + " for intent, domain, slot, value in user_act:\n", + " domain = domain.lower()\n", + " intent = intent.lower()\n", + " value = value.lower()\n", + "\n", + " # if domain in ['unk', 'cinema']:\n", + " # continue\n", + " k = slot\n", + "\n", + " if intent == 'inform':\n", + " # k = REF_SYS_DA[domain.capitalize()].get(slot, slot)\n", + " # if k is None:\n", + " # continue\n", + "\n", + " domain_dic = self.state['belief_state'][domain]\n", + "\n", + " if k in domain_dic['semi']:\n", + " # nvalue = normalize_value(self.value_dict, domain, k, value)\n", + " self.state['belief_state'][domain]['semi'][k] = value\n", + " elif k in domain_dic['book']:\n", + " self.state['belief_state'][domain]['book'][k] = value\n", + " elif k.lower() in domain_dic['book']:\n", + " self.state['belief_state'][domain]['book'][k.lower()] = value\n", + " elif intent == 'request':\n", + " # k = REF_SYS_DA[domain.capitalize()].get(slot, slot)\n", + "\n", + " if domain not in self.state['request_state']:\n", + " self.state['request_state'][domain] = {}\n", + " if k not in self.state['request_state'][domain]:\n", + " self.state['request_state'][domain][k] = 0\n", + "\n", + " return self.state\n", + "\n", + " def init_session(self):\n", + " self.state = default_state()\n", + "\n", + "'''\n", "class SimpleRuleDST(DST):\n", " def __init__(self):\n", " DST.__init__(self)\n", @@ -168,32 +246,56 @@ " return self.state\n", "\n", " def init_session(self):\n", - " self.state = default_state()\n" + " self.state = default_state()\n", + "'''\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "W definicji metody `update` zak\u0142adamy, \u017ce akty dialogowe przekazywane do monitora stanu dialogu z\n", - "modu\u0142u NLU s\u0105 czteroelementowymi listami z\u0142o\u017conymi z:\n", + "W definicji metody `update` zakładamy, że akty dialogowe przekazywane do monitora stanu dialogu z\n", + "modułu NLU są czteroelementowymi listami złożonymi z:\n", "\n", - " - nazwy aktu u\u017cytkownika,\n", - " - nazwy dziedziny, kt\u00f3rej dotyczy wypowied\u017a,\n", + " - nazwy aktu użytkownika,\n", + " - nazwy dziedziny, której dotyczy wypowiedź,\n", " - nazwy slotu,\n", - " - warto\u015bci slotu.\n", + " - wartości slotu.\n", "\n", - "Zobaczmy na kilku prostych przyk\u0142adach jak stan dialogu zmienia si\u0119 pod wp\u0142ywem przekazanych akt\u00f3w\n", - "u\u017cytkownika." + "Zobaczmy na kilku prostych przykładach jak stan dialogu zmienia się pod wpływem przekazanych aktów\n", + "użytkownika." ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 35, "metadata": { "lines_to_next_cell": 0 }, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "{'user_action': [],\n", + " 'system_action': [],\n", + " 'belief_state': {'cinema': {'book': {'title': '',\n", + " 'date': '',\n", + " 'time': '',\n", + " 'quantity': '',\n", + " 'seats': '',\n", + " 'area': '',\n", + " 'interval': ''},\n", + " 'semi': {'goal': ''}}},\n", + " 'request_state': {},\n", + " 'terminated': False,\n", + " 'history': []}" + ] + }, + "execution_count": 35, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "dst = SimpleRuleDST()\n", "dst.state" @@ -201,37 +303,84 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 36, "metadata": { "lines_to_next_cell": 0 }, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "{'book': {'title': 'batman',\n", + " 'date': '',\n", + " 'time': '15:00',\n", + " 'quantity': '',\n", + " 'seats': '',\n", + " 'area': '',\n", + " 'interval': ''},\n", + " 'semi': {'goal': ''}}" + ] + }, + "execution_count": 36, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ - "dst.update([['Inform', 'Hotel', 'Price', 'cheap'], ['Inform', 'Hotel', 'Parking', 'yes']])\n", - "dst.state['belief_state']['hotel']" + "dst.update([['Inform', 'Cinema', 'time', '15:00'], ['Inform', 'Cinema', 'title', 'Batman']])\n", + "dst.state['belief_state']['cinema']" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 37, "metadata": { "lines_to_next_cell": 0 }, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "{'book': {'title': 'batman',\n", + " 'date': '',\n", + " 'time': '15:00',\n", + " 'quantity': '',\n", + " 'seats': '',\n", + " 'area': 'na górze na środku',\n", + " 'interval': ''},\n", + " 'semi': {'goal': ''}}" + ] + }, + "execution_count": 37, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ - "dst.update([['Inform', 'Hotel', 'Area', 'north']])\n", - "dst.state['belief_state']['hotel']" + "dst.update([['Inform', 'Cinema', 'area', 'na górze na środku']])\n", + "dst.state['belief_state']['cinema']" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 38, "metadata": { "lines_to_next_cell": 0 }, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "{'cinema': {'date': 0}}" + ] + }, + "execution_count": 38, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ - "dst.update([['Request', 'Hotel', 'Area', '?']])\n", + "dst.update([['Request', 'Cinema', 'date', '?']])\n", "dst.state['request_state']" ] }, @@ -241,7 +390,28 @@ "metadata": { "lines_to_next_cell": 0 }, - "outputs": [], + "outputs": [ + { + "ename": "", + "evalue": "", + "output_type": "error", + "traceback": [ + "\u001b[1;31mRunning cells with 'Python 3.6.15 ('sysdial')' requires ipykernel package.\n", + "Run the following command to install 'ipykernel' into the Python environment. \n", + "Command: 'conda install -n sysdial ipykernel --update-deps --force-reinstall'" + ] + }, + { + "ename": "", + "evalue": "", + "output_type": "error", + "traceback": [ + "\u001b[1;31mRunning cells with 'Python 3.6.15 ('sysdial')' requires ipykernel package.\n", + "Run the following command to install 'ipykernel' into the Python environment. \n", + "Command: 'conda install -n sysdial ipykernel --update-deps --force-reinstall'" + ] + } + ], "source": [ "dst.update([['Inform', 'Hotel', 'Day', 'tuesday'], ['Inform', 'Hotel', 'People', '2'], ['Inform', 'Hotel', 'Stay', '4']])\n", "dst.state['belief_state']['hotel']" @@ -249,9 +419,32 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 39, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "{'user_action': [],\n", + " 'system_action': [],\n", + " 'belief_state': {'cinema': {'book': {'title': 'batman',\n", + " 'date': '',\n", + " 'time': '15:00',\n", + " 'quantity': '',\n", + " 'seats': '',\n", + " 'area': 'na górze na środku',\n", + " 'interval': ''},\n", + " 'semi': {'goal': ''}}},\n", + " 'request_state': {'cinema': {'date': 0}},\n", + " 'terminated': False,\n", + " 'history': []}" + ] + }, + "execution_count": 39, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "dst.state" ] @@ -262,25 +455,46 @@ "source": [ "### Taktyka Prowadzenia Dialogu\n", "\n", - "Prosta taktyka prowadzenia dialogu dla systemu rezerwacji pokoi hotelowych mo\u017ce sk\u0142ada\u0107 si\u0119 z nast\u0119puj\u0105cych regu\u0142:\n", + "Prosta taktyka prowadzenia dialogu dla systemu rezerwacji pokoi hotelowych może składać się z następujących reguł:\n", "\n", - " 1. Je\u017celi u\u017cytkownik przekaza\u0142 w ostatniej turze akt typu `Request`, to udziel odpowiedzi na jego\n", + " 1. Jeżeli użytkownik przekazał w ostatniej turze akt typu `Request`, to udziel odpowiedzi na jego\n", " pytanie.\n", "\n", - " 2. Je\u017celi u\u017cytkownik przekaza\u0142 w ostatniej turze akt typu `Inform`, to zaproponuj mu hotel\n", - " spe\u0142niaj\u0105cy zdefiniowane przez niego kryteria.\n", + " 2. Jeżeli użytkownik przekazał w ostatniej turze akt typu `Inform`, to zaproponuj mu hotel\n", + " spełniający zdefiniowane przez niego kryteria.\n", "\n", - " 3. Je\u017celi u\u017cytkownik przekaza\u0142 w ostatniej turze akt typu `Inform` zawieraj\u0105cy szczeg\u00f3\u0142y\n", - " rezerwacji, to zarezerwuj pok\u00f3j.\n", + " 3. Jeżeli użytkownik przekazał w ostatniej turze akt typu `Inform` zawierający szczegóły\n", + " rezerwacji, to zarezerwuj pokój.\n", "\n", - "Metoda `predict` taktyki `SimpleRulePolicy` realizuje regu\u0142y przedstawione powy\u017cej." + "Metoda `predict` taktyki `SimpleRulePolicy` realizuje reguły przedstawione powyżej." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, - "outputs": [], + "outputs": [ + { + "ename": "", + "evalue": "", + "output_type": "error", + "traceback": [ + "\u001b[1;31mRunning cells with 'Python 3.6.15 ('sysdial')' requires ipykernel package.\n", + "Run the following command to install 'ipykernel' into the Python environment. \n", + "Command: 'conda install -n sysdial ipykernel --update-deps --force-reinstall'" + ] + }, + { + "ename": "", + "evalue": "", + "output_type": "error", + "traceback": [ + "\u001b[1;31mRunning cells with 'Python 3.6.15 ('sysdial')' requires ipykernel package.\n", + "Run the following command to install 'ipykernel' into the Python environment. \n", + "Command: 'conda install -n sysdial ipykernel --update-deps --force-reinstall'" + ] + } + ], "source": [ "from collections import defaultdict\n", "import copy\n", @@ -308,7 +522,7 @@ " for user_act in user_action:\n", " self.update_system_action(user_act, user_action, state, system_action)\n", "\n", - " # Regu\u0142a 3\n", + " # Reguła 3\n", " if any(True for slots in user_action.values() for (slot, _) in slots if slot in ['Stay', 'Day', 'People']):\n", " if self.results:\n", " system_action = {('Booking', 'Book'): [[\"Ref\", self.results[0].get('Ref', 'N/A')]]}\n", @@ -322,7 +536,7 @@ " constraints = [(slot, value) for slot, value in state['belief_state'][domain.lower()]['semi'].items() if value != '']\n", " self.results = deepcopy(self.db.query(domain.lower(), constraints))\n", "\n", - " # Regu\u0142a 1\n", + " # Reguła 1\n", " if intent == 'Request':\n", " if len(self.results) == 0:\n", " system_action[(domain, 'NoOffer')] = []\n", @@ -333,7 +547,7 @@ " if kb_slot_name in self.results[0]:\n", " system_action[(domain, 'Inform')].append([slot[0], self.results[0].get(kb_slot_name, 'unknown')])\n", "\n", - " # Regu\u0142a 2\n", + " # Reguła 2\n", " elif intent == 'Inform':\n", " if len(self.results) == 0:\n", " system_action[(domain, 'NoOffer')] = []\n", @@ -349,14 +563,14 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "Podobnie jak w przypadku akt\u00f3w u\u017cytkownika akty systemowe przekazywane do modu\u0142u NLG s\u0105 czteroelementowymi listami z\u0142o\u017conymi z:\n", + "Podobnie jak w przypadku aktów użytkownika akty systemowe przekazywane do modułu NLG są czteroelementowymi listami złożonymi z:\n", "\n", " - nazwy aktu systemowe,\n", - " - nazwy dziedziny, kt\u00f3rej dotyczy wypowied\u017a,\n", + " - nazwy dziedziny, której dotyczy wypowiedź,\n", " - nazwy slotu,\n", - " - warto\u015bci slotu.\n", + " - wartości slotu.\n", "\n", - "Sprawd\u017amy jakie akty systemowe zwraca taktyka `SimpleRulePolicy` w odpowiedzi na zmieniaj\u0105cy si\u0119 stan dialogu." + "Sprawdźmy jakie akty systemowe zwraca taktyka `SimpleRulePolicy` w odpowiedzi na zmieniający się stan dialogu." ] }, { @@ -365,7 +579,28 @@ "metadata": { "lines_to_next_cell": 0 }, - "outputs": [], + "outputs": [ + { + "ename": "", + "evalue": "", + "output_type": "error", + "traceback": [ + "\u001b[1;31mRunning cells with 'Python 3.6.15 ('sysdial')' requires ipykernel package.\n", + "Run the following command to install 'ipykernel' into the Python environment. \n", + "Command: 'conda install -n sysdial ipykernel --update-deps --force-reinstall'" + ] + }, + { + "ename": "", + "evalue": "", + "output_type": "error", + "traceback": [ + "\u001b[1;31mRunning cells with 'Python 3.6.15 ('sysdial')' requires ipykernel package.\n", + "Run the following command to install 'ipykernel' into the Python environment. \n", + "Command: 'conda install -n sysdial ipykernel --update-deps --force-reinstall'" + ] + } + ], "source": [ "from convlab2.dialog_agent import PipelineAgent\n", "dst.init_session()\n", @@ -379,7 +614,28 @@ "metadata": { "lines_to_next_cell": 0 }, - "outputs": [], + "outputs": [ + { + "ename": "", + "evalue": "", + "output_type": "error", + "traceback": [ + "\u001b[1;31mRunning cells with 'Python 3.6.15 ('sysdial')' requires ipykernel package.\n", + "Run the following command to install 'ipykernel' into the Python environment. \n", + "Command: 'conda install -n sysdial ipykernel --update-deps --force-reinstall'" + ] + }, + { + "ename": "", + "evalue": "", + "output_type": "error", + "traceback": [ + "\u001b[1;31mRunning cells with 'Python 3.6.15 ('sysdial')' requires ipykernel package.\n", + "Run the following command to install 'ipykernel' into the Python environment. \n", + "Command: 'conda install -n sysdial ipykernel --update-deps --force-reinstall'" + ] + } + ], "source": [ "agent.response([['Inform', 'Hotel', 'Price', 'cheap'], ['Inform', 'Hotel', 'Parking', 'yes']])" ] @@ -390,7 +646,28 @@ "metadata": { "lines_to_next_cell": 0 }, - "outputs": [], + "outputs": [ + { + "ename": "", + "evalue": "", + "output_type": "error", + "traceback": [ + "\u001b[1;31mRunning cells with 'Python 3.6.15 ('sysdial')' requires ipykernel package.\n", + "Run the following command to install 'ipykernel' into the Python environment. \n", + "Command: 'conda install -n sysdial ipykernel --update-deps --force-reinstall'" + ] + }, + { + "ename": "", + "evalue": "", + "output_type": "error", + "traceback": [ + "\u001b[1;31mRunning cells with 'Python 3.6.15 ('sysdial')' requires ipykernel package.\n", + "Run the following command to install 'ipykernel' into the Python environment. \n", + "Command: 'conda install -n sysdial ipykernel --update-deps --force-reinstall'" + ] + } + ], "source": [ "agent.response([['Inform', 'Hotel', 'Area', 'north']])" ] @@ -401,7 +678,28 @@ "metadata": { "lines_to_next_cell": 0 }, - "outputs": [], + "outputs": [ + { + "ename": "", + "evalue": "", + "output_type": "error", + "traceback": [ + "\u001b[1;31mRunning cells with 'Python 3.6.15 ('sysdial')' requires ipykernel package.\n", + "Run the following command to install 'ipykernel' into the Python environment. \n", + "Command: 'conda install -n sysdial ipykernel --update-deps --force-reinstall'" + ] + }, + { + "ename": "", + "evalue": "", + "output_type": "error", + "traceback": [ + "\u001b[1;31mRunning cells with 'Python 3.6.15 ('sysdial')' requires ipykernel package.\n", + "Run the following command to install 'ipykernel' into the Python environment. \n", + "Command: 'conda install -n sysdial ipykernel --update-deps --force-reinstall'" + ] + } + ], "source": [ "agent.response([['Request', 'Hotel', 'Area', '?']])" ] @@ -410,7 +708,28 @@ "cell_type": "code", "execution_count": null, "metadata": {}, - "outputs": [], + "outputs": [ + { + "ename": "", + "evalue": "", + "output_type": "error", + "traceback": [ + "\u001b[1;31mRunning cells with 'Python 3.6.15 ('sysdial')' requires ipykernel package.\n", + "Run the following command to install 'ipykernel' into the Python environment. \n", + "Command: 'conda install -n sysdial ipykernel --update-deps --force-reinstall'" + ] + }, + { + "ename": "", + "evalue": "", + "output_type": "error", + "traceback": [ + "\u001b[1;31mRunning cells with 'Python 3.6.15 ('sysdial')' requires ipykernel package.\n", + "Run the following command to install 'ipykernel' into the Python environment. \n", + "Command: 'conda install -n sysdial ipykernel --update-deps --force-reinstall'" + ] + } + ], "source": [ "agent.response([['Inform', 'Hotel', 'Day', 'tuesday'], ['Inform', 'Hotel', 'People', '2'], ['Inform', 'Hotel', 'Stay', '4']])" ] @@ -421,15 +740,36 @@ "source": [ "### Testy End-to-End\n", "\n", - "Na koniec przeprowad\u017amy dialog \u0142\u0105cz\u0105c w potok nasze modu\u0142y\n", - "z modu\u0142ami NLU i NLG dost\u0119pnymi dla MultiWOZ w \u015brodowisku `ConvLab-2`." + "Na koniec przeprowadźmy dialog łącząc w potok nasze moduły\n", + "z modułami NLU i NLG dostępnymi dla MultiWOZ w środowisku `ConvLab-2`." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, - "outputs": [], + "outputs": [ + { + "ename": "", + "evalue": "", + "output_type": "error", + "traceback": [ + "\u001b[1;31mRunning cells with 'Python 3.6.15 ('sysdial')' requires ipykernel package.\n", + "Run the following command to install 'ipykernel' into the Python environment. \n", + "Command: 'conda install -n sysdial ipykernel --update-deps --force-reinstall'" + ] + }, + { + "ename": "", + "evalue": "", + "output_type": "error", + "traceback": [ + "\u001b[1;31mRunning cells with 'Python 3.6.15 ('sysdial')' requires ipykernel package.\n", + "Run the following command to install 'ipykernel' into the Python environment. \n", + "Command: 'conda install -n sysdial ipykernel --update-deps --force-reinstall'" + ] + } + ], "source": [ "from convlab2.nlu.svm.multiwoz import SVMNLU\n", "from convlab2.nlg.template.multiwoz import TemplateNLG\n", @@ -445,7 +785,28 @@ "metadata": { "lines_to_next_cell": 0 }, - "outputs": [], + "outputs": [ + { + "ename": "", + "evalue": "", + "output_type": "error", + "traceback": [ + "\u001b[1;31mRunning cells with 'Python 3.6.15 ('sysdial')' requires ipykernel package.\n", + "Run the following command to install 'ipykernel' into the Python environment. \n", + "Command: 'conda install -n sysdial ipykernel --update-deps --force-reinstall'" + ] + }, + { + "ename": "", + "evalue": "", + "output_type": "error", + "traceback": [ + "\u001b[1;31mRunning cells with 'Python 3.6.15 ('sysdial')' requires ipykernel package.\n", + "Run the following command to install 'ipykernel' into the Python environment. \n", + "Command: 'conda install -n sysdial ipykernel --update-deps --force-reinstall'" + ] + } + ], "source": [ "agent.response(\"I need a cheap hotel with free parking .\")" ] @@ -456,7 +817,28 @@ "metadata": { "lines_to_next_cell": 0 }, - "outputs": [], + "outputs": [ + { + "ename": "", + "evalue": "", + "output_type": "error", + "traceback": [ + "\u001b[1;31mRunning cells with 'Python 3.6.15 ('sysdial')' requires ipykernel package.\n", + "Run the following command to install 'ipykernel' into the Python environment. \n", + "Command: 'conda install -n sysdial ipykernel --update-deps --force-reinstall'" + ] + }, + { + "ename": "", + "evalue": "", + "output_type": "error", + "traceback": [ + "\u001b[1;31mRunning cells with 'Python 3.6.15 ('sysdial')' requires ipykernel package.\n", + "Run the following command to install 'ipykernel' into the Python environment. \n", + "Command: 'conda install -n sysdial ipykernel --update-deps --force-reinstall'" + ] + } + ], "source": [ "agent.response(\"Where it is located ?\")" ] @@ -467,7 +849,28 @@ "metadata": { "lines_to_next_cell": 0 }, - "outputs": [], + "outputs": [ + { + "ename": "", + "evalue": "", + "output_type": "error", + "traceback": [ + "\u001b[1;31mRunning cells with 'Python 3.6.15 ('sysdial')' requires ipykernel package.\n", + "Run the following command to install 'ipykernel' into the Python environment. \n", + "Command: 'conda install -n sysdial ipykernel --update-deps --force-reinstall'" + ] + }, + { + "ename": "", + "evalue": "", + "output_type": "error", + "traceback": [ + "\u001b[1;31mRunning cells with 'Python 3.6.15 ('sysdial')' requires ipykernel package.\n", + "Run the following command to install 'ipykernel' into the Python environment. \n", + "Command: 'conda install -n sysdial ipykernel --update-deps --force-reinstall'" + ] + } + ], "source": [ "agent.response(\"I would prefer the hotel be in the north part of town .\")" ] @@ -476,7 +879,28 @@ "cell_type": "code", "execution_count": null, "metadata": {}, - "outputs": [], + "outputs": [ + { + "ename": "", + "evalue": "", + "output_type": "error", + "traceback": [ + "\u001b[1;31mRunning cells with 'Python 3.6.15 ('sysdial')' requires ipykernel package.\n", + "Run the following command to install 'ipykernel' into the Python environment. \n", + "Command: 'conda install -n sysdial ipykernel --update-deps --force-reinstall'" + ] + }, + { + "ename": "", + "evalue": "", + "output_type": "error", + "traceback": [ + "\u001b[1;31mRunning cells with 'Python 3.6.15 ('sysdial')' requires ipykernel package.\n", + "Run the following command to install 'ipykernel' into the Python environment. \n", + "Command: 'conda install -n sysdial ipykernel --update-deps --force-reinstall'" + ] + } + ], "source": [ "agent.response(\"Yeah , could you book me a room for 2 people for 4 nights starting Tuesday ?\")" ] @@ -485,44 +909,64 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "Zauwa\u017cmy, ze nasza prosta taktyka dialogowa zawiera wiele luk, do kt\u00f3rych nale\u017c\u0105 m.in.:\n", + "Zauważmy, ze nasza prosta taktyka dialogowa zawiera wiele luk, do których należą m.in.:\n", "\n", - " 1. Niezdolno\u015b\u0107 do udzielenia odpowiedzi na przywitanie, pro\u015bb\u0119 o pomoc lub restart.\n", + " 1. Niezdolność do udzielenia odpowiedzi na przywitanie, prośbę o pomoc lub restart.\n", "\n", - " 2. Brak regu\u0142 dopytuj\u0105cych u\u017cytkownika o szczeg\u00f3\u0142y niezb\u0119dne do dokonania rezerwacji takie, jak d\u0142ugo\u015b\u0107 pobytu czy liczba os\u00f3b.\n", + " 2. Brak reguł dopytujących użytkownika o szczegóły niezbędne do dokonania rezerwacji takie, jak długość pobytu czy liczba osób.\n", "\n", - "Bardziej zaawansowane modu\u0142y zarz\u0105dzania dialogiem zbudowane z wykorzystaniem regu\u0142 mo\u017cna znale\u017a\u0107 w\n", - "\u015brodowisku `ConvLab-2`. Nale\u017c\u0105 do nich m.in. monitor [RuleDST](https://github.com/thu-coai/ConvLab-2/blob/master/convlab2/dst/rule/multiwoz/dst.py) oraz taktyka [RuleBasedMultiwozBot](https://github.com/thu-coai/ConvLab-2/blob/master/convlab2/policy/rule/multiwoz/rule_based_multiwoz_bot.py).\n", + "Bardziej zaawansowane moduły zarządzania dialogiem zbudowane z wykorzystaniem reguł można znaleźć w\n", + "środowisku `ConvLab-2`. Należą do nich m.in. monitor [RuleDST](https://github.com/thu-coai/ConvLab-2/blob/master/convlab2/dst/rule/multiwoz/dst.py) oraz taktyka [RuleBasedMultiwozBot](https://github.com/thu-coai/ConvLab-2/blob/master/convlab2/policy/rule/multiwoz/rule_based_multiwoz_bot.py).\n", "\n", "Zadania\n", "-------\n", - " 1. Zaimplementowa\u0107 w projekcie monitor stanu dialogu.\n", + " 1. Zaimplementować w projekcie monitor stanu dialogu.\n", "\n", - " 2. Zaimplementowa\u0107 w projekcie taktyk\u0119 prowadzenia dialogu.\n", + " 2. Zaimplementować w projekcie taktykę prowadzenia dialogu.\n", "\n", "Termin: 24.05.2021, godz. 23:59.\n", "\n", "Literatura\n", "----------\n", - " 1. Pawel Budzianowski, Tsung-Hsien Wen, Bo-Hsiang Tseng, I\u00f1igo Casanueva, Stefan Ultes, Osman Ramadan, Milica Gasic, MultiWOZ - A Large-Scale Multi-Domain Wizard-of-Oz Dataset for Task-Oriented Dialogue Modelling. EMNLP 2018, pp. 5016-5026\n", - " 2. Cathy Pearl, Basic principles for designing voice user interfaces, https://www.oreilly.com/content/basic-principles-for-designing-voice-user-interfaces/ data dost\u0119pu: 21 marca 2021\n", - " 3. Cathy Pearl, Designing Voice User Interfaces, Excerpts from Chapter 5: Advanced Voice User Interface Design, https://www.uxmatters.com/mt/archives/2018/01/designing-voice-user-interfaces.php data dost\u0119pu: 21 marca 2021" + " 1. Pawel Budzianowski, Tsung-Hsien Wen, Bo-Hsiang Tseng, Iñigo Casanueva, Stefan Ultes, Osman Ramadan, Milica Gasic, MultiWOZ - A Large-Scale Multi-Domain Wizard-of-Oz Dataset for Task-Oriented Dialogue Modelling. EMNLP 2018, pp. 5016-5026\n", + " 2. Cathy Pearl, Basic principles for designing voice user interfaces, https://www.oreilly.com/content/basic-principles-for-designing-voice-user-interfaces/ data dostępu: 21 marca 2021\n", + " 3. Cathy Pearl, Designing Voice User Interfaces, Excerpts from Chapter 5: Advanced Voice User Interface Design, https://www.uxmatters.com/mt/archives/2018/01/designing-voice-user-interfaces.php data dostępu: 21 marca 2021" ] } ], "metadata": { + "author": "Marek Kubis", + "email": "mkubis@amu.edu.pl", + "interpreter": { + "hash": "91e2b0d1baa6ebb76863bdb1d11380bf032a6a1fc1b919194f041a5133852891" + }, "jupytext": { "cell_metadata_filter": "-all", "main_language": "python", "notebook_metadata_filter": "-all" }, - "author": "Marek Kubis", - "email": "mkubis@amu.edu.pl", + "kernelspec": { + "display_name": "Python 3.7.9 ('venv': venv)", + "language": "python", + "name": "python3" + }, "lang": "pl", - "subtitle": "9.Zarz\u0105dzanie dialogiem z wykorzystaniem regu\u0142[laboratoria]", + "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.9" + }, + "subtitle": "9.Zarządzanie dialogiem z wykorzystaniem reguł[laboratoria]", "title": "Systemy Dialogowe", "year": "2021" }, "nbformat": 4, "nbformat_minor": 4 -} \ No newline at end of file +} diff --git a/lab/10-zarzadzanie-dialogiem-uczenie.ipynb b/lab/10-zarzadzanie-dialogiem-uczenie.ipynb index a1c2a2c..1d02d9c 100644 --- a/lab/10-zarzadzanie-dialogiem-uczenie.ipynb +++ b/lab/10-zarzadzanie-dialogiem-uczenie.ipynb @@ -9,7 +9,7 @@ "![Logo 1](https://git.wmi.amu.edu.pl/AITech/Szablon/raw/branch/master/Logotyp_AITech1.jpg)\n", "
\n", "

Systemy Dialogowe

\n", - "

10. Zarz\u0105dzanie dialogiem z wykorzystaniem technik uczenia maszynowego [laboratoria]

\n", + "

10. Zarządzanie dialogiem z wykorzystaniem technik uczenia maszynowego [laboratoria]

\n", "

Marek Kubis (2021)

\n", "
\n", "\n", @@ -20,23 +20,23 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "Zarz\u0105dzanie dialogiem z wykorzystaniem technik uczenia maszynowego\n", + "Zarządzanie dialogiem z wykorzystaniem technik uczenia maszynowego\n", "==================================================================\n", "\n", "Uczenie przez wzmacnianie\n", "-------------------------\n", "\n", - "Zamiast r\u0119cznie implementowa\u0107 zbi\u00f3r regu\u0142 odpowiedzialnych za wyznaczenie akcji, kt\u00f3r\u0105 powinien podj\u0105\u0107 agent b\u0119d\u0105c w danym stanie, odpowiedni\u0105 taktyk\u0119 prowadzenia dialogu mo\u017cna zbudowa\u0107, wykorzystuj\u0105c techniki uczenia maszynowego.\n", + "Zamiast ręcznie implementować zbiór reguł odpowiedzialnych za wyznaczenie akcji, którą powinien podjąć agent będąc w danym stanie, odpowiednią taktykę prowadzenia dialogu można zbudować, wykorzystując techniki uczenia maszynowego.\n", "\n", - "Obok metod uczenia nadzorowanego, kt\u00f3re wykorzystali\u015bmy do zbudowania modelu NLU, do konstruowania taktyk\n", - "prowadzenia dialogu wykorzystuje si\u0119 r\u00f3wnie\u017c *uczenie przez wzmacnianie* (ang. *reinforcement learning*).\n", + "Obok metod uczenia nadzorowanego, które wykorzystaliśmy do zbudowania modelu NLU, do konstruowania taktyk\n", + "prowadzenia dialogu wykorzystuje się również *uczenie przez wzmacnianie* (ang. *reinforcement learning*).\n", "\n", - "W tym uj\u0119ciu szuka\u0107 b\u0119dziemy funkcji $Q*: S \\times A \\to R$, kt\u00f3ra dla stanu dialogu $s \\in S$ oraz aktu\n", - "dialogowego $a \\in A$ zwraca nagrod\u0119 (ang. *reward*) $r \\in R$, tj. warto\u015b\u0107 rzeczywist\u0105 pozwalaj\u0105c\u0105 oceni\u0107 na ile\n", - "podj\u0119cie akcji $a$ w stanie $s$ jest korzystne.\n", + "W tym ujęciu szukać będziemy funkcji $Q*: S \\times A \\to R$, która dla stanu dialogu $s \\in S$ oraz aktu\n", + "dialogowego $a \\in A$ zwraca nagrodę (ang. *reward*) $r \\in R$, tj. wartość rzeczywistą pozwalającą ocenić na ile\n", + "podjęcie akcji $a$ w stanie $s$ jest korzystne.\n", "\n", - "Za\u0142o\u017cymy r\u00f3wnie\u017c, \u017ce poszukiwana funkcja powinna maksymalizowa\u0107 *zwrot* (ang. *return*), tj.\n", - "skumulowan\u0105 nagrod\u0119 w toku prowadzonego dialogu, czyli dla tury $t_0$ cel uczenia powinien mie\u0107 posta\u0107:\n", + "Założymy również, że poszukiwana funkcja powinna maksymalizować *zwrot* (ang. *return*), tj.\n", + "skumulowaną nagrodę w toku prowadzonego dialogu, czyli dla tury $t_0$ cel uczenia powinien mieć postać:\n", "\n", "$$ \\sum_{t=t_0}^{\\infty}{\\gamma^{t-1}r_t} $$\n", "\n", @@ -46,36 +46,48 @@ "\n", " - $r_t$: nagroda w turze $t$,\n", "\n", - " - $\\gamma \\in [0, 1]$: wsp\u00f3\u0142czynnik dyskontowy (w przypadku agent\u00f3w dialogowych bli\u017cej $1$ ni\u017c $0$, por. np. Rieser i Lemon (2011))." + " - $\\gamma \\in [0, 1]$: współczynnik dyskontowy (w przypadku agentów dialogowych bliżej $1$ niż $0$, por. np. Rieser i Lemon (2011))." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "Agent dialogowy w procesie uczenia przez wzmacnianie wchodzi w interakcj\u0119 ze *\u015brodowiskiem*, kt\u00f3re\n", - "dla akcji podejmowanej przez taktyk\u0119 prowadzenia dialogu zwraca kolejny stan oraz nagrod\u0119 powi\u0105zan\u0105 z\n", - "wykonaniem tej akcji w bie\u017c\u0105cym stanie.\n", + "Agent dialogowy w procesie uczenia przez wzmacnianie wchodzi w interakcję ze *środowiskiem*, które\n", + "dla akcji podejmowanej przez taktykę prowadzenia dialogu zwraca kolejny stan oraz nagrodę powiązaną z\n", + "wykonaniem tej akcji w bieżącym stanie.\n", "\n", - "Spos\u00f3b w jaki informacje pochodz\u0105ce ze \u015brodowiska s\u0105 wykorzystywane do znalezienia funkcji $Q*$\n", - "zale\u017cy od wybranej metody uczenia.\n", - "W przyk\u0142adzie przestawionym poni\u017cej skorzystamy z algorytmu $DQN$ (Mnih i in., 2013) co oznacza, \u017ce:\n", + "Sposób w jaki informacje pochodzące ze środowiska są wykorzystywane do znalezienia funkcji $Q*$\n", + "zależy od wybranej metody uczenia.\n", + "W przykładzie przestawionym poniżej skorzystamy z algorytmu $DQN$ (Mnih i in., 2013) co oznacza, że:\n", "\n", - " 1. b\u0119dziemy aproksymowa\u0107 funkcj\u0119 $Q*$ sieci\u0105 neuronow\u0105,\n", + " 1. będziemy aproksymować funkcję $Q*$ siecią neuronową,\n", "\n", - " 2. wagi sieci b\u0119dziemy wyznacza\u0107 korzystaj\u0105c z metody spadku gradientu.\n", + " 2. wagi sieci będziemy wyznaczać korzystając z metody spadku gradientu.\n", "\n", - "Przyk\u0142ad\n", + "Przykład\n", "--------\n", "\n", - "Taktyk\u0119 prowadzenia dialogu osadzimy w \u015brodowisku *ConvLab-2*." + "Taktykę prowadzenia dialogu osadzimy w środowisku *ConvLab-2*." ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 2, "metadata": {}, - "outputs": [], + "outputs": [ + { + "ename": "ModuleNotFoundError", + "evalue": "No module named 'convlab2'", + "output_type": "error", + "traceback": [ + "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[1;31mModuleNotFoundError\u001b[0m Traceback (most recent call last)", + "\u001b[1;32mc:\\Develop\\wmi\\AITECH\\sem1\\Systemy dialogowe\\lab\\10-zarzadzanie-dialogiem-uczenie.ipynb Cell 4'\u001b[0m in \u001b[0;36m\u001b[1;34m()\u001b[0m\n\u001b[1;32m----> 1\u001b[0m \u001b[39mfrom\u001b[39;00m \u001b[39mconvlab2\u001b[39;00m\u001b[39m.\u001b[39;00m\u001b[39mdialog_agent\u001b[39;00m\u001b[39m.\u001b[39;00m\u001b[39magent\u001b[39;00m \u001b[39mimport\u001b[39;00m PipelineAgent\n\u001b[0;32m 2\u001b[0m \u001b[39mfrom\u001b[39;00m \u001b[39mconvlab2\u001b[39;00m\u001b[39m.\u001b[39;00m\u001b[39mdialog_agent\u001b[39;00m\u001b[39m.\u001b[39;00m\u001b[39menv\u001b[39;00m \u001b[39mimport\u001b[39;00m Environment\n\u001b[0;32m 3\u001b[0m \u001b[39mfrom\u001b[39;00m \u001b[39mconvlab2\u001b[39;00m\u001b[39m.\u001b[39;00m\u001b[39mdst\u001b[39;00m\u001b[39m.\u001b[39;00m\u001b[39mrule\u001b[39;00m\u001b[39m.\u001b[39;00m\u001b[39mmultiwoz\u001b[39;00m \u001b[39mimport\u001b[39;00m RuleDST\n", + "\u001b[1;31mModuleNotFoundError\u001b[0m: No module named 'convlab2'" + ] + } + ], "source": [ "from convlab2.dialog_agent.agent import PipelineAgent\n", "from convlab2.dialog_agent.env import Environment\n", @@ -88,7 +100,7 @@ "\n", "logging.disable(logging.DEBUG)\n", "\n", - "# determinizacja oblicze\u0144\n", + "# determinizacja obliczeń\n", "import random\n", "import torch\n", "import numpy as np\n", @@ -102,8 +114,8 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "\u015arodowisko, z kt\u00f3rym agent b\u0119dzie wchodzi\u0142 w interakcje zawiera\u0107 b\u0119dzie\n", - "symulator u\u017cytkownika wykorzystuj\u0105cy taktyk\u0119 prowadzenia dialogu zbudowan\u0105 z wykorzystaniem regu\u0142." + "Środowisko, z którym agent będzie wchodził w interakcje zawierać będzie\n", + "symulator użytkownika wykorzystujący taktykę prowadzenia dialogu zbudowaną z wykorzystaniem reguł." ] }, { @@ -163,12 +175,12 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "Jak mo\u017cna zauwa\u017cy\u0107 powy\u017cej akcja, kt\u00f3ra prowadzi do pomy\u015blnego zako\u0144czenia zadania uzyskuje nagrod\u0119 $40$,\n", - "akcja kt\u00f3ra prowadzi do prawid\u0142owego rozpoznania dziedziny uzyskuje nagrod\u0119 $5$,\n", - "natomiast ka\u017cda inna akcja uzyskuje \"kar\u0119\" $-1$. Taka definicja zwrotu premiuje kr\u00f3tkie dialogi\n", - "prowadz\u0105ce do pomy\u015blnego wykonania zadania.\n", + "Jak można zauważyć powyżej akcja, która prowadzi do pomyślnego zakończenia zadania uzyskuje nagrodę $40$,\n", + "akcja która prowadzi do prawidłowego rozpoznania dziedziny uzyskuje nagrodę $5$,\n", + "natomiast każda inna akcja uzyskuje \"karę\" $-1$. Taka definicja zwrotu premiuje krótkie dialogi\n", + "prowadzące do pomyślnego wykonania zadania.\n", "\n", - "Sie\u0107 neuronowa, kt\u00f3r\u0105 wykorzystamy do aproksymacji funkcji $Q*$ ma nast\u0119puj\u0105c\u0105 architektur\u0119" + "Sieć neuronowa, którą wykorzystamy do aproksymacji funkcji $Q*$ ma następującą architekturę" ] }, { @@ -207,14 +219,14 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "Ka\u017cdy krok procedury uczenia sk\u0142ada si\u0119 z dw\u00f3ch etap\u00f3w:\n", + "Każdy krok procedury uczenia składa się z dwóch etapów:\n", "\n", - " 1. Wygenerowania przy u\u017cyciu taktyki (metoda `policy.predict`) oraz \u015brodowiska (metoda `env.step`) *trajektorii*, tj. sekwencji przej\u015b\u0107 pomi\u0119dzy stanami z\u0142o\u017conych z krotek postaci:\n", - " - stanu \u017ar\u00f3d\u0142owego,\n", - " - podj\u0119tej akcji (aktu systemowego),\n", + " 1. Wygenerowania przy użyciu taktyki (metoda `policy.predict`) oraz środowiska (metoda `env.step`) *trajektorii*, tj. sekwencji przejść pomiędzy stanami złożonych z krotek postaci:\n", + " - stanu źródłowego,\n", + " - podjętej akcji (aktu systemowego),\n", " - nagrody,\n", " - stanu docelowego,\n", - " - znacznika ko\u0144ca dialogu." + " - znacznika końca dialogu." ] }, { @@ -230,23 +242,23 @@ " max_trajectory_len = 50\n", "\n", " while sampled_num < batch_size:\n", - " # rozpocz\u0119cie nowego dialogu\n", + " # rozpoczęcie nowego dialogu\n", " s = env.reset()\n", "\n", " for t in range(max_trajectory_len):\n", " try:\n", - " # podj\u0119cie akcji przez agenta dialogowego\n", + " # podjęcie akcji przez agenta dialogowego\n", " a = policy.predict(s, warm_up=warm_up)\n", "\n", - " # odpowied\u017a \u015brodowiska na podj\u0119t\u0105 akcje\n", + " # odpowiedź środowiska na podjętą akcje\n", " next_s, r, done = env.step(a)\n", "\n", " # dodanie krotki do zbioru danych\n", - " buff.push(torch.Tensor(policy.vector.state_vectorize(s)).numpy(), # stan \u017ar\u00f3d\u0142owy\n", + " buff.push(torch.Tensor(policy.vector.state_vectorize(s)).numpy(), # stan źródłowy\n", " policy.vector.action_vectorize(a), # akcja\n", " r, # nagroda\n", " torch.Tensor(policy.vector.state_vectorize(next_s)).numpy(), # stan docelowy\n", - " 0 if done else 1) # znacznik ko\u0144ca\n", + " 0 if done else 1) # znacznik końca\n", "\n", " s = next_s\n", "\n", @@ -266,7 +278,7 @@ "source": [ " 2. Wykorzystania wygenerowanych krotek do aktualizacji taktyki.\n", "\n", - "Funkcja `train` realizuj\u0105ca pojedynczy krok uczenia przez wzmacnianie ma nast\u0119puj\u0105c\u0105 posta\u0107" + "Funkcja `train` realizująca pojedynczy krok uczenia przez wzmacnianie ma następującą postać" ] }, { @@ -286,7 +298,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "Metoda `update` klasy `DQN` wykorzystywana do aktualizacji wag ma nast\u0119puj\u0105c\u0105 posta\u0107" + "Metoda `update` klasy `DQN` wykorzystywana do aktualizacji wag ma następującą postać" ] }, { @@ -327,7 +339,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "Przebieg procesu uczenia zilustrujemy wykonuj\u0105c 100 iteracji. W ka\u017cdej iteracji ograniczymy si\u0119 do 100 przyk\u0142ad\u00f3w." + "Przebieg procesu uczenia zilustrujemy wykonując 100 iteracji. W każdej iteracji ograniczymy się do 100 przykładów." ] }, { @@ -349,7 +361,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "Sprawd\u017amy jakie akty systemowe zwraca taktyka `DQN` w odpowiedzi na zmieniaj\u0105cy si\u0119 stan dialogu." + "Sprawdźmy jakie akty systemowe zwraca taktyka `DQN` w odpowiedzi na zmieniający się stan dialogu." ] }, { @@ -411,8 +423,8 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "Jako\u015b\u0107 wyuczonego modelu mo\u017cemy oceni\u0107 mierz\u0105c tzw. wska\u017anik sukcesu (ang. *task success rate*),\n", - "tj. stosunek liczby dialog\u00f3w zako\u0144czonych powodzeniem do liczby wszystkich dialog\u00f3w." + "Jakość wyuczonego modelu możemy ocenić mierząc tzw. wskaźnik sukcesu (ang. *task success rate*),\n", + "tj. stosunek liczby dialogów zakończonych powodzeniem do liczby wszystkich dialogów." ] }, { @@ -455,10 +467,10 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "**Uwaga**: Chc\u0105c uzyska\u0107 taktyk\u0119 o skuteczno\u015bci por\u00f3wnywalnej z wynikami przedstawionymi na stronie\n", + "**Uwaga**: Chcąc uzyskać taktykę o skuteczności porównywalnej z wynikami przedstawionymi na stronie\n", "[ConvLab-2](https://github.com/thu-coai/ConvLab-2/blob/master/README.md) trzeba odpowiednio\n", - "zwi\u0119kszy\u0107 zar\u00f3wno liczb\u0119 iteracji jak i liczb\u0119 przyk\u0142ad\u00f3w generowanych w ka\u017cdym przyro\u015bcie.\n", - "W celu przy\u015bpieszenia procesu uczenia warto zr\u00f3wnolegli\u0107 obliczenia, jak pokazano w\n", + "zwiększyć zarówno liczbę iteracji jak i liczbę przykładów generowanych w każdym przyroście.\n", + "W celu przyśpieszenia procesu uczenia warto zrównoleglić obliczenia, jak pokazano w\n", "skrypcie [train.py](https://github.com/thu-coai/ConvLab-2/blob/master/convlab2/policy/dqn/train.py).\n", "\n", "Literatura\n", @@ -472,18 +484,38 @@ } ], "metadata": { + "author": "Marek Kubis", + "email": "mkubis@amu.edu.pl", + "interpreter": { + "hash": "2f9d6cf1e3d8195079a65c851de355134a77367bcd714b1a5d498c42d3c07114" + }, "jupytext": { "cell_metadata_filter": "-all", "main_language": "python", "notebook_metadata_filter": "-all" }, - "author": "Marek Kubis", - "email": "mkubis@amu.edu.pl", + "kernelspec": { + "display_name": "Python 3.8.3 64-bit", + "language": "python", + "name": "python3" + }, "lang": "pl", - "subtitle": "10.Zarz\u0105dzanie dialogiem z wykorzystaniem technik uczenia maszynowego[laboratoria]", + "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.8.3" + }, + "subtitle": "10.Zarządzanie dialogiem z wykorzystaniem technik uczenia maszynowego[laboratoria]", "title": "Systemy Dialogowe", "year": "2021" }, "nbformat": 4, "nbformat_minor": 4 -} \ No newline at end of file +} diff --git a/lab/utils/state.py b/lab/utils/state.py new file mode 100644 index 0000000..fa9f63e --- /dev/null +++ b/lab/utils/state.py @@ -0,0 +1,25 @@ +def default_state(): + state = dict(user_action=[], + system_action=[], + belief_state={}, + request_state={}, + terminated=False, + history=[]) + state['belief_state'] = { + "cinema": { + "book": { + "title": "", + "date": "", + "time": "", + "quantity": "", + "seats": "", + "area": "", + "interval": "", + }, + "semi": { + "goal": "" + } + }, + + } + return state diff --git a/lab/utils/value_dict.json b/lab/utils/value_dict.json new file mode 100644 index 0000000..ce6888b --- /dev/null +++ b/lab/utils/value_dict.json @@ -0,0 +1,507 @@ +{ + "train": { + "time": [ + "05:51", + "07:51", + "09:51", + "11:51", + "13:51", + "15:51", + "17:51", + "19:51", + "21:51", + "23:51", + "06:08", + "08:08", + "10:08", + "12:08", + "14:08", + "16:08", + "18:08", + "20:08", + "22:08", + "24:08", + "07:27", + "09:27", + "11:27", + "13:27", + "15:27", + "17:27", + "19:27", + "21:27", + "23:27", + "01:27", + "07:07", + "09:07", + "11:07", + "13:07", + "15:07", + "17:07", + "19:07", + "21:07", + "23:07", + "01:07", + "05:58", + "06:58", + "07:58", + "08:58", + "09:58", + "10:58", + "11:58", + "12:58", + "13:58", + "14:58", + "15:58", + "16:58", + "17:58", + "18:58", + "19:58", + "20:58", + "21:58", + "22:58", + "23:58", + "06:55", + "07:55", + "08:55", + "09:55", + "10:55", + "11:55", + "12:55", + "13:55", + "14:55", + "15:55", + "16:55", + "17:55", + "18:55", + "19:55", + "20:55", + "21:55", + "22:55", + "23:55", + "24:55", + "06:35", + "07:35", + "08:35", + "09:35", + "10:35", + "11:35", + "12:35", + "13:35", + "14:35", + "15:35", + "16:35", + "17:35", + "18:35", + "19:35", + "20:35", + "21:35", + "22:35", + "23:35", + "24:35", + "05:56", + "06:24", + "06:56", + "07:24", + "07:56", + "08:24", + "08:56", + "09:24", + "09:56", + "10:24", + "10:56", + "11:24", + "11:56", + "12:24", + "12:56", + "13:24", + "13:56", + "14:24", + "14:56", + "15:24", + "15:56", + "16:24", + "16:56", + "17:24", + "17:56", + "18:24", + "18:56", + "19:24", + "19:56", + "20:24", + "20:56", + "21:24", + "21:56", + "22:24", + "22:56", + "23:24", + "23:56", + "24:24", + "06:09", + "06:38", + "07:09", + "07:38", + "08:09", + "08:38", + "09:09", + "09:38", + "10:09", + "10:38", + "11:09", + "11:38", + "12:09", + "12:38", + "13:09", + "13:38", + "14:09", + "14:38", + "15:09", + "15:38", + "16:09", + "16:38", + "17:09", + "17:38", + "18:09", + "18:38", + "19:09", + "19:38", + "20:09", + "20:38", + "21:09", + "21:38", + "22:09", + "22:38", + "23:09", + "23:38", + "24:09", + "24:38", + "06:07", + "08:07", + "10:07", + "12:07", + "14:07", + "16:07", + "18:07", + "20:07", + "22:07", + "24:07", + "05:52", + "07:52", + "09:52", + "11:52", + "13:52", + "15:52", + "17:52", + "19:52", + "21:52", + "23:52", + "07:08", + "09:08", + "11:08", + "13:08", + "15:08", + "17:08", + "19:08", + "21:08", + "23:08", + "06:52", + "08:52", + "10:52", + "12:52", + "14:52", + "16:52", + "18:52", + "20:52", + "22:52", + "07:06", + "08:06", + "09:06", + "10:06", + "11:06", + "12:06", + "13:06", + "14:06", + "15:06", + "16:06", + "17:06", + "18:06", + "19:06", + "20:06", + "21:06", + "22:06", + "23:06", + "24:06", + "01:06", + "06:54", + "07:54", + "08:54", + "09:54", + "10:54", + "11:54", + "12:54", + "13:54", + "14:54", + "15:54", + "16:54", + "17:54", + "18:54", + "19:54", + "20:54", + "21:54", + "22:54", + "23:54", + "24:54", + "07:44", + "08:44", + "09:44", + "10:44", + "11:44", + "12:44", + "13:44", + "14:44", + "15:44", + "16:44", + "17:44", + "18:44", + "19:44", + "20:44", + "21:44", + "22:44", + "23:44", + "24:44", + "01:44", + "08:23", + "09:23", + "10:23", + "11:23", + "12:23", + "13:23", + "14:23", + "15:23", + "16:23", + "17:23", + "18:23", + "19:23", + "20:23", + "21:23", + "22:23", + "23:23", + "24:23", + "01:23", + "02:23", + "06:01", + "07:01", + "08:01", + "09:01", + "10:01", + "11:01", + "12:01", + "13:01", + "14:01", + "15:01", + "16:01", + "17:01", + "18:01", + "19:01", + "20:01", + "21:01", + "22:01", + "23:01", + "24:01", + "06:32", + "07:32", + "08:32", + "09:32", + "10:32", + "11:32", + "12:32", + "13:32", + "14:32", + "15:32", + "16:32", + "17:32", + "18:32", + "19:32", + "20:32", + "21:32", + "22:32", + "23:32", + "24:32", + "06:10", + "08:10", + "10:10", + "12:10", + "14:10", + "16:10", + "18:10", + "20:10", + "22:10", + "24:10", + "06:43", + "08:43", + "10:43", + "12:43", + "14:43", + "16:43", + "18:43", + "20:43", + "22:43", + "24:43", + "pierwszą", + "drugą", + "trzecią", + "piątą", + "szóstą", + "siódmą", + "ósmą", + "dziewiatą", + "dziesiątą", + "jedenastą", + "dwunastą", + "trzynastą", + "czternastą", + "piętnastą", + "szesnastą", + "siedemnastą", + "osiemnastą", + "dziewiętnastą", + "dwudziestą pierwszą", + "dwudziestą drugą", + "dwudziestą trzecią", + "dwudziestą czwartą", + "o północy" + ], + "date": [ + "w najbliższy poniedziałek", + "w najbliższy wtorek", + "w najbliższą środę", + "w najbliższy czwartek", + "w najbliższy piątek", + "w najbliższą sobotę", + "w najbliższą niedzielę", + "w poniedziałek", + "we wtorek", + "w środę", + "w czwartek", + "w piątek", + "w sobotę", + "w niedzielę", + "na najbliższy poniedziałek", + "na najbliższy wtorek", + "na najbliższą środę", + "na najbliższy czwartek", + "na najbliższy piątek", + "na najbliższą sobotę", + "na najbliższą niedzielę", + "najbliższy poniedziałek", + "najbliższy wtorek", + "najbliższa środa", + "najbliższy czwartek", + "najbliższy piątek", + "najbliższa sobota", + "najbliższa niedziela", + "na jutro", + "jutro", + "w dniu jutrzejszym", + "po jutrze", + "pojutrze", + "za dwa dni", + "za trzy dni", + "za tydzień", + "dzisiaj", + "dziś", + "na dzień 21/09", + "na 21/09", + "dzień 21/09", + "dnia 21/09", + "21/09", + "12/09", + "5/09", + "21/12", + "12/12", + "5/12", + "21/3", + "12/3", + "5/3" + ], + "quantities" : [ + "1", + "2", + "3", + "4", + "5", + "6", + "7", + "8", + "9", + "10", + "11", + "12", + "13", + "14", + "15", + "16", + "17", + "18", + "19", + "20", + "jeden", + "dwa", + "trzy", + "cztery", + "pięć", + "sześć", + "siedem", + "osiem", + "dziewięć", + "dziesięć", + "jedenaście", + "dwanaście", + "trzynaście" + ], + "seats" : [ + "a1", + "a1 a2", + "a1 a2 a3", + "a1 a2 a3 a4", + "a1 a2 a3 a4 a5", + "h1", + "h1 h2", + "h1 h2 h3", + "h1 h2 h3 h4", + "h1 h2 h3 h4 h5", + "a12", + "a11 a12", + "a11 a12 a13", + "a11 a12 a13 a14", + "a11 a12 a13 a14 a15" + ], + "areas" : [ + "u góry po prawej", + "u góry po lewej", + "u góry na środku", + "na środku po prawej", + "na środku po lewej", + "na dole po prawej", + "na dole po lewej", + "na dole na środku", + "po lewej", + "po prawej", + "na środku", + "lewo", + "prawo", + "środek", + "blisko od ekranu", + "daleko od ekranu", + "blisko ekranu", + "daleko ekranu" + ], + "interval" : [ + "rano", + "wieczorem", + "w południe", + "po południu", + "popołudniu", + "w nocy" + ] + } +} \ No newline at end of file diff --git a/src/components/DST.py b/src/components/DST.py index 1e99228..cb23947 100644 --- a/src/components/DST.py +++ b/src/components/DST.py @@ -1,22 +1,61 @@ -# Adrian class DST: - def __init__(self, slots): - self.slots = slots - def getDialogueState(self, userActs): - # iterate over speech acts - if userActs['act'] == 'book': - if userActs['slots']: - for (k, v) in userActs['slots']: - print(k) - if k in self.slots: - self.slots[k] = v + def __init__(self): + self.init_session() + # self.value_dict = json.load(open('utils/value_dict.json')) - # returns all slots - return self.slots + def update(self, user_act=None): + for intent, domain, slot, value in user_act: + domain = domain.lower() + intent = intent.lower() + value = value.lower() + k = slot -#dst = DST() -# userActs = {'inform': {'name': 'edyta', 'age': 18}, 'reqmore': {'date', 'time'}} -#ivona_acts = {'act': 'book', 'slots': [('name', 'ewa'), ('hour', 'dziesiąta'), ('size', 'trzech')]} -#print(dst.getDialogueState(ivona_acts)) + if intent == 'inform': + + domain_dic = self.state['belief_state'][domain] + + if k in domain_dic['semi']: + self.state['belief_state'][domain]['semi'][k] = value + elif k in domain_dic['book']: + self.state['belief_state'][domain]['book'][k] = value + elif k.lower() in domain_dic['book']: + self.state['belief_state'][domain]['book'][k.lower()] = value + elif intent == 'request': + + if domain not in self.state['request_state']: + self.state['request_state'][domain] = {} + if k not in self.state['request_state'][domain]: + self.state['request_state'][domain][k] = 0 + + return self.state + + def init_session(self): + self.state = self.default_state() + + def default_state(self): + state = dict(user_action=[], + system_action=[], + belief_state={}, + request_state={}, + terminated=False, + history=[]) + state['belief_state'] = { + "cinema": { + "book": { + "title": "", + "date": "", + "time": "", + "quantity": "", + "seats": "", + "area": "", + "interval": "", + }, + "semi": { + "goal": "" + } + }, + + } + return state diff --git a/src/components/NLU.py b/src/components/NLU.py index fd2665b..9c2f4e9 100644 --- a/src/components/NLU.py +++ b/src/components/NLU.py @@ -13,7 +13,7 @@ class NLU: csentence = [{'form': word} for word in sentence] fsentence = self.conllu2flair([csentence])[0] self.nluModel.predict(fsentence) - return [(token, ftoken.get_tag('slot').value) for token, ftoken in zip(sentence, fsentence)] + return self.toDSTInput([(token, ftoken.get_tag('slot').value) for token, ftoken in zip(sentence, fsentence)]) def conllu2flair(self, sentences, label=None): fsentences = [] @@ -40,4 +40,34 @@ class NLU: # new_str = re.sub(' +', ' ', new_str) for char in punctuation: messageLower = messageLower.replace(char,'') - return messageLower.split() \ No newline at end of file + return messageLower.split() + + def toDSTInput(self, taggedSentence): + result = [] + intent = None + slotValue = None + slot = None + for tuple in taggedSentence: + value, tagInt = tuple + if intent is None: intent = tagInt.split("/")[1] + if tagInt.split("/")[0] == "O": + if slotValue is not None: + result.append([intent, 'Cinema', slot, slotValue]) + slot = None + slotValue = None + elif tagInt.split("/")[0].split("-")[0] == "B": + slot = tagInt.split("/")[0].split("-")[1] + slotValue = value + elif tagInt.split("/")[0].split("-")[0] == "I": + try: + slotValue += " " + value + except: + slot = tagInt.split("/")[0].split("-")[1] + slotValue = value + + if slotValue is not None: + result.append([intent, 'Cinema', slot, slotValue]) + return result + + + diff --git a/src/dialogue_system.py b/src/dialogue_system.py index b8b6b50..9de65ca 100644 --- a/src/dialogue_system.py +++ b/src/dialogue_system.py @@ -2,23 +2,13 @@ from components.NLU import NLU from components.NLG import NLG from components.DST import DST -slots = [ - ("title", None), - ("date", None), - ("time", None), - ("quantity", None), - ("seats", None), - ("goal", None), - ("area", None), - ("interval", None), -] - def chatbot(): isActive = True # NLU nlu = NLU() + dst = DST() # hello message print("wpisz /exit aby zakończyć") @@ -32,5 +22,6 @@ def chatbot(): isActive = False else: nluPred = nlu.predict(sentence=userMessage) - print(nluPred) + dst.update(nluPred) + print(dst.state) chatbot() \ No newline at end of file diff --git a/tasks/zad8/pl/train.conllu b/tasks/zad8/pl/train.conllu index 29391c2..5b96485 100644 --- a/tasks/zad8/pl/train.conllu +++ b/tasks/zad8/pl/train.conllu @@ -2941,7 +2941,7 @@ 4 moje inform NoLabel 5 miejsca inform NoLabel 6 to inform NoLabel -7 h1h3h56 inform NoLabel +7 h1h3h56 inform B-seats # text: wymień seansy jutro # intent: inform