- #감정_분류
- #나이브_베이즈
- #나이브_베이즈_기반_감정_분류
- #scikit-learn_라이브러리를_이용한_시스템_구축
- #추가
본격적인 이야기에 앞서 이곳에선 텍스트 데이터를 크게 객관적인 글과 주관적 글로 나누고자 한다
-
객관적 글: 뉴스나 사전 같은 경우로 정보 전달 등의 목적을 지닌 글
-
주관적 글: 리뷰와 같이 주관이나 감상이 들어간 글
오늘의 목표는 주관적인 글에 포함된 감정을 구분해내는 것이다
문장의 구성 및 언어적 특징을 기반으로 각 문장을 특정 감정에 분류하는 것이다.
문장 | 감정 |
---|---|
이 캐릭터가 죽은게 아쉽네요.. | 슬픔 |
와 이 명작을 다시보다니.. | 기쁨 |
이처럼 문장에 특정 감정이 담기는 경우 특정 단어나 구조가 반복되므로 이를 기반으로 감정 분류 시스템을 만들고자 한다
나이브 베이즈란
주어진 특정 텍스트가 어떠한 범주에 포함될 확률을 말한다
이를 수식으로 나타내게 되면 다음과 같다.
P(S|T)
이러한 나이브 베이츠에서 대상을 분류하는데 사용하는 특징들은 전부 독립적 이며(이번에는 문장을 구성하는 각각의 단어들로 생각할 수 있다) 문제와 답이 주어지는 지도 학습 에서 효율적으로 사용될 수 있다
다시 한번 수식을 보자. 이번엔 수식의 각각의 변수를 아래와 같이 표현할 수 있다
P(S|T)
S: 감정 T: 텍스트
즉 P(감정 | 텍스트) 이다
이를 풀어보면
P(감정 | 텍스트) = P(감정) * P(텍스트 | 감정) / P(텍스트)
이고 이를 해석해보면 아래와 같다
나타날 확률 = 나타난 빈도 라는 가정에서
P(감정): 전체 데이터셋중 이 감정이 나타날 확률 P(텍스트): 전체 데이터셋중 이 텍스트가 나타날 확률 P(텍스트 | 감정): 특정 감정으로 분류된 텍스트들 중에서 이 텍스트가 나타날 확률
따라서 정리하면 특정 감정을 나타내는 텍스트 중 대상이 나타날 확률 x 대상 감정이 나타날 확률 / 그 텍스트가 나타날 확률 이다
good라는 단어와 happy라는 단어로 예시를 들어보자면 아래와 같이 나타낼 수 있다
(happy를 나타내는 단어가 good일 확률) x (전체 데이터셋에서 happy 나타날 확률) / (good가 나타날 확률)
이제 한번 실제로 해보자
scikit-learn라이브러리는 내부적으로 나이브 베이즈 모델을 제공한다
일단 아래 명령어를 콘솔에 입력해 scikit-learn을 설치하자
( 로컬의 경우 ) pip install scikit-learn
( 코렙의 경우 ) !pip install scikit-learn
코드는 아래와 같다
# scikit-learn에서 필요한 모듈 import
from sklearn.feature_extraction.text import CountVectorizer
from sklearn.naive_bayes import MultinomialNB
# 데이터를 담을 변수 선언
doc = ['i am happy', 'what a wonderful say'] #데이터
emo = ['happy', 'excited'] # 정답
# 모듈 언선
cv= CountVectorizer()
clf = MultinomialNB()
# 텍스트 형태의 데이터에서 각 단어에 ID를 부여하고 빈도수를 계산함
doc_to_vec = cv.fit_transform(doc)
print(doc_to_vec)
clf.fit(doc_to_vec, emo) # 모델 학습
test = ["i am good"] # 테스트 데이터
test_to_vec = cv.transform(test) # 데이터 백터화
result = clf.predict(test_to_vec) # 결과 예측
print(result)
[1] >
(0, 0) 1
(0, 1) 1
(1, 3) 1
(1, 4) 1
(1, 2) 1
[2] >
['happy']
결과물을 보면 잘 나온 것을 확인할 수 있다
여기서 doc_to_vec의 출력을 보면 id가 백터로 되어있는 것을 볼 수 있다. 그러므로 문장은 2차원 배열의 형태가 되는데 이를 이용하면 CNN을 통해 예측할 수도 있다는 것을 알 수 있다.
*그러니 다음은 CNN으로도 해보자