SystemyDialogowe-ProjektMag.../lab/09-zarzadzanie-dialogiem-reguly.ipynb

973 lines
46 KiB
Plaintext
Raw Normal View History

2022-05-05 19:58:00 +02:00
{
"cells": [
{
"cell_type": "markdown",
"metadata": {
"collapsed": false
},
"source": [
"![Logo 1](https://git.wmi.amu.edu.pl/AITech/Szablon/raw/branch/master/Logotyp_AITech1.jpg)\n",
"<div class=\"alert alert-block alert-info\">\n",
"<h1> Systemy Dialogowe </h1>\n",
2022-05-26 15:26:58 +02:00
"<h2> 9. <i>Zarządzanie dialogiem z wykorzystaniem reguł</i> [laboratoria]</h2> \n",
2022-05-05 19:58:00 +02:00
"<h3> Marek Kubis (2021)</h3>\n",
"</div>\n",
"\n",
"![Logo 2](https://git.wmi.amu.edu.pl/AITech/Szablon/raw/branch/master/Logotyp_AITech2.jpg)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
2022-05-26 15:26:58 +02:00
"Zarządzanie dialogiem z wykorzystaniem reguł\n",
2022-05-05 19:58:00 +02:00
"============================================\n",
"\n",
2022-05-26 15:26:58 +02:00
"Agent dialogowy wykorzystuje do zarządzanie dialogiem dwa moduły:\n",
2022-05-05 19:58:00 +02:00
"\n",
2022-05-26 15:26:58 +02:00
" - monitor stanu dialogu (dialogue state tracker, DST) — moduł odpowiedzialny za śledzenie stanu dialogu.\n",
2022-05-05 19:58:00 +02:00
"\n",
2022-05-26 15:26:58 +02:00
" - 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",
2022-05-05 19:58:00 +02:00
"\n",
2022-05-26 15:26:58 +02:00
"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",
2022-05-05 19:58:00 +02:00
"\n",
2022-05-26 15:26:58 +02:00
"Przykład\n",
2022-05-05 19:58:00 +02:00
"--------\n",
"\n",
2022-05-26 15:26:58 +02:00
"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",
2022-05-05 19:58:00 +02:00
"\n",
2022-05-26 15:26:58 +02:00
"**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",
2022-05-05 19:58:00 +02:00
"\n",
"```\n",
"sudo add-apt-repository ppa:deadsnakes/ppa\n",
"sudo apt update\n",
"sudo apt install python3.7 python3.7-dev python3.7-venv\n",
"```\n",
"\n",
2022-05-26 15:26:58 +02:00
"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",
2022-05-05 19:58:00 +02:00
"\n",
2022-05-26 15:26:58 +02:00
"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",
2022-05-05 19:58:00 +02:00
"\n",
"```\n",
2022-05-26 15:26:58 +02:00
"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",
2022-05-05 19:58:00 +02:00
"```\n",
"\n",
2022-05-26 15:26:58 +02:00
"Po skonfigurowaniu środowiska można przystąpić do instalacji *ConvLab-2*, korzystając z\n",
"następujących poleceń\n",
2022-05-05 19:58:00 +02:00
"\n",
"```\n",
"mkdir -p l08\n",
"cd l08\n",
"git clone https://github.com/thu-coai/ConvLab-2.git\n",
"cd ConvLab-2\n",
"pip install -e .\n",
"python -m spacy download en_core_web_sm\n",
"cd ../..\n",
"```\n",
"\n",
2022-05-26 15:26:58 +02:00
"Po zakończeniu instalacji należy ponownie uruchomić notatnik w powłoce, w której aktywne jest\n",
"środowisko wirtualne *convenv*.\n",
2022-05-05 19:58:00 +02:00
"\n",
"```\n",
"jupyter notebook 08-zarzadzanie-dialogiem-reguly.ipynb\n",
"```\n",
"\n",
2022-05-26 15:26:58 +02:00
"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",
2022-05-05 19:58:00 +02:00
"\n",
"### Monitor Stanu Dialogu\n",
"\n",
2022-05-26 15:26:58 +02:00
"Do reprezentowania stanu dialogu użyjemy struktury danych wykorzystywanej w *ConvLab-2*."
2022-05-05 19:58:00 +02:00
]
},
{
"cell_type": "code",
2022-05-26 15:26:58 +02:00
"execution_count": 3,
2022-05-05 19:58:00 +02:00
"metadata": {},
2022-05-26 15:26:58 +02:00
"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"
}
],
2022-05-05 19:58:00 +02:00
"source": [
2022-05-26 15:26:58 +02:00
"# from convlab2.util.multiwoz.state import default_state\n",
"from utils.state import default_state\n",
2022-05-05 19:58:00 +02:00
"default_state()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
2022-05-26 15:26:58 +02:00
"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",
2022-05-05 19:58:00 +02:00
"`request_state`.\n"
]
},
{
"cell_type": "code",
2022-05-26 15:26:58 +02:00
"execution_count": 34,
2022-05-05 19:58:00 +02:00
"metadata": {},
2022-05-26 15:26:58 +02:00
"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"
}
],
2022-05-05 19:58:00 +02:00
"source": [
"import json\n",
"import os\n",
"from convlab2.dst.dst import DST\n",
"from convlab2.dst.rule.multiwoz.dst_util import normalize_value\n",
"from convlab2.util.multiwoz.multiwoz_slot_trans import REF_SYS_DA\n",
"\n",
2022-05-26 15:26:58 +02:00
"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",
2022-05-05 19:58:00 +02:00
"\n",
2022-05-26 15:26:58 +02:00
" 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",
2022-05-05 19:58:00 +02:00
"class 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",
2022-05-26 15:26:58 +02:00
" self.state = default_state()\n",
"'''\n"
2022-05-05 19:58:00 +02:00
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
2022-05-26 15:26:58 +02:00
"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",
2022-05-05 19:58:00 +02:00
"\n",
2022-05-26 15:26:58 +02:00
" - nazwy aktu użytkownika,\n",
" - nazwy dziedziny, której dotyczy wypowiedź,\n",
2022-05-05 19:58:00 +02:00
" - nazwy slotu,\n",
2022-05-26 15:26:58 +02:00
" - wartości slotu.\n",
2022-05-05 19:58:00 +02:00
"\n",
2022-05-26 15:26:58 +02:00
"Zobaczmy na kilku prostych przykładach jak stan dialogu zmienia się pod wpływem przekazanych aktów\n",
"użytkownika."
2022-05-05 19:58:00 +02:00
]
},
{
"cell_type": "code",
2022-05-26 15:26:58 +02:00
"execution_count": 35,
2022-05-05 19:58:00 +02:00
"metadata": {
"lines_to_next_cell": 0
},
2022-05-26 15:26:58 +02:00
"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"
}
],
2022-05-05 19:58:00 +02:00
"source": [
"dst = SimpleRuleDST()\n",
"dst.state"
]
},
{
"cell_type": "code",
2022-05-26 15:26:58 +02:00
"execution_count": 36,
2022-05-05 19:58:00 +02:00
"metadata": {
"lines_to_next_cell": 0
},
2022-05-26 15:26:58 +02:00
"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"
}
],
2022-05-05 19:58:00 +02:00
"source": [
2022-05-26 15:26:58 +02:00
"dst.update([['Inform', 'Cinema', 'time', '15:00'], ['Inform', 'Cinema', 'title', 'Batman']])\n",
"dst.state['belief_state']['cinema']"
2022-05-05 19:58:00 +02:00
]
},
{
"cell_type": "code",
2022-05-26 15:26:58 +02:00
"execution_count": 37,
2022-05-05 19:58:00 +02:00
"metadata": {
"lines_to_next_cell": 0
},
2022-05-26 15:26:58 +02:00
"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"
}
],
2022-05-05 19:58:00 +02:00
"source": [
2022-05-26 15:26:58 +02:00
"dst.update([['Inform', 'Cinema', 'area', 'na górze na środku']])\n",
"dst.state['belief_state']['cinema']"
2022-05-05 19:58:00 +02:00
]
},
{
"cell_type": "code",
2022-05-26 15:26:58 +02:00
"execution_count": 38,
2022-05-05 19:58:00 +02:00
"metadata": {
"lines_to_next_cell": 0
},
2022-05-26 15:26:58 +02:00
"outputs": [
{
"data": {
"text/plain": [
"{'cinema': {'date': 0}}"
]
},
"execution_count": 38,
"metadata": {},
"output_type": "execute_result"
}
],
2022-05-05 19:58:00 +02:00
"source": [
2022-05-26 15:26:58 +02:00
"dst.update([['Request', 'Cinema', 'date', '?']])\n",
2022-05-05 19:58:00 +02:00
"dst.state['request_state']"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"lines_to_next_cell": 0
},
2022-05-26 15:26:58 +02:00
"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'"
]
}
],
2022-05-05 19:58:00 +02:00
"source": [
"dst.update([['Inform', 'Hotel', 'Day', 'tuesday'], ['Inform', 'Hotel', 'People', '2'], ['Inform', 'Hotel', 'Stay', '4']])\n",
"dst.state['belief_state']['hotel']"
]
},
{
"cell_type": "code",
2022-05-26 15:26:58 +02:00
"execution_count": 39,
2022-05-05 19:58:00 +02:00
"metadata": {},
2022-05-26 15:26:58 +02:00
"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"
}
],
2022-05-05 19:58:00 +02:00
"source": [
"dst.state"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Taktyka Prowadzenia Dialogu\n",
"\n",
2022-05-26 15:26:58 +02:00
"Prosta taktyka prowadzenia dialogu dla systemu rezerwacji pokoi hotelowych może składać się z następujących reguł:\n",
2022-05-05 19:58:00 +02:00
"\n",
2022-05-26 15:26:58 +02:00
" 1. Jeżeli użytkownik przekazał w ostatniej turze akt typu `Request`, to udziel odpowiedzi na jego\n",
2022-05-05 19:58:00 +02:00
" pytanie.\n",
"\n",
2022-05-26 15:26:58 +02:00
" 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",
2022-05-05 19:58:00 +02:00
"\n",
2022-05-26 15:26:58 +02:00
" 3. Jeżeli użytkownik przekazał w ostatniej turze akt typu `Inform` zawierający szczegóły\n",
" rezerwacji, to zarezerwuj pokój.\n",
2022-05-05 19:58:00 +02:00
"\n",
2022-05-26 15:26:58 +02:00
"Metoda `predict` taktyki `SimpleRulePolicy` realizuje reguły przedstawione powyżej."
2022-05-05 19:58:00 +02:00
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
2022-05-26 15:26:58 +02:00
"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'"
]
}
],
2022-05-05 19:58:00 +02:00
"source": [
"from collections import defaultdict\n",
"import copy\n",
"import json\n",
"from copy import deepcopy\n",
"\n",
"from convlab2.policy.policy import Policy\n",
"from convlab2.util.multiwoz.dbquery import Database\n",
"from convlab2.util.multiwoz.multiwoz_slot_trans import REF_SYS_DA, REF_USR_DA\n",
"\n",
"\n",
"class SimpleRulePolicy(Policy):\n",
" def __init__(self):\n",
" Policy.__init__(self)\n",
" self.db = Database()\n",
"\n",
" def predict(self, state):\n",
" self.results = []\n",
" system_action = defaultdict(list)\n",
" user_action = defaultdict(list)\n",
"\n",
" for intent, domain, slot, value in state['user_action']:\n",
" user_action[(domain, intent)].append((slot, value))\n",
"\n",
" for user_act in user_action:\n",
" self.update_system_action(user_act, user_action, state, system_action)\n",
"\n",
2022-05-26 15:26:58 +02:00
" # Reguła 3\n",
2022-05-05 19:58:00 +02:00
" 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",
"\n",
" system_acts = [[intent, domain, slot, value] for (domain, intent), slots in system_action.items() for slot, value in slots]\n",
" state['system_action'] = system_acts\n",
" return system_acts\n",
"\n",
" def update_system_action(self, user_act, user_action, state, system_action):\n",
" domain, intent = user_act\n",
" 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",
2022-05-26 15:26:58 +02:00
" # Reguła 1\n",
2022-05-05 19:58:00 +02:00
" if intent == 'Request':\n",
" if len(self.results) == 0:\n",
" system_action[(domain, 'NoOffer')] = []\n",
" else:\n",
" for slot in user_action[user_act]:\n",
" kb_slot_name = REF_SYS_DA[domain].get(slot[0], slot[0])\n",
"\n",
" 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",
2022-05-26 15:26:58 +02:00
" # Reguła 2\n",
2022-05-05 19:58:00 +02:00
" elif intent == 'Inform':\n",
" if len(self.results) == 0:\n",
" system_action[(domain, 'NoOffer')] = []\n",
" else:\n",
" system_action[(domain, 'Inform')].append(['Choice', str(len(self.results))])\n",
" choice = self.results[0]\n",
"\n",
" if domain in [\"Hotel\", \"Attraction\", \"Police\", \"Restaurant\"]:\n",
" system_action[(domain, 'Recommend')].append(['Name', choice['name']])"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
2022-05-26 15:26:58 +02:00
"Podobnie jak w przypadku aktów użytkownika akty systemowe przekazywane do modułu NLG są czteroelementowymi listami złożonymi z:\n",
2022-05-05 19:58:00 +02:00
"\n",
" - nazwy aktu systemowe,\n",
2022-05-26 15:26:58 +02:00
" - nazwy dziedziny, której dotyczy wypowiedź,\n",
2022-05-05 19:58:00 +02:00
" - nazwy slotu,\n",
2022-05-26 15:26:58 +02:00
" - wartości slotu.\n",
2022-05-05 19:58:00 +02:00
"\n",
2022-05-26 15:26:58 +02:00
"Sprawdźmy jakie akty systemowe zwraca taktyka `SimpleRulePolicy` w odpowiedzi na zmieniający się stan dialogu."
2022-05-05 19:58:00 +02:00
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"lines_to_next_cell": 0
},
2022-05-26 15:26:58 +02:00
"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'"
]
}
],
2022-05-05 19:58:00 +02:00
"source": [
"from convlab2.dialog_agent import PipelineAgent\n",
"dst.init_session()\n",
"policy = SimpleRulePolicy()\n",
"agent = PipelineAgent(nlu=None, dst=dst, policy=policy, nlg=None, name='sys')"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"lines_to_next_cell": 0
},
2022-05-26 15:26:58 +02:00
"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'"
]
}
],
2022-05-05 19:58:00 +02:00
"source": [
"agent.response([['Inform', 'Hotel', 'Price', 'cheap'], ['Inform', 'Hotel', 'Parking', 'yes']])"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"lines_to_next_cell": 0
},
2022-05-26 15:26:58 +02:00
"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'"
]
}
],
2022-05-05 19:58:00 +02:00
"source": [
"agent.response([['Inform', 'Hotel', 'Area', 'north']])"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"lines_to_next_cell": 0
},
2022-05-26 15:26:58 +02:00
"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'"
]
}
],
2022-05-05 19:58:00 +02:00
"source": [
"agent.response([['Request', 'Hotel', 'Area', '?']])"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
2022-05-26 15:26:58 +02:00
"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'"
]
}
],
2022-05-05 19:58:00 +02:00
"source": [
"agent.response([['Inform', 'Hotel', 'Day', 'tuesday'], ['Inform', 'Hotel', 'People', '2'], ['Inform', 'Hotel', 'Stay', '4']])"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Testy End-to-End\n",
"\n",
2022-05-26 15:26:58 +02:00
"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`."
2022-05-05 19:58:00 +02:00
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
2022-05-26 15:26:58 +02:00
"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'"
]
}
],
2022-05-05 19:58:00 +02:00
"source": [
"from convlab2.nlu.svm.multiwoz import SVMNLU\n",
"from convlab2.nlg.template.multiwoz import TemplateNLG\n",
"\n",
"nlu = SVMNLU()\n",
"nlg = TemplateNLG(is_user=False)\n",
"agent = PipelineAgent(nlu=nlu, dst=dst, policy=policy, nlg=nlg, name='sys')"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"lines_to_next_cell": 0
},
2022-05-26 15:26:58 +02:00
"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'"
]
}
],
2022-05-05 19:58:00 +02:00
"source": [
"agent.response(\"I need a cheap hotel with free parking .\")"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"lines_to_next_cell": 0
},
2022-05-26 15:26:58 +02:00
"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'"
]
}
],
2022-05-05 19:58:00 +02:00
"source": [
"agent.response(\"Where it is located ?\")"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"lines_to_next_cell": 0
},
2022-05-26 15:26:58 +02:00
"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'"
]
}
],
2022-05-05 19:58:00 +02:00
"source": [
"agent.response(\"I would prefer the hotel be in the north part of town .\")"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
2022-05-26 15:26:58 +02:00
"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'"
]
}
],
2022-05-05 19:58:00 +02:00
"source": [
"agent.response(\"Yeah , could you book me a room for 2 people for 4 nights starting Tuesday ?\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
2022-05-26 15:26:58 +02:00
"Zauważmy, ze nasza prosta taktyka dialogowa zawiera wiele luk, do których należą m.in.:\n",
2022-05-05 19:58:00 +02:00
"\n",
2022-05-26 15:26:58 +02:00
" 1. Niezdolność do udzielenia odpowiedzi na przywitanie, prośbę o pomoc lub restart.\n",
2022-05-05 19:58:00 +02:00
"\n",
2022-05-26 15:26:58 +02:00
" 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",
2022-05-05 19:58:00 +02:00
"\n",
2022-05-26 15:26:58 +02:00
"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",
2022-05-05 19:58:00 +02:00
"\n",
"Zadania\n",
"-------\n",
2022-05-26 15:26:58 +02:00
" 1. Zaimplementować w projekcie monitor stanu dialogu.\n",
2022-05-05 19:58:00 +02:00
"\n",
2022-05-26 15:26:58 +02:00
" 2. Zaimplementować w projekcie taktykę prowadzenia dialogu.\n",
2022-05-05 19:58:00 +02:00
"\n",
"Termin: 24.05.2021, godz. 23:59.\n",
"\n",
"Literatura\n",
"----------\n",
2022-05-26 15:26:58 +02:00
" 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"
2022-05-05 19:58:00 +02:00
]
}
],
"metadata": {
2022-05-26 15:26:58 +02:00
"author": "Marek Kubis",
"email": "mkubis@amu.edu.pl",
"interpreter": {
"hash": "91e2b0d1baa6ebb76863bdb1d11380bf032a6a1fc1b919194f041a5133852891"
},
2022-05-05 19:58:00 +02:00
"jupytext": {
"cell_metadata_filter": "-all",
"main_language": "python",
"notebook_metadata_filter": "-all"
},
2022-05-26 15:26:58 +02:00
"kernelspec": {
"display_name": "Python 3.7.9 ('venv': venv)",
"language": "python",
"name": "python3"
},
2022-05-05 19:58:00 +02:00
"lang": "pl",
2022-05-26 15:26:58 +02:00
"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]",
2022-05-05 19:58:00 +02:00
"title": "Systemy Dialogowe",
"year": "2021"
},
"nbformat": 4,
"nbformat_minor": 4
2022-05-26 15:26:58 +02:00
}