문장 유사도(Text Similarity)를 이용한 ChatBot
- 사용자 질문에 대한 응답 구현
- 사용자의 질문이 들어오면 해당 질문에 대한 문장 임베딩 벡터 생성
- 사용자 질문의 문장 임베딩 벡터 값과 챗봇 데이터의 임베딩 컬럼('embedding')에 저장해둔 모든 질문 샘플들의 문장 임베딩 벡터 값들을 이용, 코사인 유사도를 계산
- 코사인 유사도 값이 가장 높은 질문 샘플 검색
- 해당 질문 샘플과 짝이 되는 답변 샘플 반환
- chatbot 임베딩 벡터
- QA 모델에서 model.encode()을 통한 임베딩 벡터 생성 X
- encode() 함수를 사용할 경우 2차원 형태로 만듬 > 데이터프레임을 만드는 용도
- df.series는 1차원 배열만 들어가지기 때문에 for+리스트를 통해 1차원 리스트로 만들어 줘야함
# 필요한 라이브러리 임폴트
import pandas as pd
# 필요한 라이브러리 설치
!pip install sentence-transformers
# 함수 임폴트
from sentence_transformers import SentenceTransformer
# fine-tuning된 한국어 모델
model_name='ddobokki/klue-roberta-base-nli-sts'
model = SentenceTransformer(model_name)
# 챗봇 생성용 데이터 불러오기
# 파일 경로 설정
file_path='/content/drive/MyDrive/NLP/ChatBotData.csv'
# DataFrame 생성
df = pd.read_csv(file_path)
# 불필요한 컬럼 삭제
df.drop(columns=['label'], inplace=True)
# 결과 확인하기
print(df)
# chatbot데이터 > 질문 문장(Q)에 대한 임베딩 벡터 생성
# Q컬럼 인덱싱
sentence = df.loc[:,'Q'].values
# 생성된 임베딩 벡터 저장 > 리스트 생성
embedding = []
# for문 + model.encode()
for sent in sentence:
em = model.encode(sent)
embedding.append(em)
print(len(embedding))
embedding[0]
# 새로운 컬럼 생성 > 질문(Q)에 대한 임베딩 벡터 저장
df.loc[:, 'embedding'] = embedding
# 결과 확인
df
# 함수 임폴트
import numpy as np
# 텍스트 유사도 측정 함수 정의
def cosine_similarity(a, b):
return np.dot(a, b) / (np.linalg.norm(a) * np.linalg.norm(b))
# 사용자 질문에 대한 응답 구현 함수 정의 > 샘플을 이용한 테스트
'''
1. 사용자의 질문이 들어오면 해당 질문에 대한 문장 임베딩 값을 구한다.
2. 사용자 질문의 문장 임베딩 값과 챗봇 데이터의 임베딩 컬럼(df.loc[:, 'embedding'])에
저장해둔 질문 샘플들의 문장 임베딩 값들을 이용, 코사인 유사도를 계산
--> 코사인 유사도 값을 저장하는 컬럼(df.loc[:, 'score'])을 생성하고 값을 저장
3. 코사인 유사도 값이 가장 높은 질문 샘플을 찾는다.
4. 해당 질문 샘플과 짝이 되는 답변 샘플을 반환한다.
'''
def BangChatBot(question):
# 사용자 질문 > 임베딩 벡터 생성
user_embedding = model.encode(question)
# 코사인 유사도 계산
scores = []
for em in df.loc[:, 'embedding']:
score = cosine_similarity(user_embedding, em)
scores.append(score)
# 코사인 유사도 컬럼 생성
df.loc[:, 'score'] = scores
answer = df.loc[df['score'].idxmax(), 'A']
return answer
while True:
user = input('user: ')
if user == '종료':
break
else:
print(f'Bot: {BangChatBot(user)}')
참고 자료