뉴스 기사를 읽고 "이건 스포츠 뉴스야" 또는 "이건 정치 뉴스야"라고 판단하는 작업입니다. 이미지 분류(MNIST)와 똑같은 원리인데, 입력이 이미지가 아니라 텍스트라는 것만 다르죠!
우리가 사용할 데이터셋은 AG News입니다. 뉴스 기사를 4개 카테고리로 분류하는 문제예요.
예시:
제목: "Wall St. Bears Claw Back Into the Black"
본문: "Reuters - Short-sellers, Wall Street's dwindling band of ultra-cynics..."
레이블: Business (2번)
컴퓨터가 단어를 이해하려면 숫자로 바꿔야 합니다. 가장 간단한 방법이 바로 원핫 인코딩이에요!
import numpy as np # 어휘 사전 vocab = {'cat': 0, 'dog': 1, 'bird': 2, 'fish': 3, 'hamster': 4} vocab_size = len(vocab) def one_hot_encode(word): vec = np.zeros(vocab_size) vec[vocab[word]] = 1 return vec print(one_hot_encode('cat')) # [1, 0, 0, 0, 0] print(one_hot_encode('dog')) # [0, 1, 0, 0, 0] print(one_hot_encode('bird')) # [0, 0, 1, 0, 0]
💡 그래서 이후 Step에서는?
Word2Vec, GloVe 같은 밀집(Dense) 임베딩을 배워요.
벡터 길이 100~300 정도로 줄이면서, 단어 의미도 표현!
한 단어가 아니라 문장 전체를 벡터로 만들려면 어떻게 할까요?
문장에 각 단어가 몇 번 등장했는지만 세는 방법입니다. 순서는 무시해요!
from collections import Counter import numpy as np # 어휘 사전 vocab = {'the': 0, 'cat': 1, 'sat': 2, 'on': 3, 'mat': 4} def bag_of_words(sentence, vocab): words = sentence.lower().split() vec = np.zeros(len(vocab)) for word in words: if word in vocab: vec[vocab[word]] += 1 return vec sentence = "The cat sat on the mat" bow = bag_of_words(sentence, vocab) print(bow) # [2. 1. 1. 1. 1.]
이제 Bag of Words 벡터를 입력으로 받아서 뉴스 카테고리를 예측하는 MLP를 만들어봅시다!
import torch import torch.nn as nn class MLPTextClassifier(nn.Module): def __init__(self, vocab_size, num_classes=4): super().__init__() self.fc1 = nn.Linear(vocab_size, 512) self.fc2 = nn.Linear(512, 256) self.fc3 = nn.Linear(256, num_classes) self.dropout = nn.Dropout(0.5) self.relu = nn.ReLU() def forward(self, x): # x: [batch_size, vocab_size] - BoW 벡터 x = self.relu(self.fc1(x)) x = self.dropout(x) x = self.relu(self.fc2(x)) x = self.dropout(x) x = self.fc3(x) # Softmax는 CrossEntropyLoss가 알아서 처리 return x # 모델 생성 model = MLPTextClassifier(vocab_size=20000, num_classes=4) print(f"파라미터 수: {sum(p.numel() for p in model.parameters()):,}")
MLP + 원핫 인코딩은 가장 간단한 베이스라인입니다.
예상 정확도: 약 85-88%
이유:
• Bag of Words는 단어 순서를 무시함 ("dog bites man" = "man bites dog")
• 원핫 인코딩은 단어 의미를 표현 못 함
• 희소 벡터라 학습이 비효율적
하지만 놀랍게도 88%는 나쁘지 않은 시작입니다!
다음 Step들에서 점점 개선해나갈게요 🚀
MLP로 베이스라인을 만들었습니다! 하지만 개선할 점이 많죠.
문제점:
• 단어 순서 무시 → 문맥 이해 불가
• 희소 벡터 → 메모리 낭비
• 모든 단어가 동등 → 중요한 단어 강조 못 함
다음 Step 10에서 TF-IDF + CNN으로 단어 중요도를 반영해봅시다! 🚀