Skip to content
Snippets Groups Projects
Unverified Commit db9ddd46 authored by Shahin Shayandeh's avatar Shahin Shayandeh Committed by GitHub
Browse files

Normalize string comparisons in multiwoz template nlg to be case insensitive (#87)

* normalize template nlg keys to be lower case

* fix slot comparison in multiwoz nlg to be case insensitive

* use value_lower instead of calling .lower() on each comparison
parent 33f40669
No related branches found
No related tags found
No related merge requests found
...@@ -6,13 +6,21 @@ import collections ...@@ -6,13 +6,21 @@ import collections
from convlab2.nlg import NLG from convlab2.nlg import NLG
def lower_keys(x):
if isinstance(x, list):
return [lower_keys(v) for v in x]
elif isinstance(x, dict):
return {k.lower(): lower_keys(v) for k, v in x.items()}
else:
return x
def read_json(filename): def read_json(filename):
with open(filename, 'r') as f: with open(filename, 'r') as f:
return json.load(f) return lower_keys(json.load(f))
# supported slot # supported slot
slot2word = { Slot2word = {
'Fee': 'fee', 'Fee': 'fee',
'Addr': 'address', 'Addr': 'address',
'Area': 'area', 'Area': 'area',
...@@ -43,6 +51,7 @@ slot2word = { ...@@ -43,6 +51,7 @@ slot2word = {
# 'TrainID': 'TrainID' # 'TrainID': 'TrainID'
} }
slot2word = dict((k.lower(), v.lower()) for k,v in Slot2word.items())
class TemplateNLG(NLG): class TemplateNLG(NLG):
def __init__(self, is_user, mode="manual"): def __init__(self, is_user, mode="manual"):
...@@ -105,9 +114,9 @@ class TemplateNLG(NLG): ...@@ -105,9 +114,9 @@ class TemplateNLG(NLG):
dialog_acts = self.sorted_dialog_act(dialog_acts) dialog_acts = self.sorted_dialog_act(dialog_acts)
action = collections.OrderedDict() action = collections.OrderedDict()
for intent, domain, slot, value in dialog_acts: for intent, domain, slot, value in dialog_acts:
k = '-'.join([domain, intent]) k = '-'.join([domain.lower(), intent.lower()])
action.setdefault(k, []) action.setdefault(k, [])
action[k].append([slot, value]) action[k].append([slot.lower(), value])
dialog_acts = action dialog_acts = action
mode = self.mode mode = self.mode
try: try:
...@@ -160,7 +169,7 @@ class TemplateNLG(NLG): ...@@ -160,7 +169,7 @@ class TemplateNLG(NLG):
sentences = '' sentences = ''
for dialog_act, slot_value_pairs in dialog_acts.items(): for dialog_act, slot_value_pairs in dialog_acts.items():
intent = dialog_act.split('-') intent = dialog_act.split('-')
if 'Select' == intent[1]: if 'select' == intent[1]:
slot2values = {} slot2values = {}
for slot, value in slot_value_pairs: for slot, value in slot_value_pairs:
slot2values.setdefault(slot, []) slot2values.setdefault(slot, [])
...@@ -176,7 +185,7 @@ class TemplateNLG(NLG): ...@@ -176,7 +185,7 @@ class TemplateNLG(NLG):
sentence += ' , ' + value sentence += ' , ' + value
sentence += ' {} ? '.format(slot2word[slot]) sentence += ' {} ? '.format(slot2word[slot])
sentences += sentence sentences += sentence
elif 'Request' == intent[1]: elif 'request' == intent[1]:
for slot, value in slot_value_pairs: for slot, value in slot_value_pairs:
if dialog_act not in template or slot not in template[dialog_act]: if dialog_act not in template or slot not in template[dialog_act]:
sentence = 'What is the {} of {} ? '.format(slot.lower(), dialog_act.split('-')[0].lower()) sentence = 'What is the {} of {} ? '.format(slot.lower(), dialog_act.split('-')[0].lower())
...@@ -191,31 +200,32 @@ class TemplateNLG(NLG): ...@@ -191,31 +200,32 @@ class TemplateNLG(NLG):
sentences += sentence sentences += sentence
else: else:
for slot, value in slot_value_pairs: for slot, value in slot_value_pairs:
value_lower = value.lower()
if value in ["do nt care", "do n't care", "dontcare"]: if value in ["do nt care", "do n't care", "dontcare"]:
sentence = 'I don\'t care about the {} of the {}'.format(slot.lower(), dialog_act.split('-')[0].lower()) sentence = 'I don\'t care about the {} of the {}'.format(slot, dialog_act.split('-')[0])
elif self.is_user and dialog_act.split('-')[1] == 'Inform' and slot == 'Choice' and value == 'any': elif self.is_user and dialog_act.split('-')[1] == 'inform' and slot == 'choice' and value_lower == 'any':
# user have no preference, any choice is ok # user have no preference, any choice is ok
sentence = random.choice([ sentence = random.choice([
"Please pick one for me. ", "Please pick one for me. ",
"Anyone would be ok. ", "Anyone would be ok. ",
"Just select one for me. " "Just select one for me. "
]) ])
elif slot == 'Price' and 'same price range' in value: elif slot == 'price' and 'same price range' in value_lower:
sentence = random.choice([ sentence = random.choice([
"it just needs to be {} .".format(value), "it just needs to be {} .".format(value),
"Oh , I really need something {} .".format(value), "Oh , I really need something {} .".format(value),
"I would prefer something that is {} .".format(value), "I would prefer something that is {} .".format(value),
"it needs to be {} .".format(value) "it needs to be {} .".format(value)
]) ])
elif slot in ['Internet', 'Parking'] and value == 'no': elif slot in ['internet', 'parking'] and value_lower == 'no':
sentence = random.choice([ sentence = random.choice([
"It does n't need to have {} .".format(slot.lower()), "It does n't need to have {} .".format(slot),
"I do n't need free {} .".format(slot.lower()), "I do n't need free {} .".format(slot),
]) ])
elif dialog_act in template and slot in template[dialog_act]: elif dialog_act in template and slot in template[dialog_act]:
sentence = random.choice(template[dialog_act][slot]) sentence = random.choice(template[dialog_act][slot])
sentence = sentence.replace('#{}-{}#'.format(dialog_act.upper(), slot.upper()), str(value)) sentence = sentence.replace('#{}-{}#'.format(dialog_act.upper(), slot.upper()), str(value))
elif slot == 'NotBook': elif slot == 'notbook':
sentence = random.choice([ sentence = random.choice([
"I do not need to book. ", "I do not need to book. ",
"I 'm not looking to make a booking at the moment." "I 'm not looking to make a booking at the moment."
...@@ -237,7 +247,7 @@ class TemplateNLG(NLG): ...@@ -237,7 +247,7 @@ class TemplateNLG(NLG):
key += s + ';' key += s + ';'
if dialog_act in template and key in template[dialog_act]: if dialog_act in template and key in template[dialog_act]:
sentence = random.choice(template[dialog_act][key]) sentence = random.choice(template[dialog_act][key])
if 'Request' in dialog_act or 'general' in dialog_act: if 'request' in dialog_act or 'general' in dialog_act:
sentence = self._postprocess(sentence) sentence = self._postprocess(sentence)
sentences += sentence sentences += sentence
else: else:
...@@ -254,6 +264,7 @@ class TemplateNLG(NLG): ...@@ -254,6 +264,7 @@ class TemplateNLG(NLG):
def example(): def example():
# dialog act # dialog act
dialog_acts = [['Inform', 'Hotel', 'Area', 'east'],['Inform', 'Hotel', 'Internet', 'no'], ['welcome', 'general', 'none', 'none']] dialog_acts = [['Inform', 'Hotel', 'Area', 'east'],['Inform', 'Hotel', 'Internet', 'no'], ['welcome', 'general', 'none', 'none']]
#dialog_acts = [['Inform', 'Restaurant', 'NotBook', 'none']]
print(dialog_acts) print(dialog_acts)
# system model for manual, auto, auto_manual # system model for manual, auto, auto_manual
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment