"데이터 전처리에 딥러닝 모델을 태우면 얼마나 좋아질까? 그리고 시간은 얼마나 걸릴까?"
자연어 처리(NLP) 프로젝트를 진행하다 보면 가장 먼저 마주하는 벽은 **'데이터의 질(Quality)'**입니다. 특히 네이버 영화 리뷰 데이터(NSMC) 같은 댓글 데이터는 오타, 띄어쓰기 무시, 은어 사용이 빈번해 모델 학습을 어렵게 만듭니다.
이번 포스팅에서는 가장 기본적인 정규표현식(Regex) 전처리 방식과, Hugging Face의 KoBART 기반 문법 교정(GEC) 모델을 활용한 전처리 방식을 비교 실험해 보았습니다.
과연 딥러닝 모델을 활용한 전처리가 단어 사전(Vocab Size) 최적화에 얼마나 기여할 수 있을지, 그리고 그에 따른 **시간 비용(Trade-off)**은 어느 정도인지 직접 확인해 보겠습니다.
ratings_train.txt (약 15만 건)Soyoung97/gec_kr (KoBART 기반 한국어 문법 교정)두 가지 방식으로 데이터를 정제한 뒤, Mecab으로 토큰화하여 비교했습니다.
가장 일반적인 방법입니다. 한글, 영어, 기본 문장부호를 제외한 모든 특수문자를 제거합니다. 속도가 매우 빠릅니다.
import re
def preprocessor(text):
if pd.isnull(text):
return ""
text = text.lower()
# 한글, 영어, 공백, 마침표 등만 남기고 제거
text = re.sub(r"[^가-힣a-zA-Z\s.?!,]", " ", text)
text = re.sub(r"[.?!,]", " ", text)
text = re.sub(r"\s+", " ", text).strip()
return text
df["clean_document"] = df["document"].apply(preprocessor)
Method A로 1차 정제된 텍스트를 문법 교정(GEC) 모델에 통과시켜 문장을 다시 생성(Generation)하는 방식입니다. 오타와 띄어쓰기를 교정합니다.
model.half()(FP16) 적용, Batch Processing 활용# (코드 일부 발췌)
@torch.no_grad()
def gec_correct_batch(texts, max_length=128):
# ... 토크나이징 과정 ...
out = model.generate(
**enc,
max_length=max_length,
num_beams=4, # 빔 서치로 정확도 향상
repetition_penalty=2.0, # 반복 생성 억제
early_stopping=True
)
return tokenizer.batch_decode(out, skip_special_tokens=True)
실제 전처리된 데이터를 비교해보면 GEC 모델의 효과가 명확히 드러납니다.
| Label | Original | Clean (Regex) | GEC (KoBART) | 비고 |
|---|---|---|---|---|
| 1 | 흠...포스터보고 초딩영화줄... | 흠 포스터보고 초딩영화줄... | 흠 포스터보고 초딩영화줄 오버연기조차 가볍지 않구나 | 문맥 유지 |
| 0 | 너무재밓었다그래서... | 너무재밓었다그래서... | 너무재밌었다그래서... | 오타 교정 |
| 0 | 인간이 문제지.. 소는 뭔죄인가.. | 인간이 문제지 소는 뭔죄인가 | 인간이 문제지 소는 무슨 죄인가 | 구어체 순화 |
정규표현식은 특수문자만 지울 뿐, "재밓었다" 라는 오타를 수정하지 못합니다. 반면, KoBART 모델은 문맥을 파악하여 "재밌었다" 로 표준화시켰습니다.
전체 15만 건의 데이터를 Mecab으로 토큰화(morphs)한 뒤, 전체 토큰 개수와 고유 토큰(Unique Token) 개수를 계산했습니다.
# clean_tokens[:50] 출력 결과 중 일부
# ... '초딩', '영화', '줄', ... '너무', '재', '밓었다', ...
👉 문제점: 출력 결과에서 볼 수 있듯 '재', '밓었다' 처럼 오타로 인해 잘못 분리된 토큰들이 사전에 포함되어 Vocab 크기를 불필요하게 늘리고 있습니다.
# gec_tokens[:50] 출력 결과 중 일부
# ... '초딩', '영화', '줄', ... '너무', '재밌', '었', '다', ...
👉 개선점:
약 1,600개의 불필요한 노이즈 토큰이 제거되었습니다. 이는 Embedding Layer의 파라미터 수를 줄이고, 모델이 희소한(Sparse) 오타 토큰을 학습하느라 낭비하는 자원을 줄여 학습 효율을 높이는 데 기여합니다.
하지만 이 1,600개의 토큰을 줄이기 위한 비용은 적지 않았습니다.
[참고 자료]