프로젝트/[머니버디] 카드상품 추천 챗봇(finchatbot)

[머니버디] 카드 데이터 임베딩(embedding)

hyunh404 2023. 11. 20. 21:44
728x90

chat GPT를 이용해 카드상품 추천을 위한 챗봇 웹 애플리케이션을 만드는 프로젝트를 진행하면서 새롭게 알게되고 학습한 내용인 임베딩에 대해 기록하려 한다.

 

프로젝트 진행 중에 카드 상품을 csv파일로 저장해놓고 파일을 불러와 원하는 데이터를 임베딩하기 위한 작업을 수행했다.

card_data.csv
0.02MB

 

여러 카드사에서 정보를 수집한 카드데이터이며 csv파일에서 '내용' 열에 있는 데이터만 임베딩해 추천 시스템에 활용하려 한다.

 

먼저 한글로 되어있는 csv파일을 임베딩 시스템에 적용하기 위해 파이썬을 3.7버전으로 다운 그레이드를 진행해주었다. (3.7버전에서만 한글 지원이 가능하다고 하여 진행한 단계였다.)

파이썬 홈페이지에 들어가 파이썬 3.7.9버전을 다운받아주고 시스템 경로설정을 해주었다.

 

시스템변수에 파이썬경로와 스크립트 경로 추가

임베딩을 위한 파이썬 flask파일 실행을 vs code에서 진행했기 때문에 설정에 필요한 파이썬파일 경로와 스크립트 경로까지 추가해주었다. 다음으로 vs code 터미널에서 파이썬 파일을 실행하는 데 필요한 flask, pandas 모듈을 설치해주었고 임베딩을 위해 nltk, transformers, torch, numpy 라이브러리들을 설치해주었다. 

  1. NLTK (Natural Language Toolkit):
    • 자연어 처리 (NLP) 작업을 위한 Python 라이브러리로 토큰화, 형태소 분석, 개체명 인식, 구문 분석, 처리된 텍스트 데이터로부터 특징 추출 등 다양한 NLP 작업을 수행할 수 있다. NLTK는 많은 자연어 처리 작업을 수행하기 위한 다양한 도구와 데이터를 포함하고 있다.
  2. Transformers (Hugging Face Transformers):
    • 기계 학습 모델인 Transformer 모델과 이를 사용하는 다양한 NLP 모델을 제공하는 라이브러리이다. Hugging Face의 Transformers 라이브러리는 최신 NLP 모델 (BERT, GPT, RoBERTa 등)에 대한 사전 훈련된 가중치와 모델 구조를 포함하고 있으며, 텍스트 분류, 번역, 생성 등의 다양한 NLP 작업에 사용된다.
  3. PyTorch와 Torch:
    • PyTorch는 딥러닝 프레임워크로서, 특히 동적 계산 그래프를 사용하여 딥러닝 모델을 구축하고 학습하는 데 사용된다. PyTorch는 기존의 TensorFlow와 유사한 목적으로 사용되지만, 보다 직관적이고 Pythonic한 구조를 가지고 있다.
    • Torch는 Lua 프로그래밍 언어로 개발된 딥러닝 프레임워크이다. PyTorch의 전신이자, Lua를 기반으로 하는 딥러닝 라이브러리로, 현재는 PyTorch가 그 역할을 대부분 대체하고 있다.
  4. NumPy:
    • 수치 계산을 위한 Python 라이브러리로, 고성능의 다차원 배열 및 행렬 연산 기능을 제공한다. NumPy는 데이터 배열을 만들고 조작하는 데 매우 효과적이며, 선형 대수, 통계, 푸리에 변환 등의 수학적인 연산을 지원한다. 또한 NumPy는 많은 데이터 과학 및 머신러닝 라이브러리의 기반이 되는 핵심 라이브러리 중 하나이다.

각각의 라이브러리에 대한 간단한 설명도 적어보았다. 이 라이브러리들을 활용해서 임베딩을 위한 코드를 작성할 것이다. 라이브러리들을 설치 완료한 이후에 flask파일을 실행하려고 했더니 다운그레이드를 했던 파이썬 버전의 경로가 flask파일에 제대로 적용이 안되는 오류가 있었다.

따라서 vs code에서 python extension pack을 설치해주었고 python경로를 직접 python3.11에서 다운그레이드한 python3.7.9로 바꿔주었다.

 

파이썬 경로 설정을 직접하기 위한 패키지를 설치했다.
파이썬 경로를 수동으로 python3.7.9로 바꿔주었다.

경로 설정까지 마친 뒤에야 flask파일이 실행이 되었다.

 

 

________________________________________________________________________________________

 

 

이제 임베딩을 위한 코드를 작성해보겠다. 먼저 설치한 라이브러리를 불러오기 위한 import 코드를 작성해보았다.

 

import pandas as pd
import nltk
from transformers import AutoTokenizer, AutoModel
import torch
import numpy as np
 
 
flask파일에서 코드의 첫 부분에 들어가는 내용으로 각 코드에 대한 내용을 짧게 설명하겠다.
  • pandas는 데이터프레임을 다루는데 사용된다.
  • nltk는 자연어 처리를 위한 도구로, 문장 토큰화를 위해 punkt를 다운로드한다.
  • transformers는 Hugging Face의 Transformers 라이브러리로, AutoTokenizer와 AutoModel을 가져와 KoBERT 모델을 사용한다.
  • torch는 PyTorch를 사용하는데, 여기서는 모델의 출력을 처리하는 데 사용한다.
  • numpy는 수치 데이터를 다루기 위해 사용한다.

 

다음으로 nltk의 punkt 다운로드를 위한 코드를 작성한 후에 AutoTokenizerAutoModel을 사용하여 'monologg/kobert' 모델을 로드하는 코드를 작성하였다. (이해를 위한 주석도 달아두었다.)

 

# nltk 다운로드
nltk.download('punkt')

# KoBERT 모델 로딩
tokenizer = AutoTokenizer.from_pretrained("monologg/kobert")
model = AutoModel.from_pretrained("monologg/kobert")
 
 
로드를 마친 후에는 본격적으로 csv 파일로 저장해두었던 카드 데이터를 불러오기 위해 pd.read_csv 코드를 사용하였다. C:\finchatbot\card_data.csv 경로에 있는 데이터 파일을 불러왔다. 파일의 내용에서 '내용'열의 데이터만 활용하여 임베딩을 계산할 것이다.
 
# 데이터 불러오기
card_data = pd.read_csv('C:/finchatbot/card_data.csv')
 
 

 

____________________________________________________________________________________________

 

이제 본격적으로 문장을 임베딩하기 위한 함수를 정의해보겠다. 임베딩 함수는 'embed_card_benefits'로 정의하였다.

 

  • 'embed_card_benefits' 함수는 csv파일에 있는 '내용' 열의 문장들을 받아 각 문장에 대한 임베딩 값을 계산한다.
  • 먼저, 문장을 nltk.sent_tokenize를 사용하여 토큰화한다.
  • 여기서 토큰화란 주어진 텍스트를 작은 단위로 나누는 과정을 말한다. 이 작은 단위는 토큰(token)이라고 불리며, 텍스트를 처리하고 분석하는 기본 단위로 사용된다. 토큰화의 목적은 문장이나 문서를 더 작은 의미 단위로 쪼개어 처리하거나, 자연어 처리(NLP) 모델에 입력으로 제공하기 위한 것이다. -> 예를 들어, "안녕하세요. 자연어 처리에 대해 배우고 있습니다." 라는 문장이 주어졌을 때, 이를 문장 토큰화하면 다음과 같은 리스트가 생성된다: ["안녕하세요.", "자연어 처리에 대해 배우고 있습니다."]
  • 따라서 각 문장을 KoBERT 모델에 넣고 출력값을 계산한 후, 각 문장의 임베딩 값을 구하고 모든 문장의 임베딩 값을 평균하여 전체 문장의 임베딩 값을 계산한다
  • 다음으로 'card_data['내용'].apply(embed_card_benefits)'를 통해 '내용' 열의 모든 문장에 대해 위에서 정의한 embed_card_benefits 함수를 적용하고, 새로운 'embedding'열을 만들어 저장한다.
  • 최종적으로, card_data 데이터프레임을 'C:/finchatbot/embedded_card_data.csv' 파일로 저장한다.

 

# '내용' 열에 있는 문장을 분할하고 임베딩 값을 계산하여 'embedding' 열에 저장
def embed_card_benefits(sentence):
    # 문장을 토큰화하고 KoBERT 모델을 통해 임베딩 값을 계산
    tokens = nltk.sent_tokenize(sentence)  # 문장을 토큰화
    sentence_embeddings = []

    for token in tokens:
        inputs = tokenizer(token, return_tensors="pt")
        outputs = model(**inputs)
        embedding = outputs.last_hidden_state.mean(dim=1).squeeze().detach().numpy()
        sentence_embeddings.append(embedding)

    # 각 문장의 임베딩 값을 평균하여 문장 전체의 임베딩 값 계산
    embedding = torch.tensor(np.array(sentence_embeddings)).mean(dim=0).numpy()
    return embedding
 
# '내용' 열에 대해 임베딩 값을 계산하고 'embedding' 열에 저장
card_data['embedding'] = card_data['내용'].apply(embed_card_benefits)
 
# 임베딩 값을 저장한 CSV 파일로 저장
card_data.to_csv('C:/finchatbot/embedded_card_data.csv', index=False)
 
 

이렇게 임베딩 과정을 통해 임베딩된 데이터를 csv파일로 저장하였고 이제 이 데이터 파일을 카드를 추천하기 위한 파일로  활용하려 한다.

글을 마치며 한번에 코드를 파악할 수 있도록 임베딩한 csv 데이터 파일과 임베딩 전체 코드를 올려두겠다.

embedded_card_data.csv
1.19MB

 

 

_______________________________________________________________________________________________

 

(임베딩 전체 코드)

 

import pandas as pd  # pandas 라이브러리를 pd로 가져옵니다.
import nltk  # nltk 라이브러리를 가져옵니다.
from transformers import AutoTokenizer, AutoModel  # transformers 라이브러리에서 AutoTokenizer와 AutoModel을 가져옵니다.
import torch  # torch 라이브러리를 가져옵니다.
import numpy as np  # numpy 라이브러리를 np로 가져옵니다.

# nltk 다운로드
nltk.download('punkt')  # 자연어 처리를 위해 'punkt' 데이터를 다운로드합니다.

# KoBERT 모델 로딩
tokenizer = AutoTokenizer.from_pretrained("monologg/kobert")  # 'monologg/kobert' 모델의 tokenizer를 가져옵니다.
model = AutoModel.from_pretrained("monologg/kobert")  # 'monologg/kobert' 모델을 가져옵니다.

# 데이터 불러오기
card_data = pd.read_csv('C:/finchatbot/card_data.csv')  # 'C:/finchatbot/card_data.csv'에서 데이터를 불러와 card_data에 저장합니다.

# '내용' 열에 있는 문장을 분할하고 임베딩 값을 계산하여 'embedding' 열에 저장
def embed_card_benefits(sentence):
    # 문장을 토큰화하고 KoBERT 모델을 통해 임베딩 값을 계산
    tokens = nltk.sent_tokenize(sentence)  # 문장을 토큰화합니다.
    sentence_embeddings = []  # 문장의 임베딩 값을 저장할 리스트를 생성합니다.

    for token in tokens:  # 각 문장에 대해 반복합니다.
        inputs = tokenizer(token, return_tensors="pt")  # 문장을 KoBERT 모델의 입력 형식으로 변환합니다.
        outputs = model(**inputs)  # KoBERT 모델을 통해 문장을 처리하고 출력값을 계산합니다.
        embedding = outputs.last_hidden_state.mean(dim=1).squeeze().detach().numpy()  # 문장의 임베딩 값을 계산합니다.
        sentence_embeddings.append(embedding)  # 계산된 임베딩 값을 리스트에 추가합니다.

    # 각 문장의 임베딩 값을 평균하여 문장 전체의 임베딩 값 계산
    embedding = torch.tensor(np.array(sentence_embeddings)).mean(dim=0).numpy()  # 모든 문장의 임베딩 값을 평균합니다.
    return embedding  # 문장 전체의 임베딩 값을 반환합니다.

# '내용' 열에 대해 임베딩 값을 계산하고 'embedding' 열에 저장
card_data['embedding'] = card_data['내용'].apply(embed_card_benefits)  # '내용' 열의 각 문장에 대해 임베딩 값을 계산하고 저장합니다.

# 임베딩 값을 저장한 CSV 파일로 저장
card_data.to_csv('C:/finchatbot/embedded_card_data.csv', index=False)  # 계산된 임베딩 값을 'C:/finchatbot/embedded_card_data.csv' 파일로 저장합니다.
728x90