Q1. 텍스트 데이터를 모델에 적용하기 전에 어떤 전처리 과정을 거치나요?
A1. 정제(특수문자), 토큰화(의미 분리), 정규화(대소문자&어간&표제어), 불용어 제거(조사&관사&전치사), 벡터화(숫자 연산)
Q2. FastText가 Word2Vec과 다른 점은 무엇이며, 어떤 장점이 있나요?
A2. Word2Vec은 word단위(ex. preorder)로 구분하고 FastText는 subword단위(ex. pre, order) 단위로 구분. 더 작은 단위로 학습을 하기에 처음 보는 단어, 신조어, 오타에 강건.
Q3. Attention 메커니즘이 Seq2Seq 모델의 어떤 문제를 해결하는 데 도움이 되나요?
A3. 정보 병목 문제. 이는 벡터화 압축 때문. Attention은 매 단계마다 입력 문장 전체를 다시 훑어보고 현재 가장 필요한 정보에 집중할 수 있게 하여 이 문제를 해결.
Q4. Transformer 모델은 Seq2Seq 구조와 어떤 점에서 근본적으로 다른가요?
A4. Seq2Seq는 단어를 하나씩 순서대로 처리하는 순차(Sequential) 방식. Transformer는 문장의 모든 단어를 한 번에 처리하는 병렬(Parallel) 방식. 'Self Attention' 기술 덕분.
<div>, <p> 등의 태그.@, #, $ 등의 기호.studies → studi). 속도는 빠르나 정교함이 떨어짐.are, is → be). 정교하지만 더 많은 계산이 필요함.| 단계 | 목표 (하는 일) | 비유 | 주요 기법 / 고려사항 |
|---|---|---|---|
| 정제 | 노이즈 데이터 제거 | 재료 씻기 | HTML 태그, 특수 문자, URL 제거 |
| 토큰화 | 의미 단위로 분할 | 재료 썰기 | 단어 토큰화, 서브워드 토큰화(BPE 등) |
| 정규화 | 표현 형태 통일 | 비슷한 재료 모으기 | 대소문자 통일, 표제어/어간 추출 |
| 불용어 제거 | 불필요한 단어 제거 | 장식 덜어내기 | 문맥에 따라 신중하게 적용 |
| 벡터화 | 숫자 데이터로 변환 | 숫자로 계량하기 | TF-IDF, 워드 임베딩 |
def preprocess_text(text):
# 1. 정제
text = text.lower()
text = re.sub(r'[^a-z\s]', '', text)
# 2. 토큰화
tokens = word_tokenize(text)
# 3. 불용어 제거
stop_words = set(stopwords.words('english'))
tokens = [token for token in tokens if token not in stop_words]
# 4. 표제어 추출
lemmatizer = WordNetLemmatizer()
lemmatized_tokens = [lemmatizer.lemmatize(token) for token in tokens]
return " ".join(lemmatized_tokens)
lan, ang, age 등의 글자 조각이 많으므로 유사한 의미의 벡터를 생성해낼 수 있음.| 항목 | Word2Vec | FastText |
|---|---|---|
| 기본 처리 단위 | 단어 (Word) | 내부 단어 (Character n-grams) |
| OOV 처리 | 불가능. Unknown 토큰으로 처리하거나 무시함. | 가능. n-gram 벡터 합으로 새로운 단어 벡터 유추. |
| 형태소 정보 | 반영하지 못함. | 반영함. 단어 내부 구조를 학습. |
| 오타/신조어 | 취약함. | 강건함 (Robust). |
| 메모리 사용량 | 상대적으로 적음. | n-gram 정보로 인해 훨씬 많음. |
# 샘플 문장 데이터
sentences = [['i', 'love', 'deep', 'learning'], ['i', 'love', 'nlp']]
# 모델 학습
w2v_model = Word2Vec(sentences, vector_size=100, window=2, min_count=1)
ft_model = FastText(sentences, vector_size=100, window=2, min_count=1)
# OOV 단어 테스트
# Word2Vec은 학습한 적 없는 'loving'에 대한 벡터를 얻을 수 없음
try:
w2v_vector = w2v_model.wv['loving']
# FastText는 글자 조각으로 'loving' 벡터를 유추함
ft_vector = ft_model.wv['loving']
print("FastText: ft_vector.shape)
# 유사도 비교
ft_model.wv.similarity('love', 'loving')
| 구분 | Seq2Seq (without Attention) | Seq2Seq (with Attention) |
|---|---|---|
| 정보 전달 방식 | 고정된 크기의 단일 컨텍스트 벡터 (병목) | 동적이고 유연한 어텐션 컨텍스트 벡터 |
| 정보 손실 | 긴 문장에서 정보 손실 심각 | 입력 시퀀스 전체를 직접 참조하여 정보 손실 최소화 |
| 해석 가능성 | 어려움 (블랙박스) | 어텐션 가중치 시각화로 판단 근거 추론 가능 |
| 항목 | Seq2Seq | Transformer |
|---|---|---|
| 핵심 아키텍처 | 순환 신경망 (RNN) | 셀프 어텐션 (Self-Attention) |
| 데이터 처리 | 순차적 (Sequential) | 병렬적 (Parallel) |
| 속도 | 느림 (병렬화 한계) | 매우 빠름 (GPU 활용 극대화) |
| 순서 정보 처리 | RNN 구조 자체에 내재 | 포지셔널 인코딩을 별도로 추가해야 함 |
| 대표 모델 | 초창기 번역/요약 모델 | BERT, GPT, T5 등 현대 모든 LLM |
# Transformer의 인코더 구조를 사용하는 BERT 모델 로드
tokenizer = BertTokenizer.from_pretrained('bert-base-uncased')
model = BertModel.from_pretrained('bert-base-uncased')
text = "The transformer architecture allows for parallel processing."
# 토큰화 및 텐서 변환
inputs = tokenizer(text, return_tensors="pt")
# 모델 실행
with torch.no_grad():
outputs = model(**inputs)
# 모든 토큰에 대한 문맥적 임베딩 결과
contextual_embeddings = outputs.last_hidden_state
텍스트 데이터를 모델에 적용하기 전에 반드시 전처리 과정을 거쳐야 합니다. 텍스트는 구조화되지 않은 형태로 존재하기 때문에, 이를 수치적으로 처리 가능한 형태로 변환해주는 것이 전처리의 핵심 목적입니다.
가장 기본적인 전처리는 불필요한 문자 제거입니다. 예를 들어, HTML 태그, 특수 문자, 숫자, 이모지 등을 제거하거나 필요한 경우에만 유지하는 식으로 데이터를 정리합니다.
그다음으로는 소문자 변환을 많이 사용합니다. 대소문자를 통일함으로써 'Apple'과 'apple'을 같은 단어로 취급하게 되어 불필요한 중복을 줄일 수 있습니다.
또한, 불용어 제거도 중요한 과정입니다. 불용어는 '의', '이', '가', 'the', 'is', 'and'처럼 자주 등장하지만 분석에 큰 의미가 없는 단어들로, 이들을 제거하면 모델이 더 중요한 단어에 집중할 수 있습니다.
토큰화(Tokenization)도 핵심 과정 중 하나입니다. 문장을 단어, 형태소, subword 단위 등으로 나누는 과정이며, 사용하는 언어와 목적에 따라 다양한 방식이 적용됩니다.
그 외에도 어간 추출(Stemming)이나 표제어 추출(Lemmatization)을 통해 단어의 기본 형태를 통일할 수도 있고, 중복 공백 제거, 이상값 필터링, 맞춤법 교정 등의 세부적인 정제 작업도 포함될 수 있습니다.
이러한 전처리 과정을 통해 텍스트를 모델이 학습할 수 있는 일관된 입력 형태로 정리함으로써, 학습 효율과 성능을 향상시킬 수 있습니다.
FastText는 Word2Vec과 비슷한 방식으로 단어 임베딩을 학습하는 모델이지만, 단어를 더 작은 단위인 서브워드(Subword)로 분해해서 학습한다는 점에서 차이가 있습니다.
Word2Vec은 단어 전체를 하나의 단위로 보고 벡터를 학습합니다. 예를 들어 'apple'이라는 단어가 있다면, 이 단어 자체에 대한 벡터만 학습됩니다. 반면 FastText는 'app', 'ppl', 'ple' 같은 n-gram 단위의 조각으로 단어를 분해하고, 이 조각들의 임베딩을 평균내거나 합쳐서 단어 벡터를 구성합니다.
이 방식의 장점은 특히 형태가 유사한 단어들 간의 관계를 잘 반영할 수 있다는 점입니다. 예를 들어 'run', 'running', 'runner'처럼 비슷한 형태를 가진 단어들은 공통된 서브워드를 공유하므로, FastText는 이들 간의 의미적 유사성을 자연스럽게 학습할 수 있습니다.
또 하나의 큰 장점은 OOV(Out-of-Vocabulary) 문제를 완화할 수 있다는 점입니다. Word2Vec은 학습 데이터에 없는 단어는 임베딩할 수 없지만, FastText는 서브워드 단위로 처리하기 때문에 처음 보는 단어라도 그 조각들을 이용해 벡터를 생성할 수 있습니다.
결과적으로 FastText는 희귀 단어, 신조어, 오타 등이 포함된 데이터셋에서도 더 강건한 성능을 보일 수 있고, 특히 형태소 기반 언어나 언어 자원이 부족한 상황에서도 유용하게 활용될 수 있는 모델입니다.
Attention 메커니즘은 Seq2Seq(Sequence-to-Sequence) 모델이 가지는 중요한 한계를 해결하는 데 큰 도움을 줍니다.
기본적인 Seq2Seq 모델은 입력 시퀀스를 인코더가 하나의 고정된 벡터로 요약하고, 디코더는 이 벡터만을 바탕으로 전체 출력을 생성합니다. 그런데 입력 문장이 길어질수록, 인코더가 모든 정보를 하나의 벡터에 압축하는 데 한계가 생기고, 그로 인해 디코더는 필요한 문맥 정보를 충분히 받지 못하게 됩니다. 이로 인해 성능이 떨어지거나 문장의 앞부분은 잘 예측하면서도 뒷부분은 틀리는 문제가 자주 발생합니다.
이때 Attention 메커니즘을 적용하면, 디코더는 인코더의 전체 hidden state 중에서 매 시점에 필요한 부분에 '집중(attend)'해서 정보를 가져올 수 있게 됩니다. 즉, 입력 시퀀스 전체를 한꺼번에 압축하는 대신, 각 출력 단어를 생성할 때마다 입력 시퀀스의 특정 위치에 더 많은 가중치를 두고 참고할 수 있습니다.
이 덕분에 모델은 긴 문장에서도 필요한 문맥 정보를 유연하게 반영할 수 있고, 장기 의존성 문제(long-term dependency)를 완화할 수 있습니다. 결과적으로 번역, 문장 생성, 질의응답 같은 자연어 처리 과제에서 Seq2Seq 모델의 성능이 크게 향상됩니다.
Transformer 모델은 Seq2Seq 구조와 비교했을 때, 가장 큰 근본적인 차이점은 RNN을 사용하지 않고, 전적으로 Attention 메커니즘만으로 시퀀스를 처리한다는 점입니다.
전통적인 Seq2Seq 모델은 RNN, LSTM, GRU 같은 순환 신경망 구조를 사용하여 입력 시퀀스를 시간 순서대로 처리합니다. 이 구조는 시간 흐름을 따라 정보를 전달할 수 있지만, 병렬 연산이 어렵고, 긴 시퀀스일수록 학습 속도가 느려지며, 장기 의존성 문제가 발생할 수 있습니다.
반면 Transformer는 모든 입력 토큰 간의 관계를 한 번에 계산할 수 있는 Self-Attention 메커니즘을 기반으로 동작합니다. 덕분에 각 단어가 문장 내 다른 단어들과 어떻게 연결되는지를 병렬적으로 학습할 수 있으며, 연산 속도가 빠르고, 긴 문장에서도 정보 손실 없이 문맥을 반영할 수 있습니다.
또한 Transformer는 Positional Encoding이라는 기법을 사용해 입력 토큰의 순서 정보를 보완합니다. 이는 RNN처럼 순차적으로 데이터를 처리하지 않기 때문에 발생할 수 있는 순서 정보 손실 문제를 해결하는 방식입니다.
결과적으로 Transformer는 Seq2Seq보다 병렬 처리 효율이 뛰어나고, 긴 문장에서도 더 안정적인 성능을 보이며, 기계 번역, 텍스트 요약, 문장 생성 등 다양한 자연어처리 과제에서 기존 Seq2Seq을 대체하고 있습니다.