표제어 추출(Lemmatization)

애늙은이·2023년 8월 13일
0

NLP 여행기

목록 보기
6/13
post-thumbnail
post-custom-banner

🤔 표제어 추출이란?

표제어 추출(Lemmatization)은 어간 추출과 같이 텍스트 정규화에 사용되는 방법입니다. 어간 추출이 규칙을 기반으로 접사들을 잘라냈다고 하면, 표제어 추출은 사전을 이용하여 단어의 원형을 찾는 작업이라 볼 수 있습니다.

NLTK에서는 WordNetLemmatizer를 통해 표제어 추출을 진행할 수 있습니다.

import nltk
from nltk.stem import WordNetLemmatizer

nltk.download('wordnet') # 표제어 추출에 사용할 사전을 다운받습니다.

lemmatizer = WordNetLemmatizer()

print(lemmatizer.lemmatize("lives")) 


# 결과
# life

💡 표제어 추출의 특징

표제어 추출은 어간 추출과 달리 사전에서 검색하여 표제어를 반환합니다. 때문에 규칙 기반의 어간 추출보다 속도가 더 느립니다.
하지만, 'studi'같은 온전하지 않은 단어를 반환하는 어간 추출과 달리 사전을 기반으로 하기 때문에 비교적 온전한 형태의 단어를 반환해줍니다.

⚠ 표제어 추출의 한계

표제어 추출 역시 어간 추출과 마찬가지로 단어의 형태가 적절치 못하거나 단어의 원형을 얻지 못하는 경우가 생기기도 합니다.

from nltk.stem import WordNetLemmatizer

lemmatizer = WordNetLemmatizer()

print(lemmatizer.lemmatize("dies")) # 결과: dy
print(lemmatizer.lemmatize("went")) # 결과: went

때문에, 표제어 추출을 진행할 때는 단어와 단어의 품사를 같이 입력하여 정확한 표제어를 얻습니다.

from nltk.stem import WordNetLemmatizer

lemmatizer = WordNetLemmatizer() 

# lemmatize 메소드에서 품사의 기본값은 'n', 명사로 되어 있습니다.
print(lemmatizer.lemmatize("dies", 'v')) # 결과: die
print(lemmatizer.lemmatize("went", 'v')) # 결과: go

🔥 표제어 추출의 활용

표제어 추출은 형태소에 품사를 지정해주는 품사 태깅과 함께 사용할 수 있습니다.

from nltk.tokenize import word_tokenize
from nltk.tag import pos_tag
from nltk.stem import WordNetLemmatizer

txt = "We cannot direct the wind but we can adjust the sails."

tokens = word_tokenize(txt)
tags = pos_tag(tokens)
lemmatizer = WordNetLemmatizer()

result = []
for token, tag in tags:
	lemma = lemmatizer.lemmatize(token, pos=tag)
    result.append(lemma)
    
print(result)


# 결과
# KeyError: 'PRP'

하지만 품사 태깅의 결과를 그대로 표제어 추출에 인자로 넘겨주면 오류가 발생하게 됩니다. 이는 WordNetLemmatizer의 품사 태그가 pos_tag에서 사용하는 태그보다 적기 때문에 품사 태그를 인지하지 못하는 오류가 발생하게 되는 것입니다.

WordNetLemmatizerlemmatize 메소드에서 사용하는 품사 태그는 다음과 같습니다.

품사 태그설명
nnoun
vverb
aadjective
radverb
sadjective satellite

때문에 pos_tag의 품사 태그를 WordNetLemmatizer 내에서 유효한 품사 태그로 변환해줄 필요가 있습니다.

for token, tag in tags:
	if tag.startswith('N'):
    	lemma = lemmatizer.lemmatize(token, pos='n') 
	elif tag.startswith('V'):
    	lemma = lemmatizer.lemmatize(token, pos='v')
    elif tag.startswith('J'):
    	lemma = lemmatizer.lemmatize(token, pos='a')
   	elif tag.startswith('R'):
    	lemma = lemmatizer.lemmatize(token, pos='r')
   	else:
    	lemma = lemmatizer.lemmatize(token)
   	
    result.append(lemma)
profile
글쓰는 개발자입니다.
post-custom-banner

0개의 댓글