코딩세상
[자연어 처리] 텍스트 전처리 및 단어 임베딩 - 텍스트 전처리 본문
- 모델링을 위한 데이터 탐색 및 전처리
앞서 기본적인 머신러닝 및 딥러닝 모델 학습 과정을 진행할 때 구현하고자 하는 목표에 맞게 데이터를 탐색하고 해당 데이터 내의 이상치를 제거하고, 올바르게 학습 할 수 있도록 정규화를 진행하는 등 기본적인 데이터의 준비 과정이 있었습니다.
그렇다면 자연어 처리에서는 어떻게 데이터를 준비하고 가공해야할까요?
자연어 처리에서는 텍스트가 곧 데이터 이므로 모델에 맞는 텍스트 데이터를 탐색하고 데이터 내의 필요없는 단어들(특수기호, 단어 정규화(이, 그, 저, 어느 와 같은 조사 제거) 등 앞서 보았던 데이터 전처리와 비슷한 맥락으로 진행되게 됩니다.
- Tokenization
텍스트를 전처리 하는 과정 중 우리는 각 텍스트를 단어 별로 나누는 토큰화(tokenization)를 거치게 됩니다.
이는 주어진 텍스트를 위의 그림과 같이 각각의 단어를 기준으로 분리하는 것을 의미합니다.
그렇다면 토큰화를 할 때의 기준은 어떻게 설정되어 있을까요?
가장 기본적인 기준은 공백을 기준으로 설정하게 됩니다.
이렇게 우리가 공백을 기준으로 토큰화를 진행하였다면 위 텍스트에서 필요 없는 것들은 어떤 것이 있을까요? 바로 '?'와 ','입니다.
그렇기 때문에 우리는 특수 기호들을 제거하고 단어들을 소문자로 일괄적으로 바꿔주면서 동일한 의미의 토큰을 동일한 형태로 변환하게 됩니다.
그러면 간단하게 위에서 설명한 것처럼 단어를 순차적으로 전처리 해보겠습니다.
- 단어의 개수 및 빈도수 확인
word_counter = dict()
with open(파일명, 'r') as f:
for line in f:
for word in line.rstrip().split():
if word not in word_counter:
word_counter[word] = 1
else:
word_counter[word] += 1
위 코드는 텍스트 파일을 열어 파일 내의 각각의 문자열을 불러오고 각 문자열을 쪼갯을 때 단어로만 이루어져 있으면 빈 딕셔너리인 word_counter에 1을 저장하고 그리고 여러개의 단어로 이루어져 있으면 해당 단어의 개수에 따라 딕셔너리word_counter에 1을 합연산 하도록 구성된 코드입니다.
우리는 이를 통해 텍스트 파일 내에 있는 각각의 문자열들이 몇개의 단어로 이루어져 있는지 dict형태로 확인할 수 있게 됩니다.
- 자연어 처리 + 머신러닝
대부분 단어 빈도수의 분포는 지프의 법칙(Zipf's law)을 따르는데, 여기서 지프의 법칙이란?
수학적 통계를 바탕으로 밝혀진 경험적 법칙으로, 물리 및 사회 과학 분야에서 연구된 많은 종류의 정보들이 지프 분포에 가까운 경향을 보인다는 것을 뜻합니다.
그렇다면 위 그래프가 나타내는 의미는 어떤 것일까요?
지프의 법칙에 따르면 어떠한 자연어 말뭉치 표현에 나타나는 단어들을 그 사용 빈도가 높은 순서대로 나열하였을 때, 모든 단어의 사용 빈도는 해당 단어의 순위에 반비례합니다. 따라서 가장 사용 빈도가 높은 단어는 두 번째 단어보다 빈도가 약 두 배 높으며, 세 번째 단어보다는 빈도가 세 배 높습니다.
- 전처리 1 : 특수 기호 제거
우리가 위에서 설명 한 것 중 특수 기호를 지우고 단어들만 남긴다고 했던 부분이 있었습니다. 해당 부분을 코드로 구현하면 아래와 같이 구현할 수 있습니다.
import re
word = "123hello993 $!%wor$@^ld"
regex = re.compile('[^a-z A-z]')
print(regex.sub('', word))
# hello world
위 코드에서 import 한 re는 정규표현식 라이브러리이며, 여기서 정규표현식이란 정의하는 규칙을 가진 문자열의 집합을 말합니다.
따라서 변수 regex에 저장된 re.compile('[^a-z A-z]')는 소문자와 대문자 알파벳을 compile한 것이고, 이를 print문에서 사용하여 compile한 것을 바탕으로 원하는 문장을 .sub()함수를 이용하여 알파벳 소문자와 대문자를 제외한 다른 단어들은 모두 없애서 출력하게 됩니다.
- 전처리 2: Stopword 제거
영어에서 Stopword란 문법적인 기능을 지닌 단어와 불필요하게 자주 발생하는 단어를 의미합니다. 텍스트 전처리에서 이러한 Stopword는 큰 의미가 없으므로 이것을 제거해주는 과정을 거치게 됩니다.
위에서 설명한 내용을 코드로 작성하면 아래와 같습니다.
import nltk
from nltk.corpus import stopwords
sentence = ["the", "blue", "apple", "and", "a", "ham"]
stopwords = stopwords.words('english')
new_sentence = [word for word in sentence if word not in stopwords]
print(new_sentence)
#["blue", "apple", "ham"]
기본적으로 파이썬에서 nltk라는 라이브러리에서 stopwords를 지원하며 이것을 사용하여 간단하게 stopwords를 제거하여 텍스트를 전처리 할 수 있습니다.
import nltk
from nltk.corpus import stopwords
new_stopwords = ["none", "는", "가"]
stopwords = stopwords.words('English')
stopwords += new_stopwords
- 전처리2: Stemming
그리고 텍스트를 전처리 하는 과정에서 영어 단어의 경우 복수형, 단수형, 과거형, 미래형 등 많은 형태의 단어들이 있지만 원초적으로는 시간에 따른 분류일 뿐 단어들은 모두 동일한 의미를 지니고 있습니다.
그렇기 때문에 텍스트 전처리에서는 동일한 의미의 단어이지만, 문법적인 이유 등으로 인해 표현 방식이 다양한 단어를 공통된 형태로 변환해주게 되는데 이것을 Stemming이라고 합니다.
nltk라이브러리에서 Stemming 역시 지원해주고 있으며, 이를 코드로 적용시키면 아래와 같이 적용할 수 있습니다.
import nltk
from nltk.stem import PorterStemmer
words = ["studies", "studied", "studying", "dogs", "dog"]
stemmer = PorterStemmer()
for word in words:
print(stemmer.stem(word)) # studi, studi, studi, dog, dog
# 출처 및 참고자료
엘리스 AI 트랙 7기 - [이론] 텍스트 전처리 및 단어 임베딩
'인공지능' 카테고리의 다른 글
[자연어 처리] 텍스트 전처리 및 단어 임베딩 - wrod2vec (0) | 2023.09.27 |
---|---|
[자연어 처리] 텍스트 전처리 및 단어 임베딩 - 단어 임베딩 (0) | 2023.09.27 |
[자연어 처리] 텍스트 전처리 및 단어 임베딩 - 자연어 처리 (0) | 2023.09.24 |
[이미지] Convolutional Neural Network - 대표적인 CNN 모델 (0) | 2023.09.20 |
[이미지] Convolutional Neural Network - Convolutional Neural Network (2) | 2023.09.18 |