2024. 11. 15. 19:27ㆍ오블완 챌린지
오늘은 텍스트 데이터를 시각화하는 제일 기본적인 방법인 embedding을 t-SNE 방식을 통해 차원축소해서
벡터로 나타내는 시각화를 해보려고 합니다.
간단하기도 하고 대규모 데이터 시각화에도 유리해서 저도 자주 쓰는 방법이애오.
바로 파이썬 코드로 살펴 볼게요.
우선 필요한 라이브러리를 로드해올게요
import pandas as pd
from transformers import AutoModel, AutoTokenizer
import torch
import numpy as np
from tqdm import tqdm
from torch.utils.data import DataLoader, Dataset
from sklearn.manifold import TSNE
import matplotlib.pyplot as plt
from tqdm import tqdm
그리고 GPU 사용을 위한 설정.
저는 mac 환경이라 mps로 설정했지만, GPU 환경에서는 Cuda로 설정하시면 되겠죠?
device = torch.device("mps" if torch.backends.mps.is_available() else "cpu")
model_name = "google-bert/bert-base-multilingual-uncased"
model = AutoModel.from_pretrained(model_name)
tokenizer = AutoTokenizer.from_pretrained(model_name)
model.to(device)
model.eval()
데이터셋은 한글 문장과 영어 문장 2가지로 나눠서 임베딩해볼게요. 이건 GPT가 친절하게 만들어줬답니다.
eng_data = [
"The cat jumped over the fence to chase a butterfly.",
"I love reading books on rainy afternoons.",
"Technology is advancing at an incredible pace.",
"She prepared a delicious cake for the party.",
"Walking along the beach is my favorite activity.",
"The children were playing hide-and-seek in the garden.",
"He forgot to bring his umbrella on a rainy day.",
"Traveling around the world is on my bucket list.",
"The stars were shining brightly in the night sky.",
"I enjoy watching movies with a cup of hot chocolate."
]
kor_data = [
"강아지가 공을 물고 와서 주인에게 줬다.",
"나는 해가 뜨기 전 아침 산책을 즐긴다.",
"요즘 사람들은 건강한 식단에 관심이 많다.",
"친구가 나에게 직접 만든 목도리를 선물했다.",
"시장에서 신선한 과일을 많이 샀다.",
"아이들은 공원에서 연을 날리고 있었다.",
"그는 새로운 취미로 도예를 배우기 시작했다.",
"여름에는 산보다 바다로 여행 가는 걸 선호한다.",
"도시는 밤이 되자 화려한 조명으로 빛났다.",
"나는 겨울에 뜨거운 차를 마시는 걸 좋아한다."
]
그럼 이제 각 문장들에 대해서 label 만들어 주고~
eng_labels = ['English_sentence'] * len(eng_data)
kor_labels = ['Korean_sentence'] * len(kor_data)
데이터셋 처리와 임베딩을 위한 코드!
저는 batch 단위로 처리할 일이 많아서 아래 코드를 주로 사용했는데 지금보니 10 문장밖에 안되면 굳이 batch 처리는 안해도 되겠죠?!
class TextDataset(Dataset):
def __init__(self, texts):
self.texts = texts
def __len__(self):
return len(self.texts)
def __getitem__(self, idx):
return self.texts[idx]
def get_embeddings(texts, batch_size=16):
dataset = TextDataset(texts)
dataloader = DataLoader(dataset, batch_size=batch_size, shuffle=False)
embeddings = []
for batch in tqdm(dataloader):
inputs = tokenizer(batch, return_tensors='pt', truncation=True, padding=True, max_length=128)
inputs = {key: val.to(device) for key, val in inputs.items()}
with torch.no_grad():
outputs = model(**inputs)
batch_embeddings = outputs.last_hidden_state[:, 0, :].cpu().numpy()
embeddings.extend(batch_embeddings)
return embeddings
이제 위의 함수를 불러와서 임베딩으로 만들어주고, 임베딩과 label을 순서대로 나열해줘요.
eng_embeddings = get_embeddings(eng_data, batch_size=16)
kor_embeddings = get_embeddings(kor_data, batch_size=16)
all_embeddings = eng_embeddings + kor_embeddings
all_labels = eng_labels + kor_labels
이제 거의 다 왔네요. 임베딩으로 만들어 주면, 보통 BERT 계열 모델이면 768 차원의 임베딩이 생성되는데 이걸 T-SNE 차원축소를 통해 2차원의 array로 만들어 주는거에요. 그러면 우리가 볼 수 있는 좌표 평면 위에 나타낼 수 있겠죠?
all_embeddings_array = np.array(all_embeddings)
tsne_model = TSNE(random_state=42, perplexity=5)
tsne_results = tsne_model.fit_transform(all_embeddings_array)
이제 pyplot을 통해 시각화!
plt.figure(figsize=(10, 8))
for label, color in zip(['English_sentence','Korean_sentence', ], ['blue','red' ]):
indices = [i for i, l in enumerate(all_labels) if l == label]
plt.scatter(tsne_results[indices, 0], tsne_results[indices, 1], label=label, c=color, alpha=0.5)
plt.xticks([]) # X축 숫자 제거
plt.yticks([]) # Y축 숫자 제거
plt.title('t-SNE Visualization of Korean and English Sentences')
plt.legend()
plt.savefig('tsne_visualization.png', dpi=600, bbox_inches='tight')
plt.show()
이미지 저장도 해주고, 시각화 결과물은 아래와 같습니다.

bilingual model이라도 한글과 영어의 임베딩을 의미보다는 언어 차이로 다르게 나타내고 있네요.
이렇게 간단하게 bert bilingual model을 통해서 텍스트 데이터의 임베딩과 t-SNE 차원축소와 pyplot 통해 시각화를 진행해보았어요!

이건 제가 예전에 진행했던 시각화인데, 이렇게 데이터가 많으면 텍스트 데이터의 분포 차이를 한 눈에 알아볼 수 있겠죠?
물론 다른 좋은 방법들도 많지만, 심플하게 시각화할 수 있는 점은 좋은 것 같아요!
그럼 오늘도! 오블완~

'오블완 챌린지' 카테고리의 다른 글
2024.11.12~2024.11.14 EMNLP 학회 후기 (3) | 2024.11.18 |
---|---|
2024.11.15 돌아온 뱅밥 세끼 (1) | 2024.11.16 |
Arlo Wynwood 숙소 후기 (3) | 2024.11.14 |
2024.11.12 뱅밥 세끼 - 2탄 (2) | 2024.11.13 |
2024.11.12 뱅밥 세끼 - 1탄 (11) | 2024.11.12 |