컴퓨터는 숫자만 이해합니다. 하지만 우리는 "고양이가 귀엽다"라는 문장을 컴퓨터가 이해하길 원하죠. 어떻게 해야 할까요? 이것이 바로 자연어 처리(Natural Language Processing, NLP)의 첫 번째 과제입니다.
NLTK (Natural Language Toolkit)는 Python에서 가장 유명한 자연어 처리 라이브러리입니다. 텍스트를 분석하는 기본 도구들을 제공하죠.
# 1. NLTK 설치 pip install nltk # 2. Python에서 필요한 데이터 다운로드 import nltk nltk.download('punkt') # 토큰화 모델 nltk.download('stopwords') # 불용어 리스트 nltk.download('wordnet') # 표제어 추출용
문장을 의미 있는 단위로 쪼개는 작업입니다. 한국어는 "고양이가"를 "고양이"+"가"로, 영어는 "I'm"을 "I"+"'m"으로 나눠야 하죠.
from nltk.tokenize import word_tokenize text = "The cat is cute." tokens = word_tokenize(text) print(tokens) # ['The', 'cat', 'is', 'cute', '.']
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!"]
단어의 어간(stem)을 추출합니다. "running", "runner", "runs" → 모두 "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" (단어가 아닌 형태로 변환)
→ 더 정교한 방법이 필요해요!
단어를 사전 형태(표제어)로 변환합니다. Stemming보다 정확하지만 느립니다.
| 원본 | 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
의미 없는 단어(a, the, is, are 등)를 제거합니다. 문장 분석에 방해만 되니까요!
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']
지금까지 배운 걸 모두 합쳐서 텍스트 전처리 파이프라인을 만들어봅시다!
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)으로 단어를 벡터로 변환해봅시다! 🚀