
자연어처리(NLP)에서 원시 텍스트를 머신러닝 모델에 입력하기 위해서는 먼저 전처리(Preprocessing)가 필요하다. 그 중 핵심은 다음 세 가지다:
Tokenization은 문장을 의미 있는 토큰(token)으로 분리하는 작업이다.
Don't be fooled by Mr. O'Neill's e-mail: it's not 'normal'—it's phishing! Visit https://phish.com now.
# 출력 (구두점 제거 + 띄어쓰기 기준)
["Time", "is", "an", "illusion", "Lunchtime", "double", "so"]
Sentence Tokenization은 문장을 구분하는 작업으로, 단순한 마침표(.) 기준 분할은 문제가 생길 수 있다.
I am actively looking for Ph.D. students.
단순 마침표로 자르면 "Ph.D."에서 잘리는 문제가 생김.
NLTK의 sent_tokenize는 이를 잘 처리함. ➡️ 약어 내부 마침표를 구분해준다.
import re
text = "I was wondering if anyone out there could enlighten me on this car."
shortword = re.compile(r'\W*\b\w{1,2}\b')
print(shortword.sub('', text))
표기 통일: USA ↔ US, uh-huh ↔ uhhuh
대소문자 통일:
대부분은 모두 소문자로 변환
단, 고유명사나 US/us처럼 의미가 달라질 경우 예외 고려
text = "Automobile is faster than a bus."
text.lower() # 'automobile is faster than a bus.'
같은 의미의 단어를 하나로 통합하여 모델의 복잡성을 줄인다.
| 단어 | Stemming | Lemmatization |
|---|---|---|
| am | am | be |
| having | hav | have |
| going | go | go |
from nltk.corpus import stopwords
from nltk.tokenize import word_tokenize
example = "Family is not an important thing. It's everything."
stop_words = set(stopwords.words('english'))
tokens = word_tokenize(example)
filtered = [word for word in tokens if word not in stop_words]
['Family', 'important', 'thing', '.', "'s", 'everything', '.']
okt = Okt()
example = "고기를 아무렇게나 구우려고 하면 안 돼. 고기라고 다 같은 게 아니거든. 예컨대 삼겹살을 구울 때는 중요한 게 있지."
stop_words = "를 아무렇게나 구 우려 고 안 돼 같은 게 구울 때 는"
stop_words = set(stop_words.split(' '))
word_tokens = okt.morphs(example)
result = [word for word in word_tokens if not word in stop_words]
['고기', '하면', '.', '고기', '라고', '다', '아니거든', '.', '예컨대', '삼겹살', '을', '중요한', '있지', '.']
자연어 처리에서는 텍스트(문자열)를 모델이 처리할 수 있도록 숫자로 변환해야 해. 그 첫 번째 단계가 바로 정수 인코딩이다.
정수 인덱스 부여:
I → 1
love → 2
natural → 3
language → 4
processing → 5
결과 문장: [1, 2, 3, 4, 5]
| 장점 | 단점 |
|---|---|
| 간단하고 빠름 | 단어 간 관계가 반영되지 않음 |
| 메모리 효율적 | 같은 의미여도 전혀 다른 숫자로 매핑됨 |
정수 인코딩된 값을 0과 1로 구성된 벡터로 변환하는 방법이야.
전체 단어 집합의 크기만큼 차원을 갖고, 해당 단어 위치에만 1, 나머지는 0이야.
정수 인코딩:
I → 0
love → 1
natural → 2
language → 3
processing → 4
One-hot 벡터:
"I" → [1, 0, 0, 0, 0]
"love" → [0, 1, 0, 0, 0]
"natural" → [0, 0, 1, 0, 0]
| 장점 | 단점 |
|---|---|
| 단어 간 구분이 명확함 | 벡터 차원 수가 너무 큼 (단어 수 = 차원 수) |
| 머신러닝 입력으로 쉽게 사용 가능 | 단어 의미나 유사도 반영 못 함 |
Word Embedding은 단어를 저차원의 밀집된 실수 벡터로 표현하는 방법이야.
이 벡터는 학습을 통해 의미 정보(문맥, 유사도 등)를 반영함.
임베딩 벡터 (차원 = 3):
"I" → [0.1, -0.2, 0.05]
"love" → [0.9, 0.1, -0.5]
"natural" → [0.7, -0.8, 0.3]
| 장점 | 단점 |
|---|---|
| 의미 정보를 포함함 | 훈련 데이터가 적으면 부정확할 수 있음 |
| 차원 축소된 효율적 표현 | 훈련에 시간, 자원이 필요 |
문서 벡터화는 텍스트 데이터를 수치화하여 머신러닝/딥러닝 모델이 이해할 수 있는 형태로 변환하는 작업입니다. 대표적인 방식은 아래 두 가지입니다:
DTM(Document-Term Matrix)은 문서들을 행으로, 단어들을 열로 나열한 후,
각 단어가 해당 문서에 몇 번 등장했는지를 빈도수(Frequency)로 기록한 행렬 형태의 표현입니다.
즉, 여러 문서의 BoW(Bag of Words) 결과를 하나의 행렬로 확장한 구조입니다.
희소 행렬(Sparse Matrix)
단순 빈도 기반
TF-IDF는 DTM에 가중치(weight)를 부여한 방식입니다.
문서 간 유사도 비교, 중요 단어 추출 등에 널리 사용됩니다.
TF:
IDF:
TF-IDF:
| 바나나(TF) | DF | IDF | TF-IDF | |
|---|---|---|---|---|
| 문서 1 | 1 | 2 | ||
| 문서 2 | 2 | 2 |
자세한 코드는 깃허브