어간 추출과 표제어 추출이 모두 필요한 경우, 일반적으로는 어간 추출을 우선 수행한 후, 그 결과물에 대해 표제어 추출을 적용한다. 이러한 절차를 "어간 추출 후 표제어 추출" 또는 "Stemming and Lemmatization"이라고 한다.
예를 들어, "loving"이라는 단어가 있을 때, 어간 추출을 수행하면 "lov"가 추출된다. 이후, 추출된 "lov"에 대해 표제어 추출을 수행하면 "love"가 추출된다.
Python에서는 NLTK 라이브러리를 활용하여 어간 추출과 표제어 추출을 모두 수행할 수 있다. Porter Stemming을 이용하여 어간 추출을 수행하고, WordNet Lemmatization을 이용하여 표제어 추출을 수행한다.
from nltk.stem import PorterStemmer, WordNetLemmatizer
from nltk.corpus import wordnet
import nltk
nltk.download('wordnet')
# 어간 추출 (Porter Stemming)
stemmer = PorterStemmer()
stemmed_words = [stemmer.stem(word) for word in words]
# 표제어 추출 (WordNet Lemmatization)
lemmatizer = WordNetLemmatizer()
lemmatized_words = []
for word in words:
pos = wordnet.synsets(word)
if pos:
pos = pos[0].pos()
if pos.startswith('a'):
pos = 'a' # 형용사
elif pos.startswith('v'):
pos = 'v' # 동사
elif pos.startswith('n'):
pos = 'n' # 명사
elif pos.startswith('r'):
pos = 'r' # 부사
else:
pos = None
if pos:
lemma = lemmatizer.lemmatize(word, pos=pos)
lemmatized_words.append(lemma)
else:
lemmatized_words.append(word)
먼저, NLTK에서 제공하는 어간 추출과 표제어 추출을 위한 PorterStemmer와 WordNetLemmatizer 클래스를 import 한다. 또한 단어의 품사를 확인하기 위해 WordNetLemmatizer에 필요한 wordnet 코퍼스를 다운로드 받는다.
PorterStemmer 클래스는 Porter Stemming 알고리즘을 적용하여 단어의 어간을 추출한다.
위 코드에서는 PorterStemmer 객체를 생성하고,
리스트 내포(list comprehension)를 이용하여 words 리스트에 포함된 각각의 단어(word)에 대해 stemmer.stem(word)를 적용하여 어간을 추출하고,
그 결과를 stemmed_words 리스트에 저장한다.
WordNetLemmatizer 클래스는 WordNet 라이브러리를 이용하여 단어의 표제어를 추출한다.
WordNetLemmatizer 객체를 생성하고, words 리스트에 포함된 각각의 단어(word)에 대해 표제어를 추출하고, 그 결과를 lemmatized_words 리스트에 저장한다.
표제어 추출을 위해서는 단어의 품사(part of speech)를 먼저 확인해야 한다.
wordnet.synsets(word) 함수를 이용하여 단어가 어떤 품사인지 확인한 후, pos 변수에 저장한다.
pos 변수에는 WordNet에서 사용하는 품사 태그가 저장된다.
해당 단어가 형용사, 동사, 명사, 부사 중 어떤 품사인지를 확인하고, 해당 품사 태그를 pos에 저장한다.
다음으로는 WordNetLemmatizer 클래스의 lemmatize() 함수를 이용하여 단어의 표제어를 추출한다. 이때, pos 파라미터에 앞서 확인한 품사 태그를 지정하여 올바른 품사로 표제어를 추출할 수 있도록 한다.
만약, wordnet.synsets(word) 함수를 이용하여 해당 단어의 품사를 확인할 수 없는 경우, lemmatized_words 리스트에 해당 단어를 그대로 추가한다.
# 어간 추출과 표제어 추출 결과 출력
print("Stemmed words:", " ".join(stemmed_words))
print("Lemmatized words:", " ".join(lemmatized_words))
마지막으로, 어간 추출과 표제어 추출 결과를 출력한다. join() 함수를 이용하여 리스트에 저장된 결과를 공백으로 구분하여 출력한다.
Stemmed words: i am love it
Lemmatized words: i be love it
어간 추출의 결과는 단어의 어간만을 추출한 것이고, 표제어 추출의 결과는 단어의 품사에 따라 적절한 형태로 단어를 변환한 결과이다.
import nltk
from nltk.stem import PorterStemmer, WordNetLemmatizer
from nltk.tokenize import word_tokenize
# 예시 문장
sentence = "The quick brown foxes jumped over the lazy dogs."
# 어간 추출
ps = PorterStemmer()
stemmed_words = [ps.stem(w) for w in word_tokenize(sentence)]
print("Stemmed words:", stemmed_words)
# 표제어 추출
lemmatizer = WordNetLemmatizer()
lemmatized_words = [lemmatizer.lemmatize(w) for w in word_tokenize(sentence)]
print("Lemmatized words:", lemmatized_words)
'자연어 처리(NLP) 공부' 카테고리의 다른 글
자연어 처리(NLP) - 품사 태깅(Tagging) (0) | 2023.03.17 |
---|---|
자연어 처리(NLP) - 정규 표현식(Regular Expression) 모듈 re (0) | 2023.03.17 |
자연어 처리(NLP) - 어간 추출(Stemming), 표제어 추출(Lemmatization) (2) | 2023.03.16 |
자연어 처리(NLP) - 정수 인코딩(Integer Encoding) (0) | 2023.03.15 |
자연어 처리(NLP) - 불용어(stopwords) 제거 (0) | 2023.03.15 |