013-003. create train data for chatbot
# @
# You can build data to create "intent" and "NER" model
# You build each "entity" for "order pizza", "book house", "request trip information"
# You should create DB for each "entity" in service
# Each entity has text composed of n*n
# train_data_order : entity
# '판교에 오늘 피자 주문해줘' : text data
train_data_order = ['판교에 오늘 피자 주문해줘']
train_data_reserve = ['오늘 날짜에 호텔 예약 해줄레']
train_data_info = ['모래 날짜의 판교 여행 정보 알려줘']
get_data_list = train_data_info[0]
dict_entity = {
'date' : ['오늘','내일','모래'],
'loc' : ['판교','야탑'],
'menu' : ['피자','햄버거'],
'hotel' : ['호텔','여관','민박'],
'travel' : ['여행','관광','카페']
}
length = 1
# 'date', 'loc', 'menu', 'hotel', 'travel
for key in list(dict_entity.keys()):
# length = 1 * 3
length = length * len(dict_entity[key])
print("Augmentation length is {0}".format(length))
# Augmentation length is 108
# @
# Mophological analysis
from konlpy.tag import Mecab
# I create Mecab instance
mecab = Mecab('/usr/local/lib/mecab/dic/mecab-ko-dic')
# I perform 'mecab pos' on '모래 날짜의 판교 여행 정보 알려줘'
morpphed_text = mecab.pos(get_data_list)
print(morpphed_text)
# [('모래', 'NNG'), ('날짜', 'NNG'), ('의', 'JKG'), ('판교', 'NNG'), ('여행', 'NNG'), ('정보', 'NNG'), ('알려줘', 'VV+EC+VX+EC')]
# @
# Feature engineering for extracting nouns
# Precision of "intent" and "NER" is increased via feature engineering
# General noun(NNG) [메뉴]
# Proper noun(NNP) [지역]
# English(SL) [Pizza]
# Time adverb(MAG) [오늘, 내일, 모래]
# Korean "POS tag" comparison table
# https://docs.google.com/spreadsheets/d/1OGAjUvalBuX-oZvZ_-9tEfYD2gQe7hTGsgUpiiBSXI8/edit#gid=0
# This is holder for tagged_text
tagged_text = ''
# [('모래', 'NNG'), ('날짜', 'NNG'), ('의', 'JKG'), ('판교', 'NNG'), ('여행', 'NNG'), ('정보', 'NNG'), ('알려줘', 'VV+EC+VX+EC')]
for pos_tags in morpphed_text:
# Check only noun
# 'NNG', 모래
if (pos_tags[1] in ['NNG','MAG', 'NNP','SL'] and len(pos_tags[0]) > 1):
# feature_value = 모래
feature_value = pos_tags[0]
# tagged_text = '' + 모래 + ' '
tagged_text = tagged_text + pos_tags[0] + ' '
print(tagged_text)
# < 모래 날짜 판교 여행 정보
# @
# Structure of train data for 'intenet'
# You make parsed Text Data "respresent" for increasing performance of 'intent'
# This is holder for pattern
pattern = ''
# 모래 날짜 판교 여행 정보
for word in tagged_text.split(' '):
# 모래
entity = list(filter(lambda key:word in dict_entity[key], list(dict_entity.keys())))
if(len(entity) > 0):
# pattern = '' + tag + date + ' '
pattern = pattern + 'tag' + entity[0] + ' '
else:
# pattern = '' + 모래
pattern = pattern + word + ' '
print(pattern)
# < tagdate 날짜 tagloc tagtravel 정보
# @
# Data augmentation (Entity and Pattern)
# I augment pattern text of each intent as entity composed of n*n
# pattern : tagdate 날짜 tagloc tagtravel 정보
# dict_entity :
# dict_entity = {
# 'date' : ['오늘','내일','모래'],
# 'loc' : ['판교','야탑'],
# 'menu' : ['피자','햄버거'd
# 'hotel' : ['호텔','여관','민박'],
# 'travel' : ['여행','관광','카페']
# }
def augmentation_pattern(pattern, dict_entity):
# I convert 'tagdate 날짜 tagloc tagtravel 정보' into list [tagdate, 날짜, tagloc, tagtravel, 정보]
aug_pattern = pattern.split(' ')
augmented_text_list = []
temp_aug = []
# 0 to 5
for i in range(0,len(aug_pattern)):
# tagdate
if(aug_pattern[i].find("tag") > -1):
# tagdate -> date
# dict_list = dict_entity[date]
# dict_list = ['오늘','내일','모래']
dict_list = dict_entity[aug_pattern[i].replace("tag","")]
# 0 to 3
for j in range(0, len(dict_list)):
# 최초 Entity값은 그냥 추가만함
if(i == 0):
augmented_text_list.append(dict_list[j] + " ")
elif(j == 1):
augmented_text_list = list(filter(lambda word:len(word.split(' ')) == i + 1 ,augmented_text_list))
copy_data_order = augmented_text_list * (len(dict_list)-2)
augmented_text_list = list(map(lambda x:x + dict_list[j] + " ",augmented_text_list))
augmented_text_list = augmented_text_list + temp_aug + copy_data_order
else:
# I add value as I'm countinig number
temp_aug = list(filter(lambda word:len(word.split(' ')) == i+1 ,augmented_text_list))
temp_aug = list(map(lambda x:x + dict_list[j] + " " ,temp_aug))
# I delete existing value for newly added list
if(j != 0):
augmented_text_list = augmented_text_list[0:len(augmented_text_list) - len(temp_aug)]
augmented_text_list = augmented_text_list + temp_aug
# I added only pattern if it's not object for entity addition
else:
augmented_text_list = list(map(lambda x:x + aug_pattern[i] + " ",augmented_text_list))
# This is list to make n*n
temp_aug = augmented_text_list
return augmented_text_list
augmented_text_list = augmentation_pattern(pattern, dict_entity)
print(augmented_text_list)
# ['오늘 날짜 야탑 관광 정보 ',
# '내일 날짜 야탑 관광 정보 ',
# '모래 날짜 야탑 관광 정보 ',
# '오늘 날짜 판교 관광 정보 ',
# '내일 날짜 판교 관광 정보 ',
# '모래 날짜 판교 관광 정보 ',
# '오늘 날짜 야탑 여행 정보 ',
# '내일 날짜 야탑 여행 정보 ',
# '모래 날짜 야탑 여행 정보 ',
# '오늘 날짜 판교 여행 정보 ',
# '내일 날짜 판교 여행 정보 ',
# '모래 날짜 판교 여행 정보 ',
# '오늘 날짜 야탑 카페 정보 ',
# '내일 날짜 야탑 카페 정보 ',
# '모래 날짜 야탑 카페 정보 ',
# '오늘 날짜 판교 카페 정보 ',
# '내일 날짜 판교 카페 정보 ',
# '모래 날짜 판교 카페 정보 ']
# BIO Tagging
def augmentation_bio_pattern(pattern, dict_entity):
aug_pattern = pattern.split(' ')
augmented_text_list = []
temp_aug = []
for i in range(0,len(aug_pattern)):
if(aug_pattern[i].find("tag") > -1):
dict_list = dict_entity[aug_pattern[i].replace("tag","")]
bio_tag = aug_pattern[i].replace("tag","B_")
for j in range(0,len(dict_list)):
if(i == 0):
augmented_text_list.append(bio_tag + " ")
elif(j == 1):
augmented_text_list = list(filter(lambda word:len(word.split(' ')) == i + 1 ,augmented_text_list))
copy_data_order = augmented_text_list * (len(dict_list)-2)
augmented_text_list = list(map(lambda x:x + bio_tag + " ",augmented_text_list))
augmented_text_list = augmented_text_list + temp_aug + copy_data_order
else:
temp_aug = list(filter(lambda word:len(word.split(' ')) == i+1 ,augmented_text_list))
temp_aug = list(map(lambda x:x + bio_tag + " " ,temp_aug))
if(j != 0):
augmented_text_list = augmented_text_list[0:len(augmented_text_list) - len(temp_aug)]
augmented_text_list = augmented_text_list + temp_aug
else:
augmented_text_list = list(map(lambda x:x + aug_pattern[i] + " ",augmented_text_list))
temp_aug = augmented_text_list
return augmented_text_list
bio_list = augmentation_bio_pattern(pattern, dict_entity)
print(bio_list)
# ['B_date 날짜 B_loc B_travel 정보 ',
# 'B_date 날짜 B_loc B_travel 정보 ',
# 'B_date 날짜 B_loc B_travel 정보 ',
# 'B_date 날짜 B_loc B_travel 정보 ',
# 'B_date 날짜 B_loc B_travel 정보 ',
# 'B_date 날짜 B_loc B_travel 정보 ',
# 'B_date 날짜 B_loc B_travel 정보 ',
# 'B_date 날짜 B_loc B_travel 정보 ',
# 'B_date 날짜 B_loc B_travel 정보 ',
# 'B_date 날짜 B_loc B_travel 정보 ',
# 'B_date 날짜 B_loc B_travel 정보 ',
# 'B_date 날짜 B_loc B_travel 정보 ',
# 'B_date 날짜 B_loc B_travel 정보 ',
# 'B_date 날짜 B_loc B_travel 정보 ',
# 'B_date 날짜 B_loc B_travel 정보 ',
# 'B_date 날짜 B_loc B_travel 정보 ',
# 'B_date 날짜 B_loc B_travel 정보 ',
# 'B_date 날짜 B_loc B_travel 정보 ']
# @
# I obtain 'full train text' for NER
# I convert 'tag entity' into 'Labeled Entity' for training NER (for training by Bi-LSTM)
ner_train_text = [augmented_text_list, bio_list]
print(ner_train_text)
# [['오늘 날짜 야탑 관광 정보 ',
# '내일 날짜 야탑 관광 정보 ',
# '모래 날짜 야탑 관광 정보 ',
# '오늘 날짜 판교 관광 정보 ',
# '내일 날짜 판교 관광 정보 ',
# '모래 날짜 판교 관광 정보 ',
# '오늘 날짜 야탑 여행 정보 ',
# '내일 날짜 야탑 여행 정보 ',
# '모래 날짜 야탑 여행 정보 ',
# '오늘 날짜 판교 여행 정보 ',
# '내일 날짜 판교 여행 정보 ',
# '모래 날짜 판교 여행 정보 ',
# '오늘 날짜 야탑 카페 정보 ',
# '내일 날짜 야탑 카페 정보 ',
# '모래 날짜 야탑 카페 정보 ',
# '오늘 날짜 판교 카페 정보 ',
# '내일 날짜 판교 카페 정보 ',
# '모래 날짜 판교 카페 정보 '],
# ['B_date 날짜 B_loc B_travel 정보 ',
# 'B_date 날짜 B_loc B_travel 정보 ',
# 'B_date 날짜 B_loc B_travel 정보 ',
# 'B_date 날짜 B_loc B_travel 정보 ',
# 'B_date 날짜 B_loc B_travel 정보 ',
# 'B_date 날짜 B_loc B_travel 정보 ',
# 'B_date 날짜 B_loc B_travel 정보 ',
# 'B_date 날짜 B_loc B_travel 정보 ',
# 'B_date 날짜 B_loc B_travel 정보 ',
# 'B_date 날짜 B_loc B_travel 정보 ',
# 'B_date 날짜 B_loc B_travel 정보 ',
# 'B_date 날짜 B_loc B_travel 정보 ',
# 'B_date 날짜 B_loc B_travel 정보 ',
# 'B_date 날짜 B_loc B_travel 정보 ',
# 'B_date 날짜 B_loc B_travel 정보 ',
# 'B_date 날짜 B_loc B_travel 정보 ',
# 'B_date 날짜 B_loc B_travel 정보 ',
# 'B_date 날짜 B_loc B_travel 정보 ']]
# I can train algorithm for obtaining 'intent' and 'NER' model, based on above data