딥러닝 파이토치 강좌, 한국어 임베딩

딥러닝의 발전과 함께 자연어 처리(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. 결론

본 글에서는 파이토치를 활용하여 한국어 임베딩을 구현하는 과정을 다루었습니다. 임베딩은 자연어 처리에서 중요한 역할을 하며, 다양한 언어의 특성에 맞춘 전처리가 필요합니다. 향후 더 복잡한 모델과 데이터셋을 다루며 깊이 있는 연구를 진행하는 것을 추천합니다.

이 강좌가 딥러닝과 자연어 처리에 대한 이해를 높이는 데 도움이 되길 바랍니다. 더 궁금한 점이 있다면 댓글로 남겨주세요!