PRJ1_4 BERT 챗봇

영영·2023년 5월 25일
post-thumbnail

한줄기 구세주 같은 위키독스를 발견해 따라해봤다.
나는 내가 준비해놓은 데이터로 넣어서 실습했다.

내용 요약

sentence_transformers
: SBERT를 이용해 문장 임베딩을 얻을 수 있는 패키지

model = SentenceTransformer('모델이름')
: 문장 임베딩을 얻기 위해 사전 훈련된 BERT 로드.
1) 한국어가 포함되어 학습된 다국어 모델로 로드할 것.
2) 로드할 수 있는 모델 리스트
- 여기서 나는 ko가 들어간 모델들을 검색해서 사용했다.

진행 코드

import numpy as np
import pandas as pd
from numpy import dot
from numpy.linalg import norm
import urllib.request
from sentence_transformers import SentenceTransformer
import os
os.environ['KMP_DUPLICATE_LIB_OK']='True'
# 학습데이터 (Q:사용자 발화, A:시스템 발화, label:[0:기쁨, 1: 당황, 2: 분노, 3: 불안, 4: 상처, 5:슬픔])
train_data = pd.read_excel('C:/vscode/미니프로젝트/2차프로젝트_챗봇/data/TrainingData.xlsx')
train_data = train_data.iloc[:,:3]
train_data.head()
# Q의 문장 임베딩값 따로 저장
train_data['embedding'] = train_data.apply(lambda row: model.encode(row.Q), axis = 1)
# 사전학습된 BERT모델 불러오기
# model = SentenceTransformer('sentence-transformers/xlm-r-100langs-bert-base-nli-stsb-mean-tokens')
# model = SentenceTransformer('jhgan/ko-sroberta-multitask') 이거
# model = SentenceTransformer('jhgan/ko-sbert-sts')
# model = SentenceTransformer('jhgan/ko-sbert-multitask')
model = SentenceTransformer('ddobokki/klue-roberta-base-nli-sts-ko-en') 
# 이것도 굿
# 두 벡터에서 코사인 유사도 구하는 함수 정의
def cos_sim(A, B):
    return dot(A, B)/(norm(A)*norm(B))
# 임의의 질문이 들어오면 해당 질문의 문장 임베딩 값과 
# 챗봇 데이터의 임베딩 열(train_data['embedding'])에 저장해둔 
# 모든 질문 샘플들의 문장 임베딩 값들을 전부 비교하여 
# 코사인 유사도 값이 가장 높은 질문 샘플을 찾아내기.
# 그리고 해당 질문 샘플과 짝이 되는 답변 샘플을 리턴
def return_answer(question):
    embedding = model.encode(question)
    train_data['score'] = train_data.apply(lambda x: cos_sim(x['embedding'], embedding), axis=1)
    return train_data.loc[train_data['score'].idxmax()]['A']
# test
# return_answer('요즘 직장생활이 너무 편하고 좋은 것 같아')
# return_answer('죽고싶지만 떡볶이는 먹고싶어')
return_answer('취업해서 너무 신이 나!')
# 입력값 받아서 대답 반환하기
human = input('입력하세요')
print('사용자 입력값:', human)
return_answer(human)

test 결과

내가 표시해둔 두가지 모델의 답변이 맥락과 가장 잘 맞았다. 다만 'jhgan/ko-sroberta-multitask' 이건 맥락과는 말이 통하지만 지나치게 이성적인 답만 내놓는 경향이 보여서,, 내 주제와 맞지 않을 것 같았음. 그래서 'ddobokki/klue-roberta-base-nli-sts-ko-en' 이걸 사용하면 어떨까 한다.

추가 대화를 이어나가려는 시도도 보임.

0개의 댓글