목차
텍스트 분류란?
- 텍스트를 카테고리별로 분류하는 것을 말한다.
- 텍스트 분류의 예시로는 스팸 분류, 감정 분류, 의도 분류 등이 있다.
텍스트 분류 방법
- 지도 학습을 통한 텍스트 분류 모델 : 나이브 베이즈 분류, SVM, 신경망, 선형 분류 등
- 비지도 학습을 통한 텍스트 분류 모델 : K-평균 군집화, 계층적 군집화
나이브 베이즈(Naive Bayse) 분류란?
- 나이브 베이즈 분류는 베이즈 정리를 기본으로 하는 분류 기법
- 스팸 필터, 감정 분석, 추천 시스템 등에 활용된다.
- 학습을 많이 시킬수록 분류 능력이 향상된다.
- 나이브(naive)라는 단어가 붙는 이유는 데이터셋의 모든 특징들이 동등하고 독립하다고 가정하기 때문이다.
베이즈 정리
- P(A) : A가 일어날 확률 (사전 확률)
- P(B) : B가 일어날 확률
- P(A|B) : B가 일어난 후 A가 일어날 확률 (사후 확률)
- P(B|A) : A가 일어난 후 B가 일어날 확률
- 사전 확률 : 현재 가지고 있는 정보를 기초로하여 정한 초기확률 또는 확률 시행 전에 이미 가지고 있는 지식을 통해 부여한 확률
- 사후 확률 : 사건 발생 후에 어떤 원인으로부터 일어난 것이라고 생각되어지는 확률 또는 추가된 정보로부터 사전정보를 새롭게 수정한 확률
[실습 1 - 베이지안 필터 구현]
import math,sys
from konlpy.tag import Okt
class BayesianFilter:
def __init__(self):
self.words=set() #출현한 단어 기록, set() : 공집합 생성
self.word_dict={} #카테고리마다의 출현 횟수 기록
self.category_dict={} #카테고리 출현 횟수 기록
#형태소 분석
def split(self, text):
results=[]
okt=Okt()
#단어의 기본형 사용
malist=okt.pos(text, norm=True, stem=True)
for word in malist:
#어미/조사/구두점 제외
if not word[1] in ["Josa", "Eomi", "Punctuation"]:
results.append(word[0])
return results
#단어와 카테고리의 출현 횟수 세기
def inc_word(self, word, category):
#단어를 카테고리에 추가
if not category in self.word_dict: #해당 카테고리가 word_dict에 없는 경우
self.word_dict[category]={} #카테고리 생성(딕셔너리)
if not word in self.word_dict[category]: #단어가 해당 카테고리에 없으면
self.word_dict[category][word]=0 #해당 카테고리에 단어 추가
self.word_dict[category][word]+=1 #단어가 나왔으면 횟수 추가
self.words.add(word) #출현한 단어를 words 집합에 추가
def inc_category(self, category):
#카테고리 계산하기
if not category in self.category_dict: #카테고리가 category_dict에 없는 경우
self.category_dict[category]=0 #카테고리 생성
self.category_dict[category]+=1 #횟수 count
#텍스트 학습
def fit(self, text, category):
word_list=self.split(text) #텍스트 형태소 분석
for word in word_list:
self.inc_word(word, category) #단어 출현횟수 count
self.inc_category(category) #카테고리 출현횟수 count
#단어 리스트에 점수 매기기
def score(self, words, category):
score=math.log(self.category_prob(category))
for word in words:
score=+math.log(self.word_prob(word, category))
return score
#예측하기
def predict(self, text):
best_category=None
max_score=-sys.maxsize
words=self.split(text)
score_list=[]
for category in self.category_dict.keys(): #카테고리 별로 점수 매겨서 score_list에 추가
score=self.score(words, category)
score_list.append((category,score))
if score>max_score:
max_score=score
best_category=category
return best_category, score_list
#카테고리 내부의 단어 출현 횟수 구하기
def get_word_count(self, word, category):
if word in self.word_dict[category]: #단어가 카테고리에 존재하면
return self.word_dict[category][word] #해당 단어의 출현횟수 return
else:
return 0
#카테고리 계산
def category_prob(self, category):
sum_categories=sum(self.category_dict.values()) #모든 카테고리 출현 횟수의 합
category_v=self.category_dict[category] #계산하고 싶은 카테고리의 출현 횟수를 category_v에 저장
return category_v / sum_categories #해당 카테고리의 출현 확률을 return
#카테고리 내부의 단어 출현 비율 계산
def word_prob(self, word, category):
n=self.get_word_count(word, category)+1 #단어 출현 횟수
d=sum(self.word_dict[category].values())+len(self.words) #카테고리의 출현 회수 + 출현한 단어들의 수(중복없음)
return n/d
- BayesianFilter 클래스를 만들어 베이지안 필터를 구현했다.
- split() : 형태소 분석 함수
- inc_word() : 단어가 카테고리에 없으면 추가하고, 단어를 집합에 추가하고, 단어 횟수를 세는 함수
- inc_category() : 카테고리가 없으면 생성하고 카테고리 출현 횟수 세는 함수
- fit() : 텍스트를 학습하는 함수
- score() : 단어 리스트에 점수를 매기는 함수
- predict() : 카테고리 별 점수를 바탕으로 분류 카테고리를 예측하는 함수
- get_word_count : 단어의 출현횟수 세는 함수
- category_prob / word_prob : 카테고리/단어의 출현 확률을 구하는 함수
[실습 2 - 구현한 베이즈 필터를 사용해 스팸 분류 테스트]
from bayes import BayesianFilter
bf=BayesianFilter()
#텍스트 학습
bf.fit("파격 세일 - 오늘까지만 30% 할인", "광고")
bf.fit("쿠폰 선물 & 무료 배송", "광고")
bf.fit("현데계 백화점 세일", "광고")
bf.fit("봄과 함께 찾아온 따뜻한 신제품 소식", "광고")
bf.fit("인기 제품 기간 한정 세일", "광고")
bf.fit("오늘 일정 확인", "중요")
bf.fit("프로젝트 진행 상황 보고", "중요")
bf.fit("계약 잘 부탁드립니다", "중요")
bf.fit("회의 일정이 등록되었습니다.", "중요")
bf.fit("오늘 일정이 없습니다.", "중요")
#예측
pre, scorelist=bf.predict("재고 정리 할인, 무료 배송")
print("결과 = ", pre)
print(scorelist)
결과를 보면 해당 텍스트는 광고로 분류되었다.
출현한 단어 리스트를 보면 다음과 같다. (bf.words로 볼 수 있음)
참고 자료
실습 : 파이썬을 이용한 머신러닝, 딥러닝 실전 개발 입문_ 쿠지라 히코우즈쿠에 저
https://zzaebok.github.io/machine_learning/bayesian-statistics-and-machine-learning/
https://gomguard.tistory.com/6
'Study > 머신러닝' 카테고리의 다른 글
[5] 문장의 유사도 분석하기 - 레벤슈타인 거리, N-gram (1) | 2020.08.06 |
---|---|
[4] MLP(Multi Layer Perceptron)로 텍스트 분류하기 (0) | 2020.07.30 |
[2-2] Word2Vec을 활용해 문장을 벡터로 변환하기 (0) | 2020.07.17 |
[2-1] KoNLPy 사용해서 한국어 형태소 분석하기(자연어 처리) (0) | 2020.07.16 |
[1-2] 서포트 벡터 머신(Support Vector Machine) (0) | 2020.07.10 |