--39.답변검색.ipynb--
base_path = r'/content/drive/MyDrive/dataset/chatbot'
/utils/Database.py 생성
import sqlite3
import logging
class Database:
def init(self, db_file):
self.db_file = db_file
self.conn = None
def connect(self):
if self.conn != None:
return
self.conn = sqlite3.connect(self.db_file)
self.conn.row_factory = sqlite3.Row # SELECT 결과를 Row 객체로 받게 함. => Row객체는 나중에 dict, tuple 형태로 변환 가능.
print("DB 연결 성공")
def close(self):
if self.conn is None:
return
self.conn.close()
self.conn = None
print("DB 연결 닫기 성공")
def execute(self, sql):
last_row_id = -1
try:
cursor = self.conn.cursor()
cursor.execute(sql)
self.conn.commit()
last_row_id = cursor.lastrowid
except Exception as ex:
logging.error(ex)
finally:
return last_row_id
def select_one(self, sql):
result = None
try:
cursor = self.conn.cursor()
cursor.execute(sql)
result = dict(cursor.fetchone()) # 한개의 Row 를 읽어와 dict로 변환
except Exception as ex:
logging.error(ex)
finally:
return result
def select_all(self, sql):
results = None
try:
cursor = self.conn.cursor()
cursor.execute(sql)
results = [dict(row) for row in cursor.fetchall()]
except Exception as ex:
logging.error(ex)
finally:
return results
from utils.Database import Database
db = Database('example.db')
db.connect()
results = db.select_all("SELECT * FROM chatbot_train_data")
print(results)
result = db.select_one("SELECT * FROM chatbot_train_data WHERE id = 1")
print(result)
print(result['id'], result['intent'])
db.close()
/utils/FindAnswer.py 생성
class FindAnswer :
def init(self, db) :
self.db = db
def search (self, intent_name, ner_tags) :
# 의도명, 개체명으로 답변 검색
sql = self._make_query(intent_name, ner_tags)
answer = self.db.select_one(sql)
return answer
# 검색되는 답변이 없었으면 의도명만 이용하여 답변 검색
if answer is None :
sql = self._make_query(intent_name, None)
answer = self.db.select_one(sql)
return answer['answer'], answer['answer_image']
def make_query(self, intent_name, ner_tags) : # 로 시작하는 함수는 보통 class 내부에서 쓰이는 함수라고 보면 됨.
sql = "SELECT * FROM chatbot_train_data"
if intent_name != None and ner_tags == None :
sql += f" WHERE intent = '{intent_name }'"
elif intent_name != None and ner_tags != None :
where = f' WHERE intent = "{intent_name}"'
if len(ner_tags) > 0 :
where += ' and ('
for ne in ner_tags :
where += f" ner LIKE '%{ne}%' OR "
where = where[: -3] + ')' # 마지막 'OR '을 없애기 위해
sql += where
# 동일한 답변이 복수개인 경우, 랜덤으로 한개 선택
sql += " ORDER BY random() LIMIT 1"
return sql
def tag_to_word(self, ner_predicts, answer) :
for word, tag in ner_predicts :
# 변환해야 하는 태그가 있는 경우 치환
if tag in ['B_FOOD', 'B_DT', 'B_TI'] :
answer = answer.replace(f'{{{tag}}}', word)
return answer
from utils.FindAnswer import FindAnswer
!pip install konlpy
from config.DatabaseConfig import *
from utils.Database import Database
from utils.Preprocess import Preprocess
import tensorflow as tf
from tensorflow.keras.models import Model, load_model
from tensorflow.keras import preprocessing
import os
tf.keras.utils.set_random_seed(42)
tf.config.experimental.enable_op_determinism()
DB_FILE
p = Preprocess(word2index_dic= os.path.join(base_path, 'out', 'chatbot_dict.bin'),
userdic = os.path.join(base_path, 'user_dic.tsv'))
db = Database(db_file = DB_FILE)
db.connect()
from models.intent.IntentModel import IntentModel
intent= IntentModel(model_name = os.path.join(base_path, 'out', 'intent_model.h5'), preprocess=p)
from models.ner.NerModel import NerModel
ner = NerModel(model_name=os.path.join(base_path, 'out', 'ner_model.h5'), preprocess=p)
def chat(query) :
predict = intent.predict_class(query)
intent_name = intent.labels[predict]
predicts = ner.predict(query)
ner_tags = ner.predict_tags(query)
print('질문: ', query)
print("=" * 100)
print("의도 파악: ", intent_name)
print("개체명 인식: ", predicts)
print("답변 검색에 필요한 NER 태그: ", ner_tags)
queries = [
"오전에 탕수육 10개 주문합니다",
"화자의 질문 의도를 파악합니다",
"안녕하세요",
"자장면 주문할께요"
]
for q in queries :
chat(q)
from utils.FindAnswer import FindAnswer
def chatbot(query) :
predict = intent.predict_class(query)
intent_name = intent.labels[predict]
predicts = ner.predict(query)
ner_tags = ner.predict_tags(query)
print('질문: ', query)
print("=" * 100)
print("의도 파악: ", intent_name)
print("개체명 인식: ", predicts)
print("답변 검색에 필요한 NER 태그: ", ner_tags)
try :
f = FindAnswer(db)
answertext, = f.search(intent_name, ner_tags)
answer = f.tag_to_word(predicts, answer_text)
except :
answer = "죄송해요 무슨 말인지 모르곘어요"
return answer
chatbot(queries[0])
chatbot("짬뽕 2개 주문합니다")
chatbot("수고하셨습니다")