인공지능이 인간의 언어를 이해하게 만드는 과정은 결코 단순하지 않습니다. 우리가 일상적으로 사용하는 '자연어'를 컴퓨터가 계산할 수 있는 '숫자'로 바꾸는 일련의 과정을 차근차근 알아보겠습니다.
1. 자연어(Natural Language)와 NLP
자연어란 우리 인간이 의사소통을 위해 자연스럽게 만들어 사용해 온 언어(한국어, 영어 등)를 말합니다. 이는 정해진 규칙이 엄격한 프로그래밍 언어와 달리, 문맥(Context)에 따라 의미가 변하고 비유와 상징이 섞여 있어 컴퓨터가 처리하기 매우 까다롭습니다.
이를 해결하기 위한 기술이 자연어 처리(NLP, Natural Language Processing)입니다. NLP는 언어학적 지식과 컴퓨터 과학, 그리고 인공지능 기술을 융합하여 텍스트 분석, 번역, 챗봇, 감정 분석 등 다양한 응용 분야를 만들어냅니다.
2. 텍스트 전처리의 핵심: 토큰화와 정수 인코딩
2-1. 토큰화 (Tokenization)
텍스트를 분석하기 위해 가장 먼저 하는 작업은 문장을 의미 있는 최소 단위인 **'토큰(Token)'**으로 나누는 것입니다.
- 단어/어절 토큰화: 공백이나 구두점을 기준으로 나눕니다. 영어는 공백 기준이 명확하지만, 한국어는 조사나 어미가 붙는 '교착어' 특성상 형태소 분석기 사용이 필수적입니다.
- 문장 토큰화: 마침표(.), 물음표(?) 등을 기준으로 문장을 분리합니다.
- Tip: 한국어 문장 분리에는 KSS(Korean Sentence Splitter) 라이브러리가 매우 효과적입니다.
2-2. 정수 인코딩 (Integer Encoding)
컴퓨터는 글자보다 숫자를 훨씬 잘 처리합니다. 따라서 각 토큰에 고유한 정수 번호를 부여하는 과정이 필요합니다.
from tensorflow.keras.preprocessing.text import Tokenizer
from tensorflow.keras.preprocessing.sequence import pad_sequences
# 예시 텍스트
texts = ['커피 한잔 어때', '오늘 날씨 참 좋네', '옷이 어울려요']
# 1. Tokenizer 객체 생성 및 학습
tokenizer = Tokenizer()
tokenizer.fit_on_texts(texts)
# 2. 텍스트를 정수 시퀀스로 변환
sequences = tokenizer.texts_to_sequences(texts)
word_index = tokenizer.word_index
print("단어 인덱스:", word_index)
print("정수 시퀀스:", sequences)
2-3. 패딩 (Padding)
딥러닝 모델은 입력되는 데이터의 길이가 모두 같아야 병렬 연산(행렬 계산)이 가능합니다. 문장마다 단어 개수가 다르기 때문에, 짧은 문장은 0을 채워 길이를 맞춰줍니다.
# 3. 패딩 작업 (최대 길이를 4로 설정)
padded_sequences = pad_sequences(sequences, maxlen=4)
print("패딩된 시퀀스:\n", padded_sequences)
3. 단어 사전과 OOV (Out-Of-Vocabulary)
단어 사전(Vocabulary)은 학습 데이터에서 추출한 고유 단어들의 목록입니다.
하지만 학습할 때 없었던 새로운 단어가 실전(테스트)에서 등장하면 어떻게 될까요? 이를 OOV 문제라고 합니다. 단어 사전에 없는 새로운 단어는 정수 인코딩이나 임베딩으로 변환할 수 없어 모델이 올바르게 처리하지 못하게 되며, 이로 인해 성능 저하가 생깁니다. 이를 해결하기 위해 흔히 OOV 전용 토큰을 만들어 대체하거나, 서브워드 분리(BPE, WordPiece 등) 방법을 사용하여 새로운 단어를 더 작은 단위로 쪼개 처리하는 기법이 활용됩니다.
4. 텍스트의 수치화: 벡터화 (Vectorization)
벡터화는 텍스트 데이터를 숫자 형태로 변환하여 머신러닝 또는 딥러닝 모델에서 처리할 수 있도록 만드는 과정입니다. 이를 위해 단어의 빈도를 기반으로 한 Bag-of-Words(BOW), TF-IDF와 같은 방법부터, 단어 간의 의미적 관계를 학습하는 Word Embedding(단어 임베딩), 문장의 문맥과 구조를 반영하는 Transformer 기반 임베딩(BERT, GPT) 등 다양한 기법이 사용됩니다. 벡터화는 단어, 문장, 문서와 같은 텍스트 데이터의 특징을 수치적으로 표현하며, 단순히 단어의 빈도를 반영하거나 의미적 유사성을 학습하여 벡터 공간에서 단어 간 관계를 나타냅니다. 데이터의 특성과 분석 목적에 따라 적절한 벡터화 기법을 선택하는 것이 중요합니다.
4-1. 원-핫 인코딩 (One-Hot Encoding)
단어 집합의 크기만큼 차원을 만들고, 해당 단어 위치에만 1을, 나머지는 0을 부여합니다.
- 장점: 직관적이고 단순함.
- 단점: 단어 간 유사도를 알 수 없음. 단어가 많아질수록 0이 너무 많은 희소 벡터(Sparse Vector)가 되어 메모리 낭비가 심함.
4-2. Bag of Words (BoW) & DTM
순서는 무시하고 오직 '단어의 빈도'만 고려하는 방식입니다.
from collections import Counter
documents = ["I love Python Python", "Python is great Python", "I love coding coding"]
vocab = sorted(set(word for doc in documents for word in doc.split()))
word_to_index = {word: idx for idx, word in enumerate(vocab)}
bow_vectors = []
for doc in documents:
word_counts = Counter(doc.split())
# 각 단어의 빈도를 리스트에 담음
vector = [word_counts.get(word, 0) for word in vocab]
bow_vectors.append(vector)
print("단어 집합:", vocab)
print("BoW 결과:", bow_vectors)
여러 문서의 BoW를 행렬로 쌓으면 DTM(Document-Term Matrix)이 됩니다.
5. 단어의 중요도를 계산하는 TF-IDF
단순 빈도(BoW)의 치명적인 단점은 'a', 'the', '이', '가' 처럼 의미 없는 기능어들이 자주 등장해 중요하게 취급될 수 있다는 점입니다. 이를 보완한 것이 TF-IDF입니다.
- TF(Term Frequency): 특정 문서에서 단어가 등장하는 빈도.
- IDF(Inverse Document Frequency): 특정 단어가 나타난 문서 수의 역수. (여러 문서에 두루 나타나면 중요도를 낮춤)
핵심: 특정 문서에서는 자주 나오지만, 다른 문서에서는 흔치 않은 단어일수록 값이 높아집니다. 즉, 그 문서를 대표하는 핵심어를 찾기에 적합합니다.
6. 유사도 측정: 코사인 유사도 (Cosine Similarity)
벡터화된 문장들이 서로 얼마나 비슷한지 측정할 때 가장 많이 사용되는 지표입니다. 벡터의 크기(길이)보다 두 벡터가 가리키는 방향(각도)에 집중합니다.
import numpy as np
from sklearn.metrics.pairwise import cosine_similarity
# 예시: 문서 벡터 (DTM 형태)
doc1 = np.array([[0, 1, 1, 1]]) # '사과 바나나 포도'
doc2 = np.array([[1, 0, 1, 1]]) # '메론 바나나 포도'
doc3 = np.array([[2, 0, 2, 2]]) # '메론 메론 바나나 바나나 포도 포도' (패턴은 doc2와 동일)
print('1과 2의 유사도:', cosine_similarity(doc1, doc2))
print('2와 3의 유사도:', cosine_similarity(doc2, doc3)) # 결과: 1.0 (방향이 같음)
코사인 유사도는 빈도수가 두 배로 늘어나더라도(doc2 vs doc3) 그 구성 패턴이 같다면 유사도를 1로 판단하는 강력한 장점이 있습니다.
마무리하며
자연어 처리는 결국 비정형 데이터인 텍스트를 어떻게 효율적인 숫자(벡터)로 바꿀 것인가에 대한 고민의 연속입니다. 오늘 배운 기초적인 벡터화 기법들을 이해해야 나중에 배울 Word2Vec, BERT 같은 최신 임베딩 기술도 쉽게 정복할 수 있습니다!
'개념 정리 step2 > 멀티모달(Multi-modal)' 카테고리의 다른 글
| [RNN] 시퀀스 데이터와 순환 신경망(RNN) 학습 정리 (1) | 2026.01.15 |
|---|---|
| [NLP] 단어 임베딩: Word2Vec부터 FastText, GloVe (0) | 2026.01.14 |
| [Deep Learning] TensorFlow 기초와 날씨 분류 모델 실습 (0) | 2026.01.12 |
| [CV Archive] YOLOv8 Segmentation: 스타벅스 로고 추출하기 (0) | 2026.01.11 |
| [YOLO] 축구 영상 객체 탐지 프로젝트: Nano vs Small 모델 성능 비교 분석 (0) | 2026.01.10 |