305 lines
16 KiB
Python
305 lines
16 KiB
Python
from modules.NLU import NLU
|
|
from modules.DST import DST
|
|
# from modules.DP import DP
|
|
from modules.NLG import NLG
|
|
import json
|
|
import re
|
|
import time
|
|
|
|
|
|
|
|
value_dict = json.load(open('modules/value_dict.json'))
|
|
|
|
def format_prediction(prediction, intent):
|
|
out_list = []
|
|
for idx, tup in enumerate(prediction):
|
|
if tup[1][0] == 'B':
|
|
slot_list = [intent, 'Cinema', tup[1][2:], tup[0]]
|
|
for tup in prediction[idx + 1:]:
|
|
if tup[1][0] != 'I':
|
|
break
|
|
else:
|
|
slot_list[3] += ' ' + tup[0]
|
|
out_list.append(slot_list)
|
|
for slot in out_list:
|
|
slot[3] = re.sub("^[!\"#$%&\'()*+,.;:<=>?\[\]^_`{|}~]+", '', slot[3])
|
|
slot[3] = re.sub("[!\"#$%&\'()*+,.;:<=>?\[\]^_`{|}~]+$", '', slot[3])
|
|
return out_list
|
|
|
|
def main():
|
|
nlu = NLU()
|
|
dst = DST()
|
|
# dp = DP()
|
|
nlg = NLG(dst)
|
|
|
|
#nlu.train_slot_model('data/train+test-pl.conllu', 'data/train+test-pl.conllu')
|
|
#nlu.train_intent_model('data/NLU_data_intent')
|
|
nlu.load_slot_model('slot-model-pl')
|
|
nlu.load_intent_model('intent-model-pl')
|
|
|
|
start = time.time()
|
|
turns = 0
|
|
|
|
print('===========================================')
|
|
print('### By otrzymać pomoc, wpisz /pomoc ###')
|
|
print('### By zakończyć rozmowę, wpisz /koniec ###')
|
|
print('### By rozpocząć rozmowę od początku, wpisz /reset ###')
|
|
print('### By podejrzeć stan dialogu, wpisz /dst ###')
|
|
print('Witaj, jestem Usher - system do rezerwacji biletów kinowych. W czym mogę Ci pomóc?')
|
|
|
|
# WIP
|
|
while True:
|
|
turns += 1
|
|
user_input = input('> ')
|
|
dst.state['history'].append(f"user\t{user_input}")
|
|
user_input_lr = user_input.lower()
|
|
flag = False
|
|
slots = nlu.predict_slots(user_input)
|
|
intent = nlu.predict_intent(user_input)
|
|
formatted_prediction = format_prediction(slots, intent)
|
|
for slot in formatted_prediction:
|
|
if len(formatted_prediction)<2:
|
|
if dst.state['system_action'][-1] != slot:
|
|
formatted_prediction.remove(slot)
|
|
formatted_prediction.append([slot[0],slot[1],dst.state['system_action'][-1][0][2],slot[3]])
|
|
if slot[2]=='seat':
|
|
if ',' in slot[3]:
|
|
seat,row = slot[3].split(',')
|
|
formatted_prediction.remove(['inform', 'Cinema', 'seat', slot[3]])
|
|
formatted_prediction.append(['inform', 'Cinema', 'seat', seat])
|
|
formatted_prediction.append(['inform', 'Cinema', 'row', f' {row}'])
|
|
if 'rzęd' in user_input_lr:
|
|
formatted_prediction_tmp = formatted_prediction.copy()
|
|
user_input_splited = user_input_lr.split()
|
|
for slots in formatted_prediction:
|
|
if slots[2] =='row' or slots[2]=='seat' or slots[2] =='quantity':
|
|
formatted_prediction_tmp.remove(slots)
|
|
formatted_prediction = formatted_prediction_tmp.copy()
|
|
if 'miejsc' not in user_input_lr and 'bilet' not in user_input_lr:
|
|
for i in range(len(user_input_splited)-1):
|
|
if 'rzęd' in user_input_splited[i]:
|
|
try:
|
|
if isinstance(int(user_input_splited[i+1]),int)and i==0:
|
|
formatted_prediction.append(['inform', 'Cinema', 'row', user_input_splited[i+1]])
|
|
elif isinstance(int(user_input_splited[i-1]),int):
|
|
formatted_prediction.append(['inform', 'Cinema', 'row', user_input_splited[i-1]])
|
|
except:
|
|
if isinstance(int(user_input_splited[i+1]),int):
|
|
formatted_prediction.append(['inform', 'Cinema', 'row', user_input_splited[i+1]])
|
|
elif 'miejsc' in user_input_lr and 'bilet' not in user_input_lr:
|
|
for i in range(len(user_input_splited)-1):
|
|
print(user_input_splited[i],user_input_splited[i+1])
|
|
if 'rzęd' in user_input_splited[i]:
|
|
try:
|
|
if isinstance(int(user_input_splited[i+1]),int)and i==0:
|
|
formatted_prediction.append(['inform', 'Cinema', 'row', user_input_splited[i+1]])
|
|
elif isinstance(int(user_input_splited[i-1]),int):
|
|
formatted_prediction.append(['inform', 'Cinema', 'row', user_input_splited[i-1]])
|
|
except:
|
|
if isinstance(int(user_input_splited[i+1]),int):
|
|
formatted_prediction.append(['inform', 'Cinema', 'row', user_input_splited[i+1]])
|
|
if 'miejsc' in user_input_splited[i]:
|
|
try:
|
|
if i==0 and isinstance(int(user_input_splited[i+1]),int):
|
|
formatted_prediction.append(['inform', 'Cinema', 'seat', user_input_splited[i+1]])
|
|
elif isinstance(int(user_input_splited[i-1]),int):
|
|
formatted_prediction.append(['inform', 'Cinema', 'seat', user_input_splited[i-1]])
|
|
except:
|
|
if isinstance(int(user_input_splited[i+1]),int):
|
|
formatted_prediction.append(['inform', 'Cinema', 'seat', user_input_splited[i+1]])
|
|
elif 'miejsc' not in user_input_lr and 'bilet' in user_input_lr:
|
|
for i in range(len(user_input_splited)-1):
|
|
print(user_input_splited[i],user_input_splited[i+1])
|
|
if 'rzęd' in user_input_splited[i]:
|
|
try:
|
|
if isinstance(int(user_input_splited[i+1]),int)and i==0:
|
|
formatted_prediction.append(['inform', 'Cinema', 'row', user_input_splited[i+1]])
|
|
elif isinstance(int(user_input_splited[i-1]),int):
|
|
formatted_prediction.append(['inform', 'Cinema', 'row', user_input_splited[i-1]])
|
|
except:
|
|
if isinstance(int(user_input_splited[i+1]),int):
|
|
formatted_prediction.append(['inform', 'Cinema', 'row', user_input_splited[i+1]])
|
|
if 'miejsc' in user_input_splited[i]:
|
|
try:
|
|
if i==0 and isinstance(int(user_input_splited[i+1]),int):
|
|
formatted_prediction.append(['inform', 'Cinema', 'quantity', user_input_splited[i+1]])
|
|
elif isinstance(int(user_input_splited[i-1]),int):
|
|
formatted_prediction.append(['inform', 'Cinema', 'quantity', user_input_splited[i-1]])
|
|
except:
|
|
if isinstance(int(user_input_splited[i+1]),int):
|
|
formatted_prediction.append(['inform', 'Cinema', 'quantity', user_input_splited[i+1]])
|
|
elif 'miejsc' in user_input_lr and 'bilet' in user_input_lr:
|
|
for i in range(len(user_input_splited)-1):
|
|
if 'rzęd' in user_input_splited[i]:
|
|
try:
|
|
if isinstance(int(user_input_splited[i+1]),int)and i==0:
|
|
formatted_prediction.append(['inform', 'Cinema', 'row', user_input_splited[i+1]])
|
|
elif isinstance(int(user_input_splited[i-1]),int):
|
|
formatted_prediction.append(['inform', 'Cinema', 'row', user_input_splited[i-1]])
|
|
except:
|
|
if isinstance(int(user_input_splited[i+1]),int):
|
|
formatted_prediction.append(['inform', 'Cinema', 'row', user_input_splited[i+1]])
|
|
if 'miejsc' in user_input_splited[i]:
|
|
try:
|
|
if isinstance(int(user_input_splited[i+1]),int) and i==0:
|
|
formatted_prediction.append(['inform', 'Cinema', 'seat', user_input_splited[i+1]])
|
|
elif isinstance(int(user_input_splited[i-1]),int):
|
|
formatted_prediction.append(['inform', 'Cinema', 'seat', user_input_splited[i-1]])
|
|
except:
|
|
if isinstance(int(user_input_splited[i+1]),int):
|
|
formatted_prediction.append(['inform', 'Cinema', 'seat', user_input_splited[i+1]])
|
|
if 'bilet' in user_input_splited[i]:
|
|
try:
|
|
if isinstance(int(user_input_splited[i+1]),int)and i==0:
|
|
formatted_prediction.append(['inform', 'Cinema', 'quantity', user_input_splited[i+1]])
|
|
elif isinstance(int(user_input_splited[i-1]),int):
|
|
formatted_prediction.append(['inform', 'Cinema', 'quantity', user_input_splited[i-1]])
|
|
except:
|
|
if isinstance(int(user_input_splited[i+1]),int):
|
|
formatted_prediction.append(['inform', 'Cinema', 'quantity', user_input_splited[i+1]])
|
|
|
|
|
|
if user_input_lr == '/pomoc':
|
|
print('System Usher pozwala na:\n1. Rezerwację biletu\n2. Anulowanie rezerwacji biletu\n3. Zakup biletu\n4. Anulowanie zakupu biletu\n5. Sprawdzenie repertuaru\n6. Sprawdzenie dostępności miejsc')
|
|
|
|
elif user_input_lr == '/koniec':
|
|
print('Dziękuję za skorzystanie z moich usług. Miłego dnia!')
|
|
break
|
|
|
|
elif user_input_lr == '/dst':
|
|
print(dst.state)
|
|
|
|
elif user_input_lr == '/reset':
|
|
with open('history.txt', 'a+', encoding='utf-8') as f:
|
|
f.write(str(dst.state))
|
|
f.write('\n')
|
|
dst = DST()
|
|
# dp = DP() ?
|
|
print('Witaj, jestem Usher - system do rezerwacji biletów kinowych. W czym mogę Ci pomóc?')
|
|
elif 'rezerw' in user_input_lr:
|
|
if 'anulo' in user_input_lr:
|
|
flag=False
|
|
for slot in slots:
|
|
if slot == 'B-e-mail' or '@' in slot[0]:
|
|
print(nlg.update([['cinema','inform','cancel_book',slot[0]]]))
|
|
dst.update([['inform', 'Cinema', 'task', 'cancel_book'],['inform', 'Cinema', 'cancel_book_status',True]])
|
|
flag = True
|
|
if not flag:
|
|
dst.update([['inform', 'Cinema', 'task', 'cancel_book'],['inform', 'Cinema', 'cancel_book_status',False]])
|
|
print(nlg.update([['cinema','inform','cancel_book','']]))
|
|
|
|
else:
|
|
dst.update([['inform', 'Cinema', 'task', 'book']])
|
|
dst.update(formatted_prediction)
|
|
for slot,value in dst.state['belief_state']['cinema']['book'].items():
|
|
if value == '':
|
|
print(nlg.update([['cinema','request',slot,'']]))
|
|
break
|
|
elif slot=="row" and value != '':
|
|
for slot,value in dst.state['belief_state']['cinema']['semi'].items():
|
|
if value == '':
|
|
print(nlg.update([['cinema','request',slot,'']]))
|
|
break
|
|
elif slot in ["cancel_book_status","cancel_buy_status"] and value =='':
|
|
continue
|
|
elif 'kup' in user_input_lr or ('zwr' and 'bilet') in user_input_lr:
|
|
|
|
if 'anulo' in user_input_lr or 'zwr' in user_input_lr:
|
|
flag=False
|
|
for slot in slots:
|
|
if slot == 'B-e-mail' or '@' in slot[0]:
|
|
print(nlg.update([['cinema','inform','cancel_buy',slot[0]]]))
|
|
dst.update([['inform', 'Cinema', 'task', 'cancel_buy'],['inform', 'Cinema', 'cancel_buy_status',True]])
|
|
flag = True
|
|
if not flag:
|
|
dst.update([['inform', 'Cinema', 'task', 'cancel_buy'],['inform', 'Cinema', 'cancel_buy_status',False]])
|
|
print(nlg.update([['cinema','inform','cancel_buy','']]))
|
|
|
|
else:
|
|
dst.update([['inform', 'Cinema', 'task', 'buy']])
|
|
dst.update(formatted_prediction)
|
|
for slot,value in dst.state['belief_state']['cinema']['book'].items():
|
|
if value == '':
|
|
print(nlg.update([['cinema','request',slot,'']]))
|
|
break
|
|
elif slot=="row" and value != '':
|
|
for slot,value in dst.state['belief_state']['cinema']['semi'].items():
|
|
if value == '':
|
|
print(nlg.update([['cinema','request',slot,'']]))
|
|
break
|
|
elif slot in ["cancel_book_status","cancel_buy_status"] and value =='':
|
|
continue
|
|
|
|
elif (('jak' or 'któr') and 'film') in user_input_lr or 'repertuar' in user_input_lr:
|
|
dst.update([['inform', 'Cinema', 'task', 'show_movies']])
|
|
flag=False
|
|
for slot in slots:
|
|
if slot[0] in value_dict['train']['date'] or slot[0] in value_dict['train']['day'] or slot[0] in ['dziś','jutro','pojutrze']:
|
|
print(nlg.update([['cinema','offer','closestscreening',slot[0]]]))
|
|
flag = True
|
|
if not flag:
|
|
print(nlg.update([['cinema','offer','closestscreening','']]))
|
|
|
|
elif ('czy' or 'jakie' or 'które') and ('dostęp' or 'woln' or 'zajęt') in user_input_lr:
|
|
if 'miejsce' in user_input_lr:
|
|
dst.update([['offer', 'Cinema', 'task', 'show_seats']])
|
|
flag=False
|
|
for slot in slots:
|
|
if slot[0] in value_dict['train']['seat']:
|
|
print(nlg.update([['cinema','offer','seat',slot[0]]]))
|
|
flag = True
|
|
if not flag:
|
|
print(nlg.update([['cinema','offer','seat','']]))
|
|
|
|
elif len(formatted_prediction)<1:
|
|
print('Nie do końca zrozumiałem mógłbyś/mogłabyś powtórzyć? ')
|
|
|
|
else:
|
|
# print(formatted_prediction) # NLU output
|
|
dst.update(formatted_prediction)
|
|
#DP
|
|
fl = False
|
|
for action in dst.state['system_action']:
|
|
if 'cancel_book' == action[0][2]:
|
|
for slot in formatted_prediction:
|
|
if slot[2] == 'e-mail' or slot[2] == 'cancel_book' or slot[2] == 'cancel_buy':
|
|
fl = True
|
|
if fl:
|
|
print("Anulowano. Czy w czymś jeszcze mogę Ci pomóc?")
|
|
|
|
|
|
else:
|
|
for slot,value in dst.state['belief_state']['cinema']['book'].items():
|
|
if value == '':
|
|
print(nlg.update([['cinema','request',slot,'']]))
|
|
break
|
|
elif slot=="row" and value != '':
|
|
for slot,value in dst.state['belief_state']['cinema']['semi'].items():
|
|
if slot == 'payments' and value == '':
|
|
print('Czy chciałbyś dokonać płatności online?')
|
|
input_user = input('> ')
|
|
if input_user.lower() == 'tak':
|
|
print(nlg.update([['cinema','request',slot,'online']]))
|
|
dst.update([['inform', 'Cinema', 'payments', 'online']])
|
|
else:
|
|
print(nlg.update([['cinema','request',slot,'']]))
|
|
dst.update([['inform', 'Cinema', 'payments', 'in_cinema']])
|
|
elif value == '':
|
|
print(nlg.update([['cinema','request',slot,'']]))
|
|
break
|
|
elif slot in ["cancel_book_status","cancel_buy_status"] and value =='':
|
|
continue
|
|
|
|
end = time.time()
|
|
print(f'### Czas konwersacji: {round(end - start, 2)}s ###')
|
|
print(f'### Tury konwersacji: {turns} ###')
|
|
with open('history.txt', 'a+', encoding='utf-8') as f:
|
|
f.write(str(dst.state))
|
|
f.write('\n')
|
|
|
|
|
|
|
|
|
|
if __name__ == '__main__':
|
|
main()
|