💡 한 줄 정의: NLP(Natural Language Processing)는 컴퓨터가 사람의 언어를 이해하고 처리하게 만드는 기술입니다.
| 구분 | 정의 | 예시 |
|---|---|---|
| 자연 언어 | 사람들이 자연스럽게 사용하는 언어 | 한국어, 영어, 일본어 |
| 인공 언어 | 목적에 맞게 설계된 언어 | Python, Java, 에스페란토어 |
| 자연어 처리 | 자연언어를 컴퓨터가 해독·이해하는 기술 | 번역, 챗봇, 감성분석 |
자연어 이해 (NLU, Natural Language Understanding)
자연어 생성 (NLG, Natural Language Generation)
| 단계 | 기법 | 해결된 문제 | 진행 중인 문제 |
|---|---|---|---|
| 전통 기법 | 규칙기반, 통계기반 | 스팸분류, 품사결정, 개체명인식, 기본 문서생성 | — |
| 딥러닝 기법 | Word2Vec, BERT, GPT | 감성분석, 구문분석, 기계번역, 정보추출, 요약 | 복잡한 Q&A, 의역, 대화, 창의적 문서 생성 |
⚠️ 핵심 포인트: 대부분의 NLP 문제는 결국 분류(Classification) 문제입니다.
"긍정인가 부정인가?", "스팸인가 아닌가?" 등 카테고리로 분류하는 것이죠.
| 구분 | 기존 방식 (2010년대 이전) | 딥러닝 방식 (최근) |
|---|---|---|
| 핵심 기술 | 규칙기반 + 통계 머신러닝 | Word Embedding + 신경망 |
| 데이터 | 언어 전문가가 만든 고품질 샘플 | 대용량 말뭉치 자동 학습 |
| 전문가 필요 | ✅ 언어학자 필수 | ❌ 불필요 |
| 주요 모델 | 통계 번역(SMT) | BERT, GPT, Transformer |
🍳 요리에 재료가 필요하듯, NLP에도 기본 재료와 도구가 있습니다.
NLP 학습을 위해 모아 놓은 문서 집합입니다.
💡 비유: Word2Vec은 10억~100억 단어 규모의 Corpus로 학습합니다. 요리사가 다양한 식재료를 많이 접할수록 실력이 늘듯, NLP 모델도 많은 문장을 볼수록 언어를 잘 이해합니다.
Token: 텍스트를 분석하기 위해 작게 나눈 조각 (단어, 형태소, 구 등)
Tokenization: 긴 문자열을 여러 Token으로 쪼개는 작업
예시 — 영어 토큰화
입력: "I love Natural Language Processing"
출력: ["I", "love", "Natural", "Language", "Processing"]
특수 Token 종류
| Token | 역할 |
|---|---|
<START> | 문장의 시작을 표시 |
<EOS> | 문장의 끝 (End of Sentence) |
<UNK> | 사전에 없는 미등록 단어 |
<PAD> | 문장 길이를 맞추기 위한 빈 칸 |
Python 토큰화 도구
| 도구 | 특징 |
|---|---|
str.split() | 공백 기준 단순 분리 |
nltk.word_tokenize | 영어에 최적화, 구두점 처리 |
nltk.sent_tokenize | 문장 단위 분리 |
| Hugging Face tokenizers | BPE, WordPiece, SentencePiece 지원 (최신 LLM용) |
영어는 단어를 공백으로 구분하면 되지만, 한국어는 다릅니다.
| 어려움 | 설명 | 예시 |
|---|---|---|
| 교착어 | 조사가 띄어쓰기 없이 바로 붙음 | "학교에서" → 학교 + 에서 |
| 띄어쓰기 | 잘 지켜지지 않음 | "밥먹었어" → "밥 먹었어" |
| 어순 자유 | 어순이 달라도 의미 통함 | "나는 밥을 먹었다" = "밥을 나는 먹었다" |
🛠 해결책: KoNLPy(코엔엘파이) — Komoran, Mecab, Okt 등 한국어 형태소 분석기 내장. 카카오의 Khaiii도 활용 가능.
분석에 큰 의미가 없는 단어들로, 보통 처리 전에 제거합니다.
🔢 컴퓨터는 문자를 직접 이해하지 못합니다. 단어를 숫자(벡터)로 변환해야 합니다.
3가지 주요 방법: BOW → TF-IDF → Word Embedding (점점 발전)
각 문장에서 단어가 몇 번 등장하는지 count하여 벡터로 만드는 방법.
작동 방식
문서 1: "고양이가 뛰어 놀았다"
문서 2: "강아지가 뛰어 놀았다"
어휘 사전: [고양이, 강아지, 뛰어, 놀았다]
문서 1 벡터: [1, 0, 1, 1]
문서 2 벡터: [0, 1, 1, 1]
Python 사용법
from sklearn.feature_extraction.text import CountVectorizer
corpus = ["고양이가 뛰어 놀았다", "강아지가 뛰어 놀았다"]
vectorizer = CountVectorizer()
X = vectorizer.fit_transform(corpus)
BOW의 한계 ⚠️
단어 하나 대신 인접한 N개의 단어를 하나의 토큰으로 처리합니다.
| 종류 | 설명 | 예시 |
|---|---|---|
| 1-gram (unigram) | 단어 1개 | ["not"], ["working"] |
| 2-gram (bigram) | 인접 2개 | ["not working"], ["is working"] |
| 3-gram (trigram) | 인접 3개 | ["not an issue"] |
⚠️ 한계: N이 커질수록 feature(특징) 개수가 기하급수적으로 증가하여 메모리·연산 비용 폭증
BOW의 단순 빈도 문제를 해결합니다. "흔한 단어는 낮게, 특정 문서에서만 자주 쓰이는 단어는 높게" 가중치를 줍니다.
구성 요소
| 개념 | 의미 | 특징 |
|---|---|---|
| TF (단어 빈도) | 특정 문서에서 단어가 얼마나 자주 등장하는가 | 높을수록 해당 문서에서 중요 |
| DF (문서 빈도) | 전체 문서에서 그 단어가 얼마나 흔한가 | the, is, a → DF 높음 |
| IDF (역문서 빈도) | DF의 역수 | 흔할수록 낮아짐 |
| TF-IDF | TF × IDF | 높으면 그 문서에서만 특별한 단어 |
직관적 이해 예시
신문기사 분석 시 "의원이 발의한 법안"에서:
• "법안" → 이 기사에만 자주 등장 → TF-IDF 높음 ✅ (중요한 단어)
• "의원" → 정치 기사에 자주 등장 → TF-IDF 보통
• "했다, 있다" → 모든 기사에 등장 → TF-IDF 낮음 ❌ (의미 없는 단어)
Python 사용법
from sklearn.feature_extraction.text import TfidfVectorizer
vectorizer = TfidfVectorizer()
X = vectorizer.fit_transform(corpus)
사전(Vocabulary)에 있는 단어마다 고유한 번호를 부여하고, 해당 위치만 1, 나머지는 0으로 표현합니다.
예시 (어휘 사전 크기 = 10,000개)
어휘 사전: {apple: 1, aaron: 2, ..., king: 4914, ..., queen: 7157, ..., zebra: 9999}
king → [0, 0, ..., 1, ..., 0] (4914번째만 1)
queen → [0, 0, ..., 1, ..., 0] (7157번째만 1)
apple → [1, 0, 0, ..., 0] (1번째만 1)
한계 ⚠️: king과 queen이 얼마나 비슷한지 전혀 알 수 없습니다. 모든 단어 쌍의 코사인 유사도가 0으로 동일합니다.
신경망은 모든 입력의 길이가 동일해야 합니다. 짧은 문장에 <PAD> 토큰을 채워 길이를 맞춥니다.
["나는", "학생"] → [나는, 학생, <PAD>, <PAD>, <PAD>]
["나는", "밥을", "먹었다"] → [나는, 밥을, 먹었다, <PAD>, <PAD>]
🌌 One-Hot의 한계를 극복하는 핵심 기술. 단어를 다차원 공간의 벡터(실수값)로 표현하여, 비슷한 단어는 가까운 위치에 놓습니다.
"비슷한 맥락에서 등장하는 단어는 비슷한 의미를 갖는다"
예) "이사금께 충성을 맹세하였다."
"왕에게 충성을 맹세하였다."
→ "이사금"이 무슨 뜻인지 모르더라도,
주변 단어 패턴이 비슷하므로 "왕"과 비슷한 의미일 것이라고 추론 가능
Word Embedding의 3대 장점
단어 벡터는 의미적 관계를 연산으로 표현할 수 있습니다.
4차원 벡터 예시
| 단어 | 성별 | 귀족 | 나이 | 음식 |
|---|---|---|---|---|
| King | -1.0 | 0.95 | 0.70 | 0.02 |
| Queen | +1.0 | 0.97 | 0.60 | 0.03 |
| Man | -1.0 | 0.01 | 0.50 | 0.05 |
| Woman | +1.0 | 0.01 | 0.50 | 0.04 |
King - Man + Woman ≈ Queen ✅
Paris - France + Japan ≈ Tokyo ✅ (수도-국가 관계도 학습!)
One-Hot 벡터(희소, 매우 큰 차원)에 Embedding Matrix를 곱하여 작은 차원의 dense 벡터를 얻습니다.
어휘 사전 크기 = 10,000개
One-Hot 벡터 = 10,000차원 (거의 다 0)
↓ Embedding Layer
임베딩 벡터 = 300차원 (실수값으로 가득)
💡 실제로는 Embedding Matrix의 k번째 행을 그냥 조회(lookup)하는 것과 동일합니다. 행렬 곱셈보다 훨씬 빠릅니다.
구글이 2013년 발표한 Word Embedding 방법. 얕은 신경망(은닉층 1개)을 사용하며, 대규모 비지도학습으로 단어 벡터를 자동 학습합니다.
두 가지 학습 방법
| 방법 | 설명 | 특징 |
|---|---|---|
| Skip-gram | 중심 단어 → 주변 단어 예측 | 드문 단어에 강함, 느린 학습 |
| CBOW | 주변 단어들 → 중심 단어 예측 | 빠른 학습 |
Skip-gram 학습 예시 (window size = 2)
입력 문장: "I love king of Korea"
중심 단어: king
예측 대상: [I, love, of, Korea] ← 앞뒤 2개씩
→ "king"의 주변에 자주 등장하는 단어들을 학습하면서
"king"의 벡터 표현이 점점 정교해짐
두 단어 벡터 사이의 각도를 이용해 유사도를 측정합니다.
코사인 유사도 = (A · B) / (|A| × |B|)
| 값 | 의미 | 예시 |
|---|---|---|
| ≈ 1.0 | 매우 유사 | king ↔ queen |
| ≈ 0.5 | 관련 있음 | king ↔ castle |
| ≈ 0.0 | 관련 없음 | king ↔ pizza |
| ≈ -1.0 | 반대 의미 | good ↔ bad |
king – queen ≈ man – woman (성별 관계 학습 ✅)
Paris – France ≈ Tokyo – Japan (수도-국가 관계 학습 ✅)
good – better ≈ bad – worse (비교급 관계 학습 ✅)
🔗 시각화 데모: https://ronxin.github.io/wevi/
| 방법 | 단어 순서 | 단어 유사성 | 의미 파악 | 특징 |
|---|---|---|---|---|
| BOW | ❌ | ❌ | ❌ | 단순, 빠름 |
| n-gram | 부분 ✅ | ❌ | ❌ | feature 폭증 문제 |
| TF-IDF | ❌ | ❌ | ❌ | 중요도 가중치 반영 |
| One-Hot | ❌ | ❌ | ❌ | 차원 폭발 문제 |
| Word Embedding | ✅ | ✅ | ✅ | 현재 표준, 전이학습 가능 |
Q1. "phone is working"과 "phone is not working"을 같은 의미로 처리하는 방법은?
정답: BOW (Bag of Words) — 단어 순서를 무시하고 단순 빈도만 카운트하기 때문
Q2. 전체 문서에서 흔하게 등장하는 단어(the, is, a)의 TF-IDF 값은?
정답: 낮다 — IDF가 낮아지기 때문 (역문서 빈도이므로 흔할수록 IDF↓ → TF-IDF↓)
Q3. Word2Vec에서 중심 단어로 주변 단어를 예측하는 방법은?
정답: Skip-gram
Q4. "king - man + woman = ?"의 결과는?
정답: queen — Word Embedding이 단어 간 의미적 관계를 벡터로 학습했기 때문