딥러닝의 발전과 함께 자연어 처리(NLP) 분야에서도 많은 혁신이 이루어지고 있습니다. 특히, 언어의 벡터 표현인 임베딩(embedding)은 딥러닝 모델에서 중요한 역할을 하고 있습니다. 본 글에서는 파이토치(PyTorch)를 활용하여 한국어 임베딩을 구현하는 방법을 자세히 설명하겠습니다.
1. 임베딩이란?
임베딩은 단어나 문장을 고차원 공간의 벡터로 변환하여 머신러닝 모델이 이해할 수 있는 형태로 만드는 과정입니다. 이는 단어 간의 유사성을 반영할 수 있도록 합니다. 예를 들어, ‘왕’과 ‘여왕’의 임베딩 벡터는 서로 가깝게 위치하게 됩니다.
2. 한국어 자연어 처리
한국어는 다양한 형태소로 구성되어 있어 영어와 같은 언어에 비해 자연어 처리에서 더 복잡합니다. 이를 해결하기 위해 한국어 형태소 분석기를 사용할 수 있습니다. 대표적인 형태소 분석기에는 KoNLPy, mecab, khaiii 등이 있습니다.
2.1 KoNLPy 설치 및 사용법
KoNLPy는 간편하게 한국어 자연어 처리를 할 수 있게 도와주는 라이브러리입니다. 아래는 KoNLPy의 설치 방법과 기본 사용법입니다.
!pip install konlpy
2.2 기본 사용 예제
from konlpy.tag import Okt
okt = Okt()
text = "딥러닝은 인공지능의 한 분야입니다."
print(okt.morphs(text)) # 형태소 분석
print(okt.nouns(text)) # 명사 추출
print(okt.phrases(text)) # 구 추출
3. 파이토치(Pytorch)로 임베딩 구현하기
이제 우리는 모델을 구축하고, 한국어 데이터를 처리하여 임베딩을 실행할 준비가 되었습니다.
3.1 데이터셋 준비
텍스트 데이터를 준비합니다. 여기서는 간단한 한국어 문장 리스트를 사용하겠습니다.
sentences = [
"안녕하세요",
"딥러닝은 재미있습니다.",
"파이썬을 사용하여 머신러닝을 배울 수 있습니다.",
"인공지능은 우리의 미래입니다."
]
3.2 텍스트 전처리
형태소 분석기를 사용하여 단어를 추출하고, 이를 사용하여 임베딩을 만들 준비를 합니다.
from collections import Counter
import numpy as np
# 형태소 분석
def preprocess(sentences):
okt = Okt()
tokens = [okt.morphs(sentence) for sentence in sentences]
return tokens
tokens = preprocess(sentences)
# 단어 집합 생성
flat_list = [item for sublist in tokens for item in sublist]
word_counter = Counter(flat_list)
word_vocab = {word: i + 1 for i, (word, _) in enumerate(word_counter.most_common())} # 0은 패딩을 위한 자리
3.3 파이토치 데이터로더 구성
단어 벡터를 생성하기 위해 파이토치의 데이터로더를 활용하겠습니다.
import torch
from torch.utils.data import Dataset, DataLoader
class CustomDataset(Dataset):
def __init__(self, tokens, word_vocab):
self.tokens = tokens
self.word_vocab = word_vocab
def __len__(self):
return len(self.tokens)
def __getitem__(self, idx):
sentence = self.tokens[idx]
return torch.tensor([self.word_vocab[word] for word in sentence], dtype=torch.long)
dataset = CustomDataset(tokens, word_vocab)
dataloader = DataLoader(dataset, batch_size=2, shuffle=True)
3.4 임베딩 모델 구축
이제 임베딩 레이어를 포함한 모델을 구축하겠습니다.
import torch.nn as nn
class WordEmbeddingModel(nn.Module):
def __init__(self, vocab_size, embedding_dim):
super(WordEmbeddingModel, self).__init__()
self.embeddings = nn.Embedding(vocab_size, embedding_dim)
def forward(self, input):
return self.embeddings(input)
embedding_dim = 5
model = WordEmbeddingModel(vocab_size=len(word_vocab) + 1, embedding_dim=embedding_dim)
3.5 임베딩 학습하기
모델을 학습하기 위해 손실 함수와 옵티마이저를 설정하겠습니다.
loss_function = nn.CrossEntropyLoss()
optimizer = torch.optim.SGD(model.parameters(), lr=0.01)
# 간단한 예시로 5epoch만 학습
for epoch in range(5):
for i, data in enumerate(dataloader):
model.zero_grad()
output = model(data)
label = data.view(-1) # 레이블 설정 (예시로 동일한 단어를 사용)
loss = loss_function(output.view(-1, len(word_vocab) + 1), label)
loss.backward()
optimizer.step()
print(f"Epoch {epoch + 1}, Loss: {loss.item()}")
3.6 임베딩 결과 시각화
임베딩 결과를 시각화하여 단어 간의 관계를 직관적으로 이해할 수 있습니다. 여기서는 t-SNE를 사용하여 2D로 시각화하겠습니다.
from sklearn.manifold import TSNE
import matplotlib.pyplot as plt
def visualize_embeddings(model, word_vocab):
embeddings = model.embeddings.weight.data.numpy()
words = list(word_vocab.keys())
tsne = TSNE(n_components=2)
embeddings_2d = tsne.fit_transform(embeddings)
plt.figure(figsize=(10, 10))
for i, word in enumerate(words):
plt.scatter(embeddings_2d[i, 0], embeddings_2d[i, 1])
plt.annotate(word, (embeddings_2d[i, 0], embeddings_2d[i, 1]), fontsize=9)
plt.show()
visualize_embeddings(model, word_vocab)
4. 결론
본 글에서는 파이토치를 활용하여 한국어 임베딩을 구현하는 과정을 다루었습니다. 임베딩은 자연어 처리에서 중요한 역할을 하며, 다양한 언어의 특성에 맞춘 전처리가 필요합니다. 향후 더 복잡한 모델과 데이터셋을 다루며 깊이 있는 연구를 진행하는 것을 추천합니다.
이 강좌가 딥러닝과 자연어 처리에 대한 이해를 높이는 데 도움이 되길 바랍니다. 더 궁금한 점이 있다면 댓글로 남겨주세요!