[NLP 22] SBERT(SentenceBERT) 2 : 문장 유사도(Text Similarity)를 이용한 ChatBot 구현

방선생·2025년 2월 9일
0

Natural Language Processing

목록 보기
22/22

문장 유사도(Text Similarity)를 이용한 ChatBot

  • 사용자 질문에 대한 응답 구현
    • 사용자의 질문이 들어오면 해당 질문에 대한 문장 임베딩 벡터 생성
    • 사용자 질문의 문장 임베딩 벡터 값과 챗봇 데이터의 임베딩 컬럼('embedding')에 저장해둔 모든 질문 샘플들의 문장 임베딩 벡터 값들을 이용, 코사인 유사도를 계산
    • 코사인 유사도 값이 가장 높은 질문 샘플 검색
    • 해당 질문 샘플과 짝이 되는 답변 샘플 반환

  • chatbot 임베딩 벡터
    • QA 모델에서 model.encode()을 통한 임베딩 벡터 생성 X
      • encode() 함수를 사용할 경우 2차원 형태로 만듬 > 데이터프레임을 만드는 용도
      • df.series는 1차원 배열만 들어가지기 때문에 for+리스트를 통해 1차원 리스트로 만들어 줘야함



(이 시리즈의 모든 코드는 코랩환경에서 Python으로 작성하였습니다)

문장 유사도를 이용한 ChatBot Code 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 Code 2 (질문 문장에 대한 임베딩 벡터 생성 및 저장)

# 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

문장 유사도를 이용한 ChatBot Code 3 (응답 구현 함수 생성)

# 함수 임폴트
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)}')





끝!




참고 자료

numpy.linalg.norm 공식문서

profile
AI & Robotics

0개의 댓글