TOP
class="layout-aside-left paging-number">
본문 바로가기
[파이썬 Projects]/<파이썬 데이터 분석>

[파이썬] 자연어 처리(NLP) 시작하기 - 7

by 기록자_Recordian 2024. 5. 13.
728x90
반응형
시작에 앞서
해당 내용은 <파이썬으로 데이터 주무르기> -민형기 저, BJPUBLIC 출판사 의 내용을 토대로 작성되었습니다.
보다 자세한 내용은 해당 교재를 확인하여 주시기 바랍니다.

지난 챕터
 

[파이썬] 자연어 처리(NLP) 시작하기 - 6

시작에 앞서해당 내용은 -민형기 저, BJPUBLIC 출판사 의 내용을 토대로 작성되었습니다.보다 자세한 내용은 해당 교재를 확인하여 주시기 바랍니다.지난 챕터 [파이썬] 자연어 처리(NLP) 시작하기

puppy-foot-it.tistory.com


Naive Bayes Classifier의 이해 - 한글

 
한글에서는 형태소 분석을 해야 한다.
우선, 형태소 분석 이전에 okt(구 twitter) 모듈을 import 하고 기본 세팅을 해준다.
Okt 클래스는 한글 형태소 분석기로, 문장을 형태소 단위로 분석하여 명사, 동사, 형용사 등의 품사를 태깅할 수 있다.
이를 통해 한글 텍스트 데이터를 자연어 처리하기 위해 사용된다.

from konlpy.tag import okt #구 twitter

 
위의 코드를 사용하여 Okt 클래스를 불러올 때, 오류가 발생하는 경우가 있다. 이 때, konlpy 라이브러리의 구 버전에서는 Okt 클래스 대신에 Twitter 클래스를 사용하면 오류가 해결될 수 있다.

Twitter import

#한국어 형태소 분석기인 Twitter를 사용하여 형태소 분석기 객체를 생성
pos_tagger = Twitter()

한글 문장 생성
train = [('메리가 좋아', 'pos'),
         ('고양이도 좋아', 'pos'),
         ('난 수업이 지루해', 'neg'),
         ('메리는 예쁜 고양이야', 'pos'),
         ('난 마치고 메리랑 놀거야', 'pos'),]

 
생성된 문장을 가지고 말뭉치 생성

all_words = set(word.lower() for sentence in train 
                for word in word_tokenize(sentence[0])) 
all_words

말뭉치 생성
고양이도, 고양이가, 메리가, 메리는 이 다른 단어로 잡혀있다.

 
이런 경우, 단어 분류가 제대로 되어 있지 않기 때문에 분류기의 제대로된 동작을 장담하기 어렵다.

t = [({word: (word in word_tokenize(x[0])) for word in all_words}, x[1])
     for x in train]
t

튜플 목록 생성
튜플 목록을 생성

classifier = nltk.NaiveBayesClassifier.train(t)
classifier.show_most_informative_features()

분류기 훈련하고 가장 정보를 많이 제공하는 특성 표시

 
테스트 문장을 생성하고

 
해당 단어가 문장에 포함되어 있는지 여부를 확인하여 특징을 생성하고

test_sent_features = {word.lower():
                          (word in word_tokenize(test_sentence.lower()))
                          for word in all_words}
test_sent_features

 
분류기로 분류해보면

classifier.classify(test_sent_features)

한글 분류기
테스트 문장이 '부정'으로 나온다

 
이렇기 때문에, 한글을 다룰 때는 형태소 분석이 필요하다.


tokenize 함수를 사용하여 train 문장 분석하기

 
먼저 tokenize 함수를 사용하여 train 문장을 분석한 뒤, 정규화를 수행하고 각 단어에서 어간을 추출한다.

# tokenize 함수를 사용하여 train 문장 분석
def tokenize(doc):
    return ['/'.join(t) for t in pos_tagger.pos(doc, norm=True, stem=True)]
#'/'.join(t) for t in ...: 형태소 분석 결과인 튜플들을 슬래시('/')로 구분된 문자열 형태로 변환
# norm=True로 설정하여 정규화(normalization)를 수행하고
# stem=True로 설정하여 각 단어에서 어간(stem)을 추출

 
그리고나서 문장의 형태소를 분석하여 형태소 단위로 분리하고
분리된 형태소와 레이블을 쌍으로 묶어 리스트에 저장한다.

# tokenize 함수를 사용
# row[0]의 텍스트를 형태소 분석하여 단어들을 형태소 단위로 분리
# 분리된 형태소들과 해당 텍스트의 레이블인 row[1]을 쌍으로 묶어 리스트에 저장
# row[1]은 해당 텍스트의 레이블(예: 긍정 또는 부정)을 나타냄
train_docs = [(tokenize(row[0]), row[1]) for row in train]
train_docs

단어와 형태소 쌍

 
그리고 다시 전체 말뭉치를 만들고

tokens = [t for d in train_docs for t in d[0]] #모든 문서에서 추출된 형태소들을 tokens 리스트에 저장
tokens

말뭉치 생성

말뭉치에 있는 단어가 있는지 없는지를 구분하는 함수를 만들어서 train 문장에 적용

def term_exists(doc):
    return {word: (word in set(doc)) for word in tokens}
# 각 문서에 대해 term_exists 함수를 적용하여 문서를 단어 존재 여부로 표현한 뒤,
# 해당 문서의 클래스(c)와 함께 train_xy 리스트에 저장
train_xy = [(term_exists(d), c) for d,c in train_docs]
train_xy

train_xy 리스트 생성

 
이제 분류기를 동작시키고

나이브 베이즈 분류기 동작

 
형태소 분석 이전에 부정되었던 문장을 다시 테스트 해보면

# 테스트 문장 생성
test_sentence = [("난 수업이 마치면 메리랑 놀거야")]
# 테스트 문장 형태소 분석
test_docs = pos_tagger.pos(test_sentence[0])
test_docs

테스트 문장 생성하여 형태소 분석하기

 
테스트 문장에 대한 단어 특징을 생성하고

test_sent_features = {word: (word in tokens) for word in test_docs}
test_sent_features

 
결과를 보면

단어 분류기 결과

긍정(pos)으로 잘 나온다.


다음글

[파이썬] 자연어 처리(NLP) 시작하기 - 8

728x90
반응형