Step 8 컴퓨터가 언어를 읽는 법

NLTK 기초 - 토큰화, 어간 추출, 형태소 분석

1. 자연어 처리(NLP)의 시작

컴퓨터는 숫자만 이해합니다. 하지만 우리는 "고양이가 귀엽다"라는 문장을 컴퓨터가 이해하길 원하죠. 어떻게 해야 할까요? 이것이 바로 자연어 처리(Natural Language Processing, NLP)의 첫 번째 과제입니다.

🧠 컴퓨터가 언어를 이해하는 과정

문장 → 숫자 변환 과정 1. 원문 "고양이가 귀엽다" 2. 토큰화 ["고양이가", "귀엽다"] 3. 정제 ["고양이", "귀엽다"] 4. 숫자화 [42, 108] 컴퓨터가 이해!

2. NLTK란?

NLTK (Natural Language Toolkit)는 Python에서 가장 유명한 자연어 처리 라이브러리입니다. 텍스트를 분석하는 기본 도구들을 제공하죠.

📦 NLTK 설치 및 데이터 다운로드

# 1. NLTK 설치
pip install nltk

# 2. Python에서 필요한 데이터 다운로드
import nltk

nltk.download('punkt')       # 토큰화 모델
nltk.download('stopwords')  # 불용어 리스트
nltk.download('wordnet')    # 표제어 추출용

3. 토큰화 (Tokenization)

문장을 의미 있는 단위로 쪼개는 작업입니다. 한국어는 "고양이가"를 "고양이"+"가"로, 영어는 "I'm"을 "I"+"'m"으로 나눠야 하죠.

🔪 단어 토큰화 (Word Tokenization)

토큰화 예시 "The cat is cute." The cat is cute .
from nltk.tokenize import word_tokenize

text = "The cat is cute."
tokens = word_tokenize(text)
print(tokens)  
# ['The', 'cat', 'is', 'cute', '.']

📄 문장 토큰화 (Sentence Tokenization)

from nltk.tokenize import sent_tokenize

text = "Hello world. This is NLP. It's fun!"
sentences = sent_tokenize(text)
print(sentences)
# ['Hello world.', 'This is NLP.', "It's fun!"]

4. 어간 추출 (Stemming)

단어의 어간(stem)을 추출합니다. "running", "runner", "runs" → 모두 "run"으로!

✂️ Porter Stemmer

Stemming 원리 변환 전 running runner runs ran ↓ Stemming 변환 후 run
from nltk.stem import PorterStemmer

stemmer = PorterStemmer()

words = ["running", "runner", "runs", "ran"]
for word in words:
    print(f"{word}{stemmer.stem(word)}")

# running → run
# runner → runner (완벽하지 않음)
# runs → run
# ran → ran (불규칙 동사는 못 잡음)

⚠️ Stemming의 한계

단순 규칙 기반이라 완벽하지 않습니다:
• "better" → "better" (good의 비교급인데 못 잡음)
• "studies" → "studi" (단어가 아닌 형태로 변환)
→ 더 정교한 방법이 필요해요!

5. 표제어 추출 (Lemmatization)

단어를 사전 형태(표제어)로 변환합니다. Stemming보다 정확하지만 느립니다.

📖 WordNet Lemmatizer

원본 Stemming Lemmatization 비고
running run run ✅ 둘 다 OK
better better good ✅ Lemma가 우수
studies studi study ✅ Lemma가 정확
was wa be ✅ Lemma가 정확
from nltk.stem import WordNetLemmatizer

lemmatizer = WordNetLemmatizer()

# 품사를 지정해야 정확함!
print(lemmatizer.lemmatize("better", pos='a'))  # 'a'=형용사 → good
print(lemmatizer.lemmatize("running", pos='v'))  # 'v'=동사 → run
print(lemmatizer.lemmatize("studies", pos='v'))  # study

6. 불용어 제거 (Stopwords Removal)

의미 없는 단어(a, the, is, are 등)를 제거합니다. 문장 분석에 방해만 되니까요!

🚫 불용어 필터링

불용어 제거 전후 제거 전 (9개 단어) ["The", "cat", "is", "on", "the", "mat", "and", "it", "looks", "cute"] 불용어 불용어 불용어 불용어 불용어 ↓ 불용어 제거 제거 후 (4개 단어) ["cat", "mat", "looks", "cute"]
from nltk.corpus import stopwords
from nltk.tokenize import word_tokenize

# 영어 불용어 목록
stop_words = set(stopwords.words('english'))
print(f"불용어 개수: {len(stop_words)}")  # 179개

text = "The cat is on the mat"
tokens = word_tokenize(text)

# 불용어 제거
filtered = [w for w in tokens if w.lower() not in stop_words]
print(filtered)  # ['cat', 'mat']

7. 전체 파이프라인

지금까지 배운 걸 모두 합쳐서 텍스트 전처리 파이프라인을 만들어봅시다!

🔄 텍스트 전처리 파이프라인

NLP 전처리 파이프라인 1. 소문자 변환 The Cat → the cat 2. 토큰화 → [the, cat, ...] 3. 불용어 제거 → [cat, ...] 4. 표제어 추출 → [cat, ...] ✅ 전처리 완료! 깨끗한 토큰 리스트 → 모델 학습 준비 완료
import nltk
from nltk.tokenize import word_tokenize
from nltk.corpus import stopwords
from nltk.stem import WordNetLemmatizer

def preprocess_text(text):
    # 1. 소문자 변환
    text = text.lower()
    
    # 2. 토큰화
    tokens = word_tokenize(text)
    
    # 3. 불용어 제거
    stop_words = set(stopwords.words('english'))
    tokens = [w for w in tokens if w not in stop_words]
    
    # 4. 알파벳만 남기기
    tokens = [w for w in tokens if w.isalpha()]
    
    # 5. 표제어 추출
    lemmatizer = WordNetLemmatizer()
    tokens = [lemmatizer.lemmatize(w) for w in tokens]
    
    return tokens

# 테스트
text = "The cats are running quickly on the streets."
clean_tokens = preprocess_text(text)
print(clean_tokens)
# ['cat', 'running', 'quickly', 'street']

🎯 다음 단계는?

이제 텍스트를 토큰으로 나눴습니다! 하지만 컴퓨터는 여전히 문자를 이해하지 못하죠.

"cat"을 어떻게 숫자로 바꿀까요?

다음 Step 9에서 원핫 인코딩(One-Hot Encoding)으로 단어를 벡터로 변환해봅시다! 🚀