일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
- type-hint
- word2vec
- 의미연결망
- 허깅페이스
- dynamic topic modeling
- sensibleness
- 사회연결망분석
- QANet
- degree centrality
- 구글클라우드플랫폼
- 머신러닝
- hugging face
- 알파베타가지치기
- 토픽모델링
- 동적토픽모델링
- Google Cloud Platform
- Holdout
- 임베딩
- ROC-AUC Curve
- word representation
- sbert
- 분류모델평가
- semantic network
- GCP
- Min-Max 알고리즘
- Enriching Word Vectors with Subword Information
- topic modeling
- 감성분석
- sequential data
- Meena
- Today
- Total
Dev.log
나이브 베이즈 분류기(Naive Bayes Classifier) 본문
이번 포스팅에서는 나이브 베이즈(Naive Bayse)에 대해 진행해 보도록 하겠습니다. 먼저 나이브 베이즈에 들어가기 앞서 나이브 베이즈의 사전 지식인 조건부 확률과 베이즈 정리에 대해 간단히 짚고 넘어가겠습니다.
조건부확률 (Conditional Probability)와 베이즈 정리(Bayes' theorem)
사건 B가 발생했을 떄 사건 A가 발생할 확률은 사건 B의 영향을 받아 변화할 수 있습니다. 조건부 확률은 P(B) > 0 의 조건을 만족하면서, 어떠한 사건 B가 일어났을때 사건 A가 일어날 확률을 의미합니다. 즉, 주어진 사건이 일어났다는 가정하에 다른 한 사건이 일어나는 확률을 의미합니다.
예를 들어, 우리가 주사위를 던질 때 각 숫자가 나올확률은 1/6으로 생각합니다. 만약 여기서, 주사위를 던지고나서 나오는 숫자가 홀수(odd)라는 추가적인 정보가 주어졌다고 합시다. 이런 정보는 주사위의 표본공간 {1,2,3,4,5,6}에서 {1,3,5}로 줄여버렸기 떄문에 우리가 1이 나올 확률을 계산할 때 영향을 끼칩니다. 이러한 예시를 조건부확률의 수식에 대입해보면 다음과 같습니다. A가 주사위를 굴렸을때 1이 나오는 사건이고, B가 주사위를 굴렸을 때 홀수가 나오는 사건이면 P(A∩B)는 1/6이고, P(B)는 3/6이 됩니다. 즉 주사위의 숫자가 홀수가 나왔을때 1이나오는 사건은 P(A|B) = (1/6) / (3/6) = 1/3으로 나타낼수 있습니다. 베이즈 정리는 조건부확률을 구하는 공식으로서 다음과 같이 정의할 수 있습니다.
P(A)는 사전확률(posteriror)이라고 하며 사건 B가 발생하기 전에 가지고 있던 사건 A의 확률입니다. 만약 사건 B가 발생하면 이 정보를 반영해서 사건 A의 확률은 P(A|B)가 되며, 이는 사후확률이라고 합니다. 시후확률은 사전확률에 P(B|A)/P(B)를 곱해주면 얻을수 있는데, 여기서 P(B|A)는 likelihood라고 하며 사건 A가 발생한 경우 사건 B의 확률을 의미합니다. 또한 P(B)는 normalizing constant라고 하며 확률의 크기 조정을 의미합니다. 베이즈 정리는 사건 B가 발생함으로써 사건 A의 확률이 어떻게 변화하는지 표현하였습니다. 즉 새로운 정보가 기존의 추론에 어떠한 영향을 미치는지 나타냅니다.
나이브 베이즈(Naive Bayes)
나이브 베이즈는 베이즈 정리를 통해 데이터가 각 클래스에 속할 확률을 계산하는 방법으로써, 텍스트 classification, 추천시스템 또는 감성분석에까지 주로 활용됩니다. 즉 사건 B가 주어졌을때 사건 A가 일어날 확률인 P(A|B), 조건부 확률을 이용한 classfication 기법이라고 할 수 있습니다. 이제 나이브 베이즈를 통해 어떠한 인풋이 주어졌을때 해당 인풋이 정상적인것인지 비정상적인것인지 구분해보겠습니다.
- P(정상 | 인풋) = 인풋이 있을 때 정상일 확률
- P(비정상 | 인풋) = 인풋이 있을 떄 비정상일 확률
이를 베이즈정리를 통해 표현하면 다음과 같이 나타납니다.
- P(정상 | 인풋) = (P(인풋 | 정상 ) × P(정상 )) / P(인풋)
- P(비정상 | 인풋) = (P(인풋 | 비정상) × P(비정상)) / P(인풋)
인풋이 주어졌을 때, P(정상| 인풋)이 P(비정상 | 인풋)보다 크다면 정상적인 인풋이라고 볼 수 있으며, 그 반대라면 비정상적인 인풋이라고 볼 수 있습니다. 이제 sklearn에서 제공하는 fetch_20newsgroups의 20개의 주제를 가진 18,846개의 뉴스데이터를통해 나이브 베이즈 분류기(Naive Bayes classifer)를 통해 데이터를 분류해 보겠습니다. 먼저 분류를위한 패키지를 다운받아보도록 하겠습니다.
import pandas as pd
import re
from sklearn.feature_extraction.text import CountVectorizer
from sklearn.feature_extraction.text import TfidfTransformer
from sklearn.naive_bayes import MultinomialNB
from sklearn.metrics import accuracy_score
from sklearn.datasets import fetch_20newsgroups
이후 fetch_20newsgroups의 데이터셋을 간단하게 전처리 하는 과정을 거치겠습니다.
news_df = pd.DataFrame({'News' : newsdata.data, 'Target' : newsdata.target})
def data_cleansing(df):
delete_email = re.sub(r'\b[\w\+]+@[\w]+.[\w]+.[\w]+.[\w]+\b', ' ', df)
delete_number = re.sub(r'\b|\d+|\b', ' ',delete_email)
delete_non_word = re.sub(r'\b[\W]+\b', ' ', delete_number)
cleaning_result = ' '.join(delete_non_word.split())
return cleaning_result
def preprocessing(dataframe):
dataframe.News = dataframe.News.str.replace("[^a-zA-Z]", " ")
dataframe.News = dataframe.News.apply(lambda x: ' '.join([w for w in x.split() if len(w)>3]))
dataframe.News = dataframe.News.apply(lambda x: x.lower())
return dataframe
news_df['News'] = news_df['News'].apply(data_cleansing)
news_df = preprocessing(news_df)
이후 NLTK의 stopwords를 통해 불필요한 단어들에 대해 처리를 시켜줍니다.
from nltk.corpus import stopwords
import nltk
stop_words = stopwords.words('english')
stop_words = set(stop_words)
news_df['News'] = news_df['News'].apply(lambda x: ' '.join([word for word in x.split() if word not in (stop_words)]))
간단하게 분류기 모델 생성을 위해서 임베딩 방법이 아닌 인코딩 방법 중 하나인 TF-IDF를 통해 단어를 벡터화 시켜줍니다.
dtmvector = CountVectorizer()
X_train_dtm = dtmvector.fit_transform(news_df.News)
tfidf_transformer = TfidfTransformer()
tfidfv = tfidf_transformer.fit_transform(X_train_dtm)
이후, 모델을 생성해주고 테스트 데이터에 대해 예측을 해봅니다.
newsdata_test = fetch_20newsgroups(subset='test', shuffle=True)
X_test_dtm = dtmvector.transform(newsdata_test.data)
tfidfv_test = tfidf_transformer.transform(X_test_dtm)
predicted = mod.predict(tfidfv_test)
print("정확도:", accuracy_score(newsdata_test.target, predicted))
정확도: 0.8056293149229952
'자연어처리' 카테고리의 다른 글
SentiwordNet (0) | 2022.04.23 |
---|---|
Semantic Network Analysis (0) | 2022.04.23 |
Dynamic Topic Modeling (0) | 2022.04.11 |
토픽모델링이란 (0) | 2022.03.03 |
Latent Dirichlet Allocation(LDA) (0) | 2022.02.19 |