Preprocessing - Stemming & Lemmatization

미분류

2020. 1. 8. 09:08

1. Stemming and Lemmatization (Normalization)

이번 챕터에서는 정규화 기법(Normalization, 표현방법이 다른 단어들을 통합시켜서 같은 단어로 만든다) 중 코퍼스에 있는 단어의 개수를 줄일 수 있는 기법인 표제어 추출(lemmatization)과 어간 추출(stemming)의 개념에 대해서 알아봅니다. 또한 이 둘의 결과가 어떻게 다른지 이해합니다. 이 두 작업이 갖고 있는 의미는 눈으로 봤을 때는 서로 다른 단어들이지만, 하나의 단어로 일반화시킬 수 있다면 하나의 단어로 일반화시켜서 문서 내의 단어 수를 줄이겠다는 것입니다. 이러한 방법들은 단어의 빈도수를 기반으로 문제를 풀고자 하는 BoW(Bag of Words) 표현을 사용하는 자연어 처리 문제에서 주로 사용됩니다. BoW 표현은 뒤의 4챕터에서 배우게 됩니다. 자연어 처리에서 전처리, 더 정확히는 정규화의 지향점은 언제나 갖고 있는 코퍼스로부터 복잡성을 줄이는 일입니다.

 

 


Stemming (문맥정보 X)

am → am
the going → the go
having → hav

 

Lemmatization (문맥정보 O)

am → be
the going → the going
having → have

 


 

2. 표제어 추출(Lemmatization) - 문맥정보를 고려해 어근 찾기

표제어(Lemma)는 한글로는 '표제어' 또는 '기본 사전형 단어' 정도의 의미를 갖습니다. 표제어 추출은 단어들로부터 표제어를 찾아가는 과정입니다. 표제어 추출은 단어들이 다른 형태를 가지더라도, 그 뿌리 단어를 찾아가서 단어의 개수를 줄일 수 있는지 판단합니다. 예를 들어서 am, are, is는 서로 다른 스펠링이지만 그 뿌리 단어는 be라고 볼 수 있습니다. 이 때, 이 단어들의 표제어는 be라고 합니다. 형태소는 두 가지 종류가 있습니다. 각각 어간(stem)과 접사(affix)입니다.

 


어간(stem) : 단어의 의미를 담고 있는 단어의 핵심 부분.

접사(affix) : 단어에 추가적인 의미를 주는 부분.

 


 

형태학적 파싱은 이 두 가지 구성 요소를 분리하는 작업을 말합니다. 가령, cats라는 단어에 대해 형태학적 파싱을 수행한다면, 형태학적 파싱은 결과로 cat(어간)와 -s(접사)를 분리합니다. 꼭 두 가지로 분리되지 않는 경우도 있습니다. 단어 fox는 형태학적 파싱을 한다고 하더라도 더 이상 분리할 수 없습니다. fox는 독립적인 형태소이기 때문입니다. 이와 유사하게 cat 또한 더 이상 분리되지 않습니다.

 

# import nltk
# nltk.download('wordnet')

from nltk.stem import WordNetLemmatizer

n = WordNetLemmatizer()
words=['policy', 'doing', 'organization', 'have', 'going', 'love', 'lives', 'fly', 'dies', 'watched', 'has', 'starting']
print([n.lemmatize(w) for w in words])

# 출력
# ['policy', 'doing', 'organization', 'have', 'going', 'love', 'life', 'fly', 'dy', 'watched', 'ha', 'starting']

 

3. 어간 추출(Stemming) - 문맥정보를 고려하지 않고 어근 찾기

 


 

Stemming :

단어만 고려, 간단한 룰기반으로 수행되는 경우가 많으며 처리가 간단함

 

Lemmatization :

단어 외에도 품사 등의 문맥 정보를 고려하여, 성능이 좋지만 더 복잡한 처리가 필요함.

 


 

위는 Stemming과 Lemmatization의 차이를 의미합니다. 이제 어간 추출 알고리즘(Stemming) 중 하나인 포터 알고리즘(Porter Algorithm)에 아래의 Text를 입력으로 넣는다고 해봅시다.

 

from nltk.stem import PorterStemmer
from nltk.tokenize import word_tokenize

s = PorterStemmer()
text="This was not the map we found in Billy Bones's chest, but an accurate copy, complete in all things--names and heights and soundings--with the single exception of the red crosses and the written notes."
words=word_tokenize(text)
print([s.stem(w) for w in words])

# 출력
# ['thi', 'wa', 'not', 'the', 'map', 'we', 'found', 'in', 'billi', 'bone', "'s", 'chest', ',', 'but', 'an', 'accur', 'copi', ',', 'complet', 'in', 'all', 'thing', '--', 'name', 'and', 'height', 'and', 'sound', '--', 'with', 'the', 'singl', 'except', 'of', 'the', 'red', 'cross', 'and', 'the', 'written', 'note', '.']

 

위의 알고리즘의 결과에는 사전에 없는 단어들도 포함되어 있습니다. 위의 어간 추출은 단순 규칙에 기반하여 이루어지기 때문입니다. 가령, 포터 알고리즘의 어간 추출은 이러한 규칙들을 가집니다.

 

FINALIZE → FINAL
IMPORTANCE → IMPORT
TYPICALLY → TYPIC

 

from nltk.stem import PorterStemmer

s = PorterStemmer()
words=['finalize', 'importance', 'typically']
print([s.stem(w) for w in words])

# 출력
# ['final', 'import', 'typic']

 

어간 추출 속도는 표제어 추출보다 일반적으로 빠른데, 포터 어간 추출기는 정밀하게 설계되어 정확도가 높으므로 영어 자연어 처리에서 어간 추출을 하고자 한다면 가장 준수한 선택입니다. NLTK에서는 포터 알고리즘 외에도 랭커스터 스태머(Lancaster Stemmer) 알고리즘을 지원합니다. 이번에는 포터 알고리즘과 랭커스터 스태머 알고리즘으로 각각 어간 추출을 진행했을 때, 이 둘의 결과를 비교해보도록 하겠습니다.

 

from nltk.stem import PorterStemmer
from nltk.stem import LancasterStemmer

s=PorterStemmer()
l=LancasterStemmer()

words=['policy', 'doing', 'organization', 'have', 'going', 'love', 'lives', 'fly', 'dies', 'watched', 'has', 'starting']
print([s.stem(w) for w in words])
print([l.stem(w) for w in words])

# 출력
# ['polici', 'do', 'organ', 'have', 'go', 'love', 'live', 'fli', 'die', 'watch', 'ha', 'start']
# ['policy', 'doing', 'org', 'hav', 'going', 'lov', 'liv', 'fly', 'die', 'watch', 'has', 'start']

 

4. Reference

 

위키독스

온라인 책을 제작 공유하는 플랫폼 서비스

wikidocs.net

 

'미분류' 카테고리의 다른 글

Preprocessing - Ont-Hot Encoding  (0) 2020.01.08
Preprocessing - Integer Encoding  (0) 2020.01.08
Preprocessing - Stopword  (0) 2020.01.08
Preprocessing - Cleaning & Normalization  (0) 2020.01.08
Preprocessing - Tokenization  (0) 2020.01.08
파일구조란 무엇인가?  (0) 2020.01.04
확률의 정의  (0) 2020.01.03