2019. 1. 23. 00:24ㆍUdacity Nanodegree/Natural Language Processing
텍스트의 복잡도를 낮추기 위한 작업
영어에서는 문장의 첫 글자는 대문자이다
스타일 이슈때문에 단어를 모두 대문자로 쓰는 경우도 있다
따라서 텍스트 처리를 위해 보통 모든 문자를 소문자로 두곤 한다.
NLP의 목적에 따라 punctuation을 없애버리기도 한다.
마침표, 쉼표, 느낌표 등등
이러한 방법은 문서 분류(document classification), 군집화(clustering)와 같이 세부적인 디테일이 그렇게 중요하지 않은 경우에 사용한다
정규 표현식을 다음과 같이 사용한다.
text = re.sub(r"[^a-zA-Z0-9]", " ", text)
a~z, A~Z, 또는 0~9가 아닌 문자를 모두 공백으로 치환한다.
여기서 중요한 점은 아예 없애는 것이 아닌 공백으로 치환한다는 점이다.
이는 문장의 형태를 최대한 유지하기 위함이다.
정리하면, 소문자 변환이나 punctuation 제거는 가장 흔하게 쓰이는 Text normalization방법이다
Tokenization
Token은 Symbol을 세련된 말로 표현하는 방법이며, 뜻을 가지고 있는 상태로 더이상 쪼갤 수 없는 상태인 것들을 지칭한다
NLP의 경우 각각의 단어를 Token이라고 칭한다
따라서 Tokenization이라고 하면 문장을 단어별로 나누는 작업을 칭한다
Text데이터에서 이러한 Tokenization을 가장 간단하게 해 볼수 있는 방법은 python의 split()을 통한 방법이다.
이 경우, List형태의 단어 묶음을 받는다.
기본적으로 ' '(스페이스, space)를 기준으로 나눈다.
여기서는 tab이나 new line문자(\n)도 기준에 포함한다.
또한 2개 이상의 공백도 무시함으로써 공백 문자를 받는 것을 방지한다.
필요할 경우, 이러한 기준을 따로 설정하는 parameter가 있다
여기까지 우리는 python의 빌트인(built-in) 함수를 통한 방법을 알아봤지만, 이 중에서 몇몇 방법은 NLTK 라이브러리를 사용한다면 훨씬 수월하게 진행할 수 있다.
NLTK: Natural Language Toolkit
문장을 가장 수월하게 나눌 수 있는 방법에는 nltk.tokenize를 불러오는 방법이 있다.
from nltk.tokenize import word_tokenize
이 경우, python의 split()과 비슷하게 동작하지만 좀더 스마트하게 작동한다.
punctuation이 문장 내 위치에 따라 다르게 취급된다.
때론 텍스트 전체를 문장 단위로 나눠야 할 때도 있다.
문장을 번역하고 싶을 경우에 이러한 작업이 발생한다.
from nltk.tokenize import sent_tokenize
이렇게 문장을 나누고 나면 각 문장을 단어로 나누는 작업도 할 수 있다.
NLTK는 다른 여러가지 tokenizer를 제공한다.
정규 표현식 기반
Tweet tokenizer
트위터 핸들이나 해쉬태그나 이모티콘도 분류해준다.
더 세부적인 내용을 살펴보고 싶다면
nltk.tokenize
내용을 살펴보자
Stop Word Removal
Stop word란 is, at, or, 등등... 과 같은 문장 내에서 크게 의미를 가지지 않는 단어들을 말한다.
이러한 stop word를 제거해 주는 과정을 거치면서 우리가 작업해야 하는 단어의 종류를 줄일 수 있다.
이런 과정을 통해 추후의 과정에서의 복잡성을 조금이라도 줄일 수 있다.
예를 들면, dogs are the best라는 문장에서 are과 the를 빼면, dogs best만 남는다.
이 단어들만 가지고도 충분히 문장이 긍정적인 감정을 가진다는 것을 볼 수 있다.
NLTK를 이용하면 어떤 단어들이 stop word인지 볼 수 있다.
# List stop words
from nltk.corpus import stopwords
print(stopwords.words("english")) # stop words in English이러한 stop word의 corpus는 라이브러리나 프로그램에 따라 다르다.
또한 용도에 따라서는 stop word가 아닐 수도 있게 된다.
stop word를 제거하기 위해 다음과 같은 코드를 사용한다.
words = [w for w in words if w not in stopwords.words("english")]
문장을 리스트로 받아 그중 stop word에 해당하는 것들을 지워주는 코드
Part-of-Speech Tagging
PoS(Part-of-Speech)란 문장 내에서 단어의 품사를 말한다.
명사, 동사, 대명사, 등등이 이에 포함된다.
문장 내에서 단어가 어떻게 쓰였는지에 대해 살펴보는 것은 문장이 어떤것을 말하고자 하는지 이해하는데에 도움이 된다.
또한 문장 내에서 단어와 단어간의 관계를 집어 살펴보거나, 단어들 간의 상호 참조와 같은 관계를 살펴보기에 용이하다.
NLTK는 이번에도 이러한 작업을 쉽고 편하게 만들어준다.
pos_tag함수를 통해 이러한 작업을 쉽게 할 수 있다.
from nltk import pos_tag
# Tag parts of speech (PoS)
sentence = word_tokenize("I always lie down to tell a lie")
pos_tag(sentence)
잘 살펴본다면 알겠지만 같은 lie라는 단어도 문장의 위치에 따라 VBP(동사)와 NN(명사)로 구분되는 것을 확인할 수 있다.
각 태그가 어떤 뜻인지 살펴보려면 NLTK 공식 문서를 확인해 보자
이러한 PoS Tagging을 통해 문장 parsing을 할 수도 있다.
# Define a customer grammer
my_grammer = nltk.CFG.fromstring("""
S -> NP VP
PP -> P NP
NP -> Det N | Det N PP | 'I'
VP -> V NP | VP PP
Det -> 'an' | 'my'
N -> 'elephant' | 'pajamas'
V -> 'shot'
P -> 'in'
""")
parser = nltk.ChartParser(my_grammar)
# Parse a sentence
sentence = word_tokenize("I shot an elephant in my pajamas")
for tree in parser.parse(sentence):
print(tree)
# Visualize parse trees
for tree in parser.parse(sentence):
tree.draw()
위 코드를 진행하면 아래와 같은 결과가 나온다.
'Udacity Nanodegree > Natural Language Processing' 카테고리의 다른 글
Text Processing(4) - 한장 요약 (0) | 2019.01.23 |
---|---|
Text Processing(3) - 텍스트 내에서의 분류/변환작업 (0) | 2019.01.23 |
Text Processing(1) - 데이터 클리닝(Data Cleaning/Cleansing) (0) | 2019.01.20 |
NLP의 작업 과정 (0) | 2019.01.20 |
Welcome to the Natural Language Processing Nanodegree (0) | 2019.01.17 |