일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 |
- 딥러닝
- eecs 498
- BFS
- CNN
- 백준
- One-Stage Detector
- Reinforcement Learning
- dynamic programming
- Mask Processing
- LSTM
- image processing
- NLP
- Python
- two-stage detector
- 강화학습
- 그래프 이론
- C++
- machine learning
- r-cnn
- real-time object detection
- deep learning
- opencv
- DP
- MinHeap
- AlexNet
- 머신러닝
- YoLO
- ubuntu
- dfs
- MySQL
- Today
- Total
JINWOOJUNG
[ NLP ] Cleaning & Normalization 본문
본 포스팅은 [딥 러닝을 이용한 자연어 처리 입문]을 기반으로 공부한 내용을 정리하는 포스팅입니다.
https://wikidocs.net/book/2155
Tokenization 전, 후에는 텍스트 데이터를 용도에 맞게 정제(Cleaning) 및 정규화(Normalization)을 수행하게 된다.
- 정제(Cleaning) : Corpus로 부터 Noise 제거
- 정규화(Normalization) : 표현 방법이 다른 단어들을 통합시켜서 같은 단어로 만듦
Cleaning의 경우 Tokenization에 방해가 되는 요소를 제거하기 위해 Tokenization 전에도 사용되지만, 후에도 존재하는 Noise 제거 목적으로 사용된다.
Cleaning
불필요한 단어 제거
Cleaning 에서의 Noise Data는 자연어가 아니면서 의미 없는 글자(특수문자) 뿐만 아니라, 분석 목적에 맞지 않는 불필요한 단어를 의미하기도 한다. 불필요한 단어를 제거하는 방법을 알아보자.
- 등장 빈도가 적은 단어 제거
텍스트 데이터에서 너무 적게 등장하는 단어는 일반적인 패턴을 학습하거나 분류하는데 기여하지 못할 수 있다.
스펨메일을 분류하는 상황에서, 다수의 데이터에서 매우 적게 등장하는 단어는 스펨 메일과 정상 메일을 분류하는데 영향을 주지 않는다. 이처럼 등장 빈도가 적은 단어는 단순 Noise일 가능성이 높고, 해당 단어를 학습한다면 Overfitting 될 수 있다.
- 길이가 짧은 단어
영어권 언어에서는 길이가 짧은 단어를 삭제함으로써 자연어 처리에서 의미가 없는 단어들을 제거하는 효과를 볼 수 있다고 알려져 있다. 즉, 영어권 언어에서는 길이가 짧은 단어들은 대부분 불용어에 해당된다. 또한, 길이를 조건으로 텍스트를 삭제 함으로써 구두점까지도 한번에 제거할 수 있기 때문이다.
하지만 동일한 이론이 한국어에도 적용될 수 있을까? 영어 단어의 평균 길이는 6~7 정도이며, 한국어 단어의 평균 길이는 2~3 정도로 추정된다. 이는 영어 단어와 한국어 단어의 각 한 글자가 가진 의미의 크기가 다르기 때문이다. 한국어는 대부분 한자어기 때문에 한 글자만으로도 의미를 가진 경우가 많다. 예를 들어, "학교"의 "학","교"는 각각 배우다, 학교의 의미를 포함하고 있다. 하지만 영어는 "s","c","h","o","o","l"로 표현된다.
이러한 언어적 차이 때문에 영어권 언어에서는 2~3 이하인 단어를 제거함으로써 의미를 갖지 못하는 단어를 제거할 수 있다. 예를 들어, 길이가 1인 단어를 제거한다면 관사 'a', 주어 'i' 등 자연어 처리에서 의미를 갖지 못하는 단어를 제거할 수 있다. 만약 길이가 2인 단어를 제거한다면 "it","at" 등 대부분 불용어에 해당되는 단어를 제거할 수 있다.
Cleaning 과정은 다음과 같다.
import re
text = "I was wondering if anyone out there could enlighten me on this car."
# 길이가 1~2인 단어들을 정규 표현식을 이용하여 삭제
shortword = re.compile(r'\W*\b\w{1,2}\b')
print(shortword.sub('', text))
# was wondering anyone out there could enlighten this car.
- 불용어(Stopwords)
NLP에서 불용어는 텍스트 처리 과정에서 큰 도움이 되지 않는 단어를 의미한다. 이때, 의미가 없다는 의미는 자주 등장하지만 분석을 하는 것에 있어서는 큰 도움이 되지 않는 단어들을 의미한다. 예를 들면, I, my, me, over, 조사, 접미사 같은 단어들은 문장에서는 자주 등장하지만 실제 의미 분석을 하는데는 거의 기여하는 바가 없는 경우가 있다.
이러한 불용어는 사전에 정의되어 있지만, 개발자가 직접 정의할 수 있다. 본 포스팅에서는 NLTK에서 정의된 불용어와 제거하는 방법을 알아보자.
NLTK가 정의한 영어 불용어는 총 198개로, "a","an","about" 등의 관사, 접속사, 전치사 등이 포함되어 있다.
from nltk.corpus import stopwords
stop_words_list = stopwords.words('english')
print('불용어 개수 :', len(stop_words_list))
print('불용어 10개 출력 :',stop_words_list[:10])
# 불용어 개수 : 198
# 불용어 10개 출력 : ['a', 'about', 'above', 'after', 'again', 'against', 'ain', 'all', 'am', 'an']
불용어를 제거하는 방법은 다음과 같다. 먼저 NLTK의 Tokenization을 수행한 뒤, 각각의 Token이 불용어에 해당되는지 아닌지 판단하면 된다.
from nltk.tokenize import word_tokenize
from nltk.corpus import stopwords
example = "Family is not an important thing. It's everything."
stop_words = set(stopwords.words('english'))
word_tokens = word_tokenize(example)
result = []
for word in word_tokens:
if word not in stop_words:
result.append(word)
print('불용어 제거 전 :',word_tokens)
print('불용어 제거 후 :',result)
# 불용어 제거 전 : ['Family', 'is', 'not', 'an', 'important', 'thing', '.', 'It', "'s", 'everything', '.']
# 불용어 제거 후 : ['Family', 'important', 'thing', '.', 'It', "'s", 'everything', '.']
하국어에서 불용어를 제거하는 방법은 토큰화 후 조사, 접속사 등을 제거하면 된다. 앞서 설명한 것처럼 불용어를 직접 정의하고 해당 불용어를 제거하는 것도 하나의 방법이다.
Okt를 이용해서 Tokenization 수행 이후, 사전에 정의된 한국어 불용어를 제거하는 과정이다.
from nltk.corpus import stopwords
from konlpy.tag import Okt
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]
print('불용어 제거 전 :',word_tokens)
print('불용어 제거 후 :',result)
# 불용어 제거 전 : ['고기', '를', '아무렇게나', '구', '우려', '고', '하면', '안', '돼', '.', '고기', '라고', '다', '같은', '게', '아니거든', '.', '예컨대', '삼겹살', '을', '구울', '때', '는', '중요한', '게', '있지', '.']
# 불용어 제거 후 : ['고기', '하면', '.', '고기', '라고', '다', '아니거든', '.', '예컨대', '삼겹살', '을', '중요한', '있지', '.']
Normalization
규칙에 기반한 표기가 다른 단어 통합
USA와 US는 같은 의미를 가지지만 표기가 다르므로 하나의 단어로 정규화 할 수 있다. "uh-huh","uhhuh"는 형태는 다르지만 여전히 같은 의미를 가진다. 이처럼 직접 코딩을 통해 정의할 수 있는 정규화 규칙의 예로서 같은 의미를 갖고있음에도, 표기가 다른 단어들을 하나의 단어로 정규화할 수 있다.
표기가 다른 단어를 통합하는 방법 중 어간 추출과 표제어 추출은 다음 포스팅에서 진행 할 예정이다.
대, 소문자 통합
영어권 언어에서 대, 소문자를 통합하는 것은 단어의 개수를 줄일 수 있는 또 다른 정규화 방법입니다. 영어권 언어에서 대문자는 문장의 맨 앞 등과 같은 특정 상황에서만 쓰이고, 대부분의 글은 소문자로 작성되기 때문에 대, 소문자 통합 작업은 대부분 대문자를 소문자로 변환하는 소문자 변환작업으로 이루어지게 됩니다.
예를 들어, Autonomous라는 단어가 문장의 가장 앞에 나와서 대문자로 표기되었다면, 대, 소문자 통합 없이는 autonomous를 찾는 질의의 결과로 찾을 수 없게 된다. 이처럼 소문자 변환 작업을 통해 단어의 개수를 줄일 수 있다.
하지만, 무작정 줄이면은 안된다. 예를 들어, '미국'을 뜻하는 US와 '우리'를 뜻하는 us는 명백히 구분되어야 하는 단어이다. 또한, 회사 이름, 사람 이름 등은 대문자로 유지되는 것이 더 명확한 방법이다. 그렇다면 일부만 소문자화를 하고, 규칙을 정의해서 소문자를 수행 한다면 더 좋은 결과가 나올까? 하지만 코퍼스 자체가 유튜브 댓글 등 비공식 입력이라면 해당 규칙의 일관성이 존재하지 않는다. 따라서 "일괄 소문자 변환"이 가장 간단하고 실용적일 수 있다.
'NLP, LLM, Multi-modal' 카테고리의 다른 글
[ VLM ] VLM Tasks와 Benchmarks..(1) (0) | 2025.04.15 |
---|---|
[ NLP ] 어간 추출(Stemming) & 표제어 추출(Lemmatization) (0) | 2025.04.14 |
[ NLP ] Tokenization (0) | 2025.04.13 |
[ NLP ] 자연어 처리를 위한 NLTK, KoNLPy (0) | 2025.04.13 |