0. 포스팅 목록 & GitHub
(깃허브 스타 버튼 눌러주시면 글 작성에 큰 도움이 됩니다!)
https://github.com/Seokii/Chatbot4Univ
https://seokii.tistory.com/146
이전 포스팅인 [5. 엑셀 내용 임베딩 및 pt파일 저장 & 입력 질문과 유사도 비교] 글에서 구현했던
임베딩 저장 기능과 유사도 비교를 통한 점수 측정 기능을
챗봇 엔진에서 사용하기 위해 클래스화 시키도록 하겠습니다.
1. 질문 데이터 임베딩 & pt파일 저장
이전에 작성했던 코드는 주석 처리하고 진행했습니다.
# /train_tools/qna/create_embedding_data.py
class create_embedding_data:
def __init__(self, preprocess, df):
# 텍스트 전처리기
self.p = preprocess
# 질문 데이터프레임
self.df = df
# pre-trained SBERT
self.model = SentenceTransformer('snunlp/KR-SBERT-V40K-klueNLI-augSTS')
def create_pt_file(self):
# 질문 목록 리스트
target_df = list(self.df['질문(Query)'])
# 형태소 분석
for i in range(len(target_df)):
sentence = target_df[i]
pos = self.p.pos(sentence)
keywords = self.p.get_keywords(pos, without_tag=True)
temp = ""
for k in keywords:
temp += str(k)
target_df[i] = temp
self.df['질문 전처리'] = target_df
self.df['embedding_vector'] = self.df['질문 전처리'].progress_map(lambda x : self.model.encode(x))
# self.df.to_excel("/Users/Home/Documents/GitHub/Chatbot4Univ/train_tools/qna/train_data_embedding.xlsx", index=False)
embedding_data = torch.tensor(self.df['embedding_vector'].tolist())
torch.save(embedding_data, '/Users/Home/Documents/GitHub/Chatbot4Univ/train_tools/qna/embedding_data.pt')
코드의 내용은 이전과 거의 같고 클래스화 시켰습니다.
이전 코드와 다른 점은, 구현했던 텍스트 전처리기를 통해 질문 데이터를 pos태깅하고 불용어 제거를 진행한 후 임베딩을 진행했습니다.
이는 유사도를 비교할 대상이 챗봇 사용자의 전처리된 입력이기 때문입니다.
따라서, 구축한 질문 데이터의 임베딩도 전처리 후 진행되도록 구현했습니다.
주석 처리된 # self.df.to_excel~ 부분은 윈도우에서 개발 진행 시 권한 오류가 발생하여 주석처리했습니다.
리눅스 기반의 서버 컴퓨터에서는 이를 쉽게 해결할 수 있기에 후에 주석을 제거하면, 전처리와 임베딩 데이터도 표시된 엑셀 파일을 저장할 수 있습니다.
2. 답변 검색 클래스
# utils/FindAnswer.py
import torch
import numpy as np
from numpy import dot
from numpy.linalg import norm
from sentence_transformers import SentenceTransformer, util
class FindAnswer:
def __init__(self, preprocess, df, embedding_data):
# 챗봇 텍스트 전처리기
self.p = preprocess
# pre-trained SBERT
self.model = SentenceTransformer('snunlp/KR-SBERT-V40K-klueNLI-augSTS')
# 질문 데이터프레임
self.df = df
# embedding_data
self.embedding_data = embedding_data
def search(self, query, intent):
# 형태소 분석
pos = self.p.pos(query)
# 불용어 제거
keywords = self.p.get_keywords(pos, without_tag=True)
query_pre = ""
for k in keywords:
query_pre += str(k)
# 전처리된 질문 인코딩 및 텐서화
query_encode = self.model.encode(query_pre)
query_tensor = torch.tensor(query_encode)
# 코사인 유사도를 통해 질문 데이터 선택
cos_sim = util.cos_sim(query_tensor, self.embedding_data)
best_sim_idx = int(np.argmax(cos_sim))
selected_qes = self.df['질문(Query)'][best_sim_idx]
if self.df['의도(Intent)'][best_sim_idx] == intent:
# 선택된 질문 문장 인코딩
selected_qes_encode = self.model.encode(selected_qes)
# 유사도 점수 측정
score = dot(query_tensor, selected_qes_encode) / (norm(query_tensor) * norm(selected_qes_encode))
# 답변
answer = self.df['답변(Answer)'][best_sim_idx]
imageUrl = self. df['답변 이미지'][best_sim_idx]
success = True
else:
selected_qes = "nan"
score = 0
answer = "nan"
imageUrl = "nan"
success = False
return selected_qes ,score, answer, imageUrl, success
이전 포스팅에서 구현했던 코드의 흐름과는 거의 동일합니다.
이전 코드와 다른 점은 아래와 같습니다.
- 앞서 언급한 것처럼, 전처리기를 통해 질문의 전처리가 이루어짐.
- 질문의 의도 파악 모델이 먼저 실행되기 때문에 선택된 질문의 의도와 모델이 계산한 의도가 일치하지 않는다면, 올바른 답변을 출력할 수 없게 설정함.
- 올바른 수행이 이루어졌는지 아닌지를 구분하기 위한 success 변수를 반환하도록 구현함.
이는 추후에 데이터 축적을 목적으로 로그를 남기기 위함.
'머신러닝 & 딥러닝 > 자연어처리' 카테고리의 다른 글
대학교 AI 질의응답 챗봇 만들기 - 9. 챗봇 엔진 서버 테스트 (0) | 2022.07.30 |
---|---|
대학교 AI 질의응답 챗봇 만들기 - 8. 챗봇 엔진 서버 (0) | 2022.07.30 |
대학교 AI 질의응답 챗봇 만들기 - 6. 소켓 모듈과 JSON (0) | 2022.07.29 |
대학교 AI 질의응답 챗봇 만들기 - 5. 엑셀 내용 임베딩 및 pt파일 저장 & 입력 질문과 유사도 비교(코사인 유사도) (1) | 2022.07.29 |
대학교 AI 질의응답 챗봇 만들기 - 4. 질의응답 데이터 엑셀로 구축 (1) | 2022.07.29 |
댓글