콘텐츠로 이동
Data Prep
상세

자연어 처리 개요

자연어 처리(Natural Language Processing, NLP)는 인간 언어를 컴퓨터가 이해하고 생성할 수 있도록 하는 인공지능 분야다. 텍스트 분류, 감성 분석, 기계 번역, 질의응답 등 다양한 응용에 활용됨.


핵심 개념

텍스트 표현

방법 설명 장점 단점
Bag of Words 단어 출현 빈도 벡터 간단 순서 무시, 희소
TF-IDF 빈도 x 역문서빈도 중요 단어 강조 순서 무시
Word2Vec 분산 표현 (CBOW/Skip-gram) 의미 유사도 다의어 미처리
GloVe 전역 동시출현 행렬 분해 전역 통계 활용 다의어 미처리
FastText 서브워드 임베딩 OOV 처리 벡터 크기
ELMo 문맥 의존 임베딩 (BiLSTM) 다의어 처리 느림
BERT Transformer 양방향 SOTA, 전이학습 계산량

토큰화 (Tokenization)

방법 예시 특징
단어 단위 "playing" → "playing" OOV 문제
BPE (Byte Pair Encoding) "playing" → "play", "##ing" GPT 계열
WordPiece "playing" → "play", "##ing" BERT
SentencePiece 언어 무관 다국어

알고리즘 분류 체계

NLP Tasks & Methods
├── Text Classification
│   ├── Traditional: Naive Bayes, SVM, Logistic
│   ├── Neural: CNN, LSTM, Transformer
│   └── Pre-trained: BERT, RoBERTa, DeBERTa
├── Sequence Labeling
│   ├── NER (Named Entity Recognition)
│   ├── POS Tagging
│   └── Methods: CRF, BiLSTM-CRF, BERT+CRF
├── Text Generation
│   ├── Language Models: GPT, LLaMA
│   ├── Seq2Seq: T5, BART
│   └── Decoding: Greedy, Beam, Sampling
├── Information Extraction
│   ├── Relation Extraction
│   ├── Event Extraction
│   └── Knowledge Graph Construction
├── Semantic Analysis
│   ├── Sentiment Analysis
│   ├── Aspect-Based SA
│   └── Emotion Detection
├── Topic Modeling
│   ├── LDA (Latent Dirichlet Allocation)
│   ├── NMF
│   └── BERTopic
├── Question Answering
│   ├── Extractive QA (BERT)
│   ├── Generative QA (T5, GPT)
│   └── RAG (Retrieval-Augmented Generation)
├── Machine Translation
│   ├── Seq2Seq + Attention
│   └── Transformer (mBART, NLLB)
└── Summarization
    ├── Extractive
    └── Abstractive (BART, T5)

텍스트 분류 (Text Classification)

BERT 기반 분류

from transformers import AutoTokenizer, AutoModelForSequenceClassification
from transformers import Trainer, TrainingArguments
import torch

# 모델 로드
model_name = "klue/bert-base"  # 한국어
tokenizer = AutoTokenizer.from_pretrained(model_name)
model = AutoModelForSequenceClassification.from_pretrained(
    model_name, 
    num_labels=3
)

# 토큰화
def tokenize_function(examples):
    return tokenizer(
        examples["text"], 
        padding="max_length", 
        truncation=True,
        max_length=256
    )

tokenized_datasets = dataset.map(tokenize_function, batched=True)

# 학습 설정
training_args = TrainingArguments(
    output_dir="./results",
    num_train_epochs=3,
    per_device_train_batch_size=16,
    per_device_eval_batch_size=64,
    warmup_steps=500,
    weight_decay=0.01,
    logging_dir="./logs",
    evaluation_strategy="epoch",
    save_strategy="epoch",
    load_best_model_at_end=True,
)

trainer = Trainer(
    model=model,
    args=training_args,
    train_dataset=tokenized_datasets["train"],
    eval_dataset=tokenized_datasets["test"],
)

trainer.train()

참고 논문: - Devlin, J. et al. (2019). "BERT: Pre-training of Deep Bidirectional Transformers for Language Understanding". NAACL. - Liu, Y. et al. (2019). "RoBERTa: A Robustly Optimized BERT Pretraining Approach". arXiv.


개체명 인식 (NER)

시퀀스 레이블링 태스크로 텍스트에서 인명, 지명, 기관명 등을 추출.

BIO 태깅: - B-PER: Person 시작 - I-PER: Person 내부 - O: 엔티티 아님

from transformers import AutoTokenizer, AutoModelForTokenClassification
from transformers import pipeline

# NER 파이프라인
ner_pipeline = pipeline(
    "ner", 
    model="klue/bert-base",  # Fine-tuned NER model
    aggregation_strategy="simple"
)

text = "삼성전자 이재용 회장이 서울에서 기자회견을 열었다."
entities = ner_pipeline(text)

# 결과: [{'entity_group': 'ORG', 'word': '삼성전자', ...}, ...]

감성 분석 (Sentiment Analysis)

문서 수준 감성

from transformers import pipeline

# 감성 분석
sentiment_analyzer = pipeline(
    "sentiment-analysis",
    model="nlptown/bert-base-multilingual-uncased-sentiment"
)

result = sentiment_analyzer("이 제품 정말 좋아요!")
# {'label': '5 stars', 'score': 0.85}

속성 기반 감성 분석 (ABSA)

특정 속성(aspect)에 대한 감성 추출:

"이 식당은 음식은 맛있는데 서비스가 별로다" - 음식: 긍정 - 서비스: 부정


토픽 모델링

LDA (Latent Dirichlet Allocation)

문서 집합에서 잠재 토픽 발견:

\[p(w|d) = \sum_{t=1}^{T} p(w|t) \cdot p(t|d)\]
from sklearn.decomposition import LatentDirichletAllocation
from sklearn.feature_extraction.text import CountVectorizer

# 문서-단어 행렬
vectorizer = CountVectorizer(max_df=0.95, min_df=2, max_features=1000)
doc_term_matrix = vectorizer.fit_transform(documents)

# LDA
lda = LatentDirichletAllocation(
    n_components=10,  # 토픽 수
    random_state=42
)
lda.fit(doc_term_matrix)

# 토픽별 주요 단어
feature_names = vectorizer.get_feature_names_out()
for topic_idx, topic in enumerate(lda.components_):
    top_words = [feature_names[i] for i in topic.argsort()[:-10:-1]]
    print(f"Topic {topic_idx}: {', '.join(top_words)}")

BERTopic

BERT 임베딩 기반 토픽 모델링:

from bertopic import BERTopic

topic_model = BERTopic(language="multilingual")
topics, probs = topic_model.fit_transform(documents)

# 토픽 정보
topic_model.get_topic_info()
topic_model.visualize_topics()

참고 논문: - Blei, D.M. et al. (2003). "Latent Dirichlet Allocation". JMLR. - Grootendorst, M. (2022). "BERTopic: Neural Topic Modeling with a Class-based TF-IDF". arXiv.


LLM 시대의 NLP

Prompt Engineering

LLM을 활용한 Zero-shot / Few-shot 학습:

from openai import OpenAI

client = OpenAI()

# Zero-shot 분류
prompt = """다음 리뷰의 감성을 분류하세요: 긍정, 부정, 중립

리뷰: "배송은 빨랐는데 제품 품질이 실망스럽네요"
감성:"""

response = client.chat.completions.create(
    model="gpt-4",
    messages=[{"role": "user", "content": prompt}]
)

RAG (Retrieval-Augmented Generation)

외부 지식을 검색하여 LLM 응답 품질 향상:

from langchain.vectorstores import Chroma
from langchain.embeddings import OpenAIEmbeddings
from langchain.chains import RetrievalQA
from langchain.llms import OpenAI

# 벡터 스토어 생성
embeddings = OpenAIEmbeddings()
vectorstore = Chroma.from_documents(documents, embeddings)

# RAG 체인
qa_chain = RetrievalQA.from_chain_type(
    llm=OpenAI(),
    chain_type="stuff",
    retriever=vectorstore.as_retriever(search_kwargs={"k": 3})
)

answer = qa_chain.run("질문 내용")

참고 논문: - Lewis, P. et al. (2020). "Retrieval-Augmented Generation for Knowledge-Intensive NLP Tasks". NeurIPS.


한국어 NLP

주요 모델

모델 기관 특징
KoBERT SKT BERT 한국어
KoELECTRA 개인 ELECTRA 한국어
KLUE-BERT KLUE 벤치마크와 함께 공개
KoGPT 카카오 GPT 한국어
HyperCLOVA 네이버 대규모 한국어 LLM

형태소 분석

from konlpy.tag import Okt, Mecab

okt = Okt()
text = "자연어 처리는 재미있습니다."

# 형태소 분석
print(okt.morphs(text))  # ['자연어', '처리', '는', '재미있습니다', '.']
print(okt.pos(text))     # [('자연어', 'Noun'), ('처리', 'Noun'), ...]
print(okt.nouns(text))   # ['자연어', '처리']

평가 지표

태스크 지표
분류 Accuracy, F1, AUC-ROC
NER Entity-level F1
생성 BLEU, ROUGE, BERTScore
QA Exact Match, F1
번역 BLEU, COMET

참고 문헌

교과서

  • Jurafsky, D. & Martin, J.H. (2023). "Speech and Language Processing" (3rd ed). (무료 온라인)
  • Goldberg, Y. (2017). "Neural Network Methods for Natural Language Processing". Morgan & Claypool.

핵심 논문

  • Vaswani, A. et al. (2017). "Attention Is All You Need". NeurIPS.
  • Devlin, J. et al. (2019). "BERT". NAACL.
  • Brown, T. et al. (2020). "Language Models are Few-Shot Learners". NeurIPS.

라이브러리

  • Hugging Face Transformers: https://huggingface.co/transformers
  • spaCy: https://spacy.io/
  • KoNLPy: https://konlpy.org/