일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- GenerativeAI
- 코드업파이썬
- 데이터분석
- 생성형AI
- 자연어처리
- 구글퀵랩
- 클라우드
- Blazor
- nlp
- Python
- 파이썬기초
- 블레이저
- 파이썬
- 파이썬알고리즘
- 머신러닝
- DataScience
- Microsoft
- C#
- GenAI
- 코드업100제
- 코드업
- 빅데이터
- attention
- gcp
- 파이썬기초100제
- 데이터사이언스
- Azure
- 한빛미디어
- codeup
- 알고리즘
- Today
- Total
Tech for good
텍스트 전처리(Text preprocessing) - 표제어 추출(Lemmatization) & 어간 추출(Stemming) 본문
텍스트 전처리(Text preprocessing) - 표제어 추출(Lemmatization) & 어간 추출(Stemming)
Diana Kang 2021. 9. 28. 09:43
* 위의 책을 참고하여 작성된 글입니다.
목차
1. 표제어 추출(Lemmatization)
2. 어간 추출(Stemming)
3. 표제어 추출(Lemmatization)과 어간 추출(Stemming) 비교
정규화 기법 중 코퍼스에 있는 단어의 개수를 줄일 수 있는 기법으로 표제어 추출(lemmatization)과 어간 추출(stemming)이 있다. 이 두 작업은 서로 다른 단어들을 하나의 단어로 일반화시켜 문서 내의 단어 수를 줄이겠다는 것에 의의가 있다. 주로 단어의 빈도수를 기반으로 문제를 풀고자 하는 BoW(Bag of Words) 표현을 사용하는 자연어 처리 문제에서 주로 사용되며, 이러한 정규화 기법을 통해 코퍼스로부터의 복잡성을 줄일 수 있다.
1. 표제어 추출(Lemmatization)
표제어 추출은 단어들로부터 표제어를 찾아가는 과정이다.
예시) am, are, is의 표제어는 be이다.
표제어 추출을 하는 가장 섬세한 방법은 단어의 형태학적 파싱을 먼저 진행하는 것이다. 형태소란 '의미를 가진 가장 작은 단위'를 뜻한다. 그리고 형태학(morphology)이란 형태소로부터 단어들을 만들어가는 학문을 뜻한다.
형태소는 두 가지 종류가 있다.
① 어간(stem)
: 단어의 의미를 담고 있는 단어의 핵심 부분
② 접사(affix)
: 단어에 추가적인 의미를 주는 부분
형태학적 파싱은 이 두 가지 구성 요소를 분리하는 작업을 말한다. 가령 cats라는 단어에 대해 형태학적 파싱을 수행한다면, 결과는 cat(어간)와 -s(접사)로 분리된다.
자연어처리 도구인 NLTK에서는 표제어 추출을 위한 도구인 WordNetLemmatizer을 지원한다.
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']
결과를 살펴보면 표제어 추출의 경우, 단어의 형태가 적절히 보존되는 양상을 보인다. 하지만 그럼에도 위의 결과에서는 dy나 ha와 같이 의미를 알 수 없는 적절치 못한 단어를 출력하고 있다. 이는 표제어 추출기(lemmatizer)가 본래 단어의 품사 정보를 알아야만 정확한 결과를 얻을 수 있기 때문이다.
WordNetLemmatizer을 활용하여 입력으로 단어의 품사를 알려주면, 품사의 정보를 보존하며 정확한 Lemma(단어의 기본형)를 출력한다.
n.lemmatize('dies', 'v')
'die'
n.lemmatize('watched', 'v')
'watch'
n.lemmatize('has', 'v')
'have'
표제어 추출에 대해 다시 한 번 정리해보자면, 표제어 추출은 문맥을 고려하며 품사 정보를 보존한다.
(즉, POS 태그를 보존한다고도 말할 수 있다.)
2. 어간 추출(Stemming)
어간(Stem)을 추출하는 작업을 어간 추출(stemming)이라고 한다. 어간 추출은 형태학적 분석을 단순화한 버전이라고 볼 수도 있고, 정해진 규칙만 보고 단어의 어미를 자르는 어림짐작의 작업이라고 볼 수도 있다. 즉, 어간 추출 후에 나오는 결과 단어는 사전에 존재하지 않는 단어일 수도 있다.
다음으로 어간 추출 알고리즘 중 하나인 포터 알고리즘(Porter Algorithm)을 살펴보자.
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(words)
['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', '.']
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', '.']
결과를 살펴보면 사전에 없는 단어들도 포함되어 있다. 어간 추출이 단순 규칙에 기반하여 이루어지기 때문이다.
가령, 포터 알고리즘의 어간 추출은 이러한 규칙들을 가진다.
ALIZE → AL
ANCE → 제거
ICAL → IC
words=['formalize', 'allowance', 'electricical']
print([s.stem(w) for w in words])
['formal', 'allow', 'electric']
위의 규칙에 따라서 다음과 같은 결과가 나오는 것이다.
formalize → formal
allowance → allow
electricical → electric
어간 추출 속도는 표제어 추출보다 일반적으로 빠른데, 포터 어간 추출기는 정밀하게 설계되어 정확도가 높으므로 영어 자연어 처리에서 어간 추출을 하고자 한다면 가장 준수한 선택이다. NLTK에서는 포터 알고리즘 외에도 랭커스터 스태머(Lancaster Stemmer)알고리즘을 지원한다. 그럼 이제 포터 알고리즘과 랭커스터 스태머 알고리즘으로 각각 어간 추출을 진행했을 때의 결과를 비교해보도록 하자.
# 포터 알고리즘
from nltk.stem import PorterStemmer
s=PorterStemmer()
words=['policy', 'doing', 'organization', 'have', 'going', 'love', 'lives', 'fly', 'dies', 'watched', 'has', 'starting']
print([s.stem(w) for w in words])
['polici', 'do', 'organ', 'have', 'go', 'love', 'live', 'fli', 'die', 'watch', 'ha', 'start']
# 랭커스터 스태머 알고리즘
from nltk.stem import LancasterStemmer
l=LancasterStemmer()
words=['policy', 'doing', 'organization', 'have', 'going', 'love', 'lives', 'fly', 'dies', 'watched', 'has', 'starting']
print([l.stem(w) for w in words])
['policy', 'doing', 'org', 'hav', 'going', 'lov', 'liv', 'fly', 'die', 'watch', 'has', 'start']
동일한 단어들의 나열에 대해 두 스태머는 전혀 다른 결과를 보여준다. 그렇기 때문에 이미 알려진 알고리즘을 사용할 때는, 사용하고자 하는 코퍼스에 스태머를 적용해보고 어떤 스태머가 해당 코퍼스에 적합한지를 판단한 후 사용해야 한다.
이런 규칙에 기반한 알고리즘은 종종 일반화가 지나치게 되거나 덜 되거나 하는 경우가 있다. 예를 들어 포터 알고리즘에서 organization을 어간 추출하면, 결과는 아래와 같다.
organization → organ
organization과 organ이 완전히 다른 단어 임에도 organization에 대해 어간 추출을 했더니 organ이라는 단어가 나왔다. organ에 대해서 어간 추출을 한다고 하더라도 결과는 역시 organ이 되기 때문에, 두 단어에 대해서 어간 추출을 한다면 동일한 어간을 갖게 된다. 이는 어간 추출의 목적에는 맞지 않다.
3. 표제어 추출(Lemmatization)과 어간추출(Stemming) 비교
Lemmatization
am → be
the going → the going
having → have
Stemming
am → am
the going → the go
having → hav
'IT > Data Science' 카테고리의 다른 글
[빅데이터를 지탱하는 기술] 1. 빅데이터의 기초 지식 - 빅데이터 시대의 데이터 분석 기반 (0) | 2021.10.02 |
---|---|
[빅데이터를 지탱하는 기술] 1. 빅데이터의 기초 지식 - 빅데이터의 정착 (0) | 2021.10.01 |
<데이터 쓰기의 기술>, 차현나 (0) | 2021.08.27 |
[처음 배우는 딥러닝 챗봇] Ch8. 챗봇 엔진 만들기 (0) | 2021.07.15 |
[T아카데미] 딥러닝을 활용한 자연어 처리 기술 실습 1강 (0) | 2021.06.02 |