✅ Tokenization, Cleaning & Normalization, Stopwords, Integer Encoding, Vectorization

📌 개요

자연어처리(NLP)에서 원시 텍스트를 머신러닝 모델에 입력하기 위해서는 먼저 전처리(Preprocessing)가 필요하다. 그 중 핵심은 다음 세 가지다:

  • Tokenization (토큰화)
  • Cleaning & Normalization (정제 & 정규화)
  • Stopwords removal (불용어 제거)

1. Tokenization (토큰화)

✔️ 정의

Tokenization은 문장을 의미 있는 토큰(token)으로 분리하는 작업이다.

✔️ Word Tokenization (단어 단위)

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"]

도구별 차이점

  • nltk.word_tokenize → "Don't" → ["Do", "n't"]
  • WordPunctTokenizer → "Don't" → ["Don", "'", "t"]
  • text_to_word_sequence → 모두 소문자로, 특수문자 제거

✔️ Sentence Tokenization (문장 단위)

Sentence Tokenization은 문장을 구분하는 작업으로, 단순한 마침표(.) 기준 분할은 문제가 생길 수 있다.

I am actively looking for Ph.D. students.

단순 마침표로 자르면 "Ph.D."에서 잘리는 문제가 생김.
NLTK의 sent_tokenize는 이를 잘 처리함. ➡️ 약어 내부 마침표를 구분해준다.



2. Cleaning & Normalization (정제 & 정규화)

✔️ Cleaning (정제)

  • 노이즈 제거: 특수기호, HTML 태그, 불필요한 숫자 등 제거
  • 길이가 짧은 단어 제거: 영어에서 의미 없는 단어가 제거됨
    예: I, a, to, at 등은 삭제해도 큰 문제 없음
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))

✔️ Normalization (정규화)

  • 표기 통일: USA ↔ US, uh-huh ↔ uhhuh

  • 대소문자 통일:

    • 대부분은 모두 소문자로 변환

    • 단, 고유명사나 US/us처럼 의미가 달라질 경우 예외 고려

text = "Automobile is faster than a bus."
text.lower()  # 'automobile is faster than a bus.'

✔️ 어간추출 vs 표제어추출

같은 의미의 단어를 하나로 통합하여 모델의 복잡성을 줄인다.

어간추출 (Stemming)

  • 규칙 기반 단순 어미 제거
  • 종종 사전에 존재하지 않는 단어가 생성됨

표제어추출 (Lemmatization)

  • 문맥, 품사 기반의 원형 단어 추출
  • 정확도 높음

예시 비교

단어StemmingLemmatization
amambe
havinghavhave
goinggogo


3. Stopwords (불용어 제거)

✔️ 정의

  • 분석에 기여하지 않는 흔한 단어들
  • 영어: I, me, is, and 등
  • 한국어: 은, 는, 을, 를 등

✔️ 영어 불용어 제거

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]
['고기', '하면', '.', '고기', '라고', '다', '아니거든', '.', '예컨대', '삼겹살', '을', '중요한', '있지', '.']


4. Integer Encoding(원핫인코딩, 워드임베딩)

📌 개요

자연어 처리에서는 텍스트(문자열)를 모델이 처리할 수 있도록 숫자로 변환해야 해. 그 첫 번째 단계가 바로 정수 인코딩이다.

  • 예시 문장: "I love natural language processing"
  • 단어 목록 = ["I", "love", "natural", "language", "processing"]

정수 인덱스 부여:

I → 1  
love → 2  
natural → 3  
language → 4  
processing → 5
결과 문장: [1, 2, 3, 4, 5]

✔️ 장점 & 단점

장점단점
간단하고 빠름단어 간 관계가 반영되지 않음
메모리 효율적같은 의미여도 전혀 다른 숫자로 매핑됨

One-hot Encoding (원-핫 인코딩)

📌 개요

정수 인코딩된 값을 0과 1로 구성된 벡터로 변환하는 방법이야.
전체 단어 집합의 크기만큼 차원을 갖고, 해당 단어 위치에만 1, 나머지는 0이야.

  • 예시 문장: "I love natural language processing"
  • 단어 목록 = ["I", "love", "natural", "language", "processing"]

정수 인코딩:

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 (단어 임베딩)

📌 개요

Word Embedding은 단어를 저차원의 밀집된 실수 벡터로 표현하는 방법이야.
이 벡터는 학습을 통해 의미 정보(문맥, 유사도 등)를 반영함.

  • 예시 문장: "I love natural language processing"
  • 단어 목록 = ["I", "love", "natural", "language", "processing"]

임베딩 벡터 (차원 = 3):

"I"        → [0.1, -0.2, 0.05]  
"love"     → [0.9, 0.1, -0.5]  
"natural"  → [0.7, -0.8, 0.3]

✔️ 학습 방식

  • 랜덤 초기화 후 신경망 훈련 과정에서 함께 학습됨
  • 또는 사전 훈련된 임베딩 사용
    예: Word2Vec, GloVe, FastText 등

✔️ 장점 & 단점

장점단점
의미 정보를 포함함훈련 데이터가 적으면 부정확할 수 있음
차원 축소된 효율적 표현훈련에 시간, 자원이 필요


5. 문서 백터화(Vectorization)

🔸 개념 정리

문서 벡터화는 텍스트 데이터를 수치화하여 머신러닝/딥러닝 모델이 이해할 수 있는 형태로 변환하는 작업입니다. 대표적인 방식은 아래 두 가지입니다:

  1. DTM (Document-Term Matrix)
  2. TF-IDF (Term Frequency - Inverse Document Frequency)

1️⃣ DTM (문서 단어 행렬)

✔️ 정의

DTM(Document-Term Matrix)은 문서들을 행으로, 단어들을 열로 나열한 후,
각 단어가 해당 문서에 몇 번 등장했는지를 빈도수(Frequency)로 기록한 행렬 형태의 표현입니다.
즉, 여러 문서의 BoW(Bag of Words) 결과를 하나의 행렬로 확장한 구조입니다.

⚠️ DTM의 한계

  1. 희소 행렬(Sparse Matrix)

    • 대부분의 단어가 특정 문서에 나타나지 않기 때문에 0이 많은 행렬이 됩니다.
    • 저장 공간 낭비 + 연산 비효율성 발생
  2. 단순 빈도 기반

    • 의미 없는 단어(the, is 등 불용어)도 높은 빈도를 가질 수 있어 정확한 비교가 어려움

2️⃣ TF-IDF

✔️ 개념

TF-IDF는 DTM에 가중치(weight)를 부여한 방식입니다.
문서 간 유사도 비교, 중요 단어 추출 등에 널리 사용됩니다.

  • TF (Term Frequency): 특정 문서에서 단어 t가 등장한 횟수
  • DF (Document Frequency): 단어 t가 등장한 문서 수
  • IDF (Inverse Document Frequency): 드물게 등장할수록 중요도가 높다고 판단

✔️ 수식 (문자 그대로 보기용)

TF:

tf(d,t)=문서 d에서 단어 t의 등장 횟수tf(d, t) = \text{문서 } d \text{에서 단어 } t \text{의 등장 횟수}

IDF:

idf(t)=log(n1+df(t))idf(t) = \log \left( \frac{n}{1 + df(t)} \right)

TF-IDF:

tfidf(d,t)=tf(d,t)×idf(t)tfidf(d, t) = tf(d, t) \times idf(t)

✔️ 예시 비교

바나나(TF)DFIDFTF-IDF
문서 112log(41+2)0.287\log\left(\frac{4}{1+2}\right) ≈ 0.2871×0.2871 \times 0.287
문서 222log(41+2)0.287\log\left(\frac{4}{1+2}\right) ≈ 0.2872×0.287=0.5752 \times 0.287 = 0.575

자세한 코드는 깃허브

0개의 댓글