귀퉁이 서재

NLP - 4. 어간 추출(Stemming)과 표제어 추출(Lemmatization) 본문

자연어 처리 (NLP)

NLP - 4. 어간 추출(Stemming)과 표제어 추출(Lemmatization)

Baek Kyun Shin 2020. 2. 12. 19:22

텍스트 전처리 세 번째 주제는 어간 추출(Stemming)과 표제어 추출(Lemmatization)입니다. 이전과 마찬가지로 파이썬 머신러닝 완벽 가이드 (권철민 저), 딥 러닝을 이용한 자연어 처리 입문(유원주 저)을 요약정리했습니다.

택스트 전처리의 목적은 말뭉치(Corpus)로부터 복잡성을 줄이는 것입니다. 어간 추출과 표제어 추출 역시 말뭉치의 복잡성을 줄여주는 텍스트 정규화 기법입니다.

텍스트 안에서 언어는 다양하게 변합니다. 영어를 예로 들면, 과거형, 현재 진행형, 미래형, 3인칭 단수 여부 등 많은 조건에 따라 원래 단어가 변화합니다. play를 예로 들면, plays, played, playing 등과 같이 조건에 따라 다양하게 달라집니다. 어간 추출(Stemming)과 표제어 추출(Lemmatization)은 단어의 원형을 찾는 것입니다. played, plays, playing으로부터 play를 찾는 것입니다.

어간 추출(Stemming)

어간 추출(Stemming)이란 단어로 부터 어간(Stem)을 추출하는 작업을 뜻합니다. 어간 추출은 뒤이어 설명할 표제어 추출보다 성능이 떨어집니다. 즉, 일부 철자가 훼손된 어근 단어를 추출합니다. 단어를 보고 어림짐작하여 어미를 잘라 어간을 추출하기 때문입니다. NLTK의 어간 추출 Stemmer로는 대표적으로 Porter, Lancaster, Snowball Stemmer가 있습니다. Porter Stemmer와 Lancaster Stemmer를 비교해보겠습니다.

Porter Stemmer

from nltk.stem import PorterStemmer
stemmer = PorterStemmer()

print(stemmer.stem('working'),stemmer.stem('works'),stemmer.stem('worked'))
print(stemmer.stem('amusing'),stemmer.stem('amuses'),stemmer.stem('amused'))
print(stemmer.stem('happier'),stemmer.stem('happiest'))
print(stemmer.stem('fancier'),stemmer.stem('fanciest'))
print(stemmer.stem('was'), stemmer.stem('love'))
work work work
amus amus amus
happier happiest
fancier fanciest
wa love

Lancaster Stemmer

from nltk.stem import LancasterStemmer
stemmer = LancasterStemmer()

print(stemmer.stem('working'),stemmer.stem('works'),stemmer.stem('worked'))
print(stemmer.stem('amusing'),stemmer.stem('amuses'),stemmer.stem('amused'))
print(stemmer.stem('happier'),stemmer.stem('happiest'))
print(stemmer.stem('fancier'),stemmer.stem('fanciest'))
print(stemmer.stem('was'), stemmer.stem('love'))
work work work
amus amus amus
happy happiest
fant fanciest
was lov

work는 모두 잘 추출했습니다. 하지만 amusing, amuses, amused는 amuse로 추출해야 하는데 amus로 잘못 추출한 것을 볼 수 있습니다. Porter와 Lancaster가 서로 다른 성능을 보입니다.

표제어 추출(Lemmatization)

일반적으로 어간 추출(Stemming)보다 표제어 추출(Lemmatization)이 더 정확히 어근 단어를 찾아줍니다. 품사와 같은 문법적인 요소와 더 의미적인 부분을 감안하기 때문인데, 그래서 어간 추출보다 시간이 더 오래 걸립니다.

표제어 추출은 WordNetLemmatizer를 주로 사용합니다.

from nltk.stem import WordNetLemmatizer

lemma = WordNetLemmatizer()
print(lemma.lemmatize('amusing'),lemma.lemmatize('amuses'),lemma.lemmatize('amused'))
print(lemma.lemmatize('happier'),lemma.lemmatize('happiest'))
print(lemma.lemmatize('fancier'),lemma.lemmatize('fanciest'))
print(lemma.lemmatize('was'), lemma.lemmatize('love'))
amusing amuses amused
happier happiest
fancier fanciest
wa love

영 성능이 좋지 않네요. 표제어 추출은 단어의 품사 정보를 알아야만 정확한 결과를 얻을 수 있습니다. 아래와 같이 두 번째 인자에 품사 정보를 넣어주면 정확하게 어근 단어를 추출하는 것을 볼 수 있습니다.

print(lemma.lemmatize('amusing','v'),lemma.lemmatize('amuses','v'),lemma.lemmatize('amused','v'))
print(lemma.lemmatize('happier','a'),lemma.lemmatize('happiest','a'))
print(lemma.lemmatize('fancier','a'),lemma.lemmatize('fanciest','a'))
print(lemma.lemmatize('was', 'v'), lemma.lemmatize('love', 'v'))
amuse amuse amuse
happy happy
fancy fancy
be love

완벽하죠?

References

Reference1: 파이썬 머신러닝 완벽가이드 (권철민 저)

Reference2: 딥 러닝을 활용한 자연어 처리 입문 (어간 추출과 표제어 추출)

Comments