Generic_DialogSystem/DialogManager.ipynb

9.2 KiB

import json
import os


class DST():
    def __init__(self):
        self.state = json.load(open('dictionary.json'))

    def update(self, user_act=None):
        for intent, domain, slot, value in user_act:
            domain = domain.lower()
            intent = intent.lower()
            slot = slot.lower()
            
            if domain not in self.state['belief_state']:
                continue

            if intent == 'inform':
                if slot == 'none' or slot == '':
                    continue

                domain_dic = self.state['belief_state'][domain]

                if slot in domain_dic:
                    self.state['belief_state'][domain][slot] = value

            elif intent == 'request':
                if domain not in self.state['request_state']:
                    self.state['request_state'][domain] = {}
                if slot not in self.state['request_state'][domain]:
                    self.state['request_state'][domain][slot] = 0
                    
        self.state['user_act'] = user_act
        return self.state
    def init_session(self):
            self.state = json.load(open('dictionary.json'))
dst = DST()
user_act = [('inform', 'payment', 'type', 'karta'),  ('inform', 'delivery', 'type','paczkomat'), ('inform', 'product', 'type', 'telefon'), ('request', 'product', 'type', '?')]
state = dst.update(user_act)
print(state['belief_state'])
print(state['request_state'])
dst.state
{'payment': {'type': 'karta', 'amount': '', 'loyalty_card': ''}, 'delivery': {'type': 'paczkomat', 'address': '', 'time': ''}, 'product': {'name': '', 'type': 'telefon', 'brand': '', 'price_range': '', 'price': '', 'quantity': '', 'quality': ''}}
{'product': {'type': 0}}
{'user_act': [('inform', 'payment', 'type', 'karta'),
  ('inform', 'delivery', 'type', 'paczkomat'),
  ('inform', 'product', 'type', 'telefon'),
  ('request', 'product', 'type', '?')],
 'system_act': [],
 'belief_state': {'payment': {'type': 'karta',
   'amount': '',
   'loyalty_card': ''},
  'delivery': {'type': 'paczkomat', 'address': '', 'time': ''},
  'product': {'name': '',
   'type': 'telefon',
   'brand': '',
   'price_range': '',
   'price': '',
   'quantity': '',
   'quality': ''}},
 'request_state': {'product': {'type': 0}},
 'terminated': False,
 'history': []}
from collections import defaultdict
from convlab.policy.policy import Policy
import json

class SimpleRulePolicy(Policy):
    def __init__(self):
        Policy.__init__(self)
        self.db = json.load(open('product_db.json'))

    def predict(self, state):
        self.results = []
        system_action = defaultdict(list)
        user_action = defaultdict(list)
        system_acts = []
        for intent, domain, slot, value in state['user_act']:
            user_action[(domain.lower(), intent.lower())].append((slot.lower(), value))
        for user_act in user_action:
            self.update_system_action(user_act, user_action, state, system_action)
        system_acts = [[intent, domain, slot, value] for (domain, intent), slots in system_action.items() for slot, value in slots]
        state['system_act'] = system_acts
        return system_acts


    def update_system_action(self, user_act, user_action, state, system_action):
        domain, intent = user_act
        constraints = [(slot, value) for slot, value in state['belief_state'][domain.lower()].items() if value != '']
        self.results = self.db['database'][domain]

        # Reguła 1
        if intent == 'request':
            if len(self.results) == 0:
                system_action[(domain, 'NoOffer')] = []
            else:
                for slot in user_action[user_act]:
                    if self.results and slot[0] in self.results[0]:
                        system_action[(domain, 'Inform')].append([slot[0], self.results[0].get(slot[0], 'unknown')])

        # Reguła 2
        elif intent == 'inform':
            if len(self.results) == 0:
                system_action[(domain, 'NoOffer')] = []
            else:
                system_action[(domain, 'Inform')].append(['Choice', str(len(self.results))])
                for product in self.results:
                    if all(product.get(slot, '').lower() == value.lower() for slot, value in constraints):
                        system_action[(domain, 'Recommend')].append(['Name', product['name']])
                        break

dst = DST()
user_act = [('inform', 'product', 'type', 'energol')]
state = dst.update(user_act)
policy = SimpleRulePolicy()
policy.predict(state)
[['Inform', 'product', 'Choice', '11'],
 ['Recommend', 'product', 'Name', 'RedBull']]
from convlab.dialog_agent import PipelineAgent
policy = SimpleRulePolicy()
agent = PipelineAgent(nlu=None, dst=dst, policy=policy, nlg=None, name='sys')
WARNING:root:nlu info_dict is not initialized
WARNING:root:dst info_dict is not initialized
WARNING:root:policy info_dict is not initialized
WARNING:root:nlg info_dict is not initialized
agent.response([('inform', 'product', 'type', 'warzywo'), ('inform', 'product', 'price_range', 'tani'), ('inform', 'product', 'quality', 'exquisite')])
[['Inform', 'product', 'Choice', '11'],
 ['Recommend', 'product', 'Name', 'pomidor']]
agent.response([('inform', 'product', 'type', 'napój'), ('inform', 'product', 'price_range', 'drogi'), ('inform', 'product', 'quality', 'exquisite')])
[['Inform', 'product', 'Choice', '11'],
 ['Recommend', 'product', 'Name', 'Sok pomarańczowy']]
agent.response([('inform', 'product', 'type', 'owoc'), ('inform', 'product', 'price_range', 'tani'), ('inform', 'product', 'quality', 'exquisite')])
[['Inform', 'product', 'Choice', '11'],
 ['Recommend', 'product', 'Name', 'banan']]