[PYTHON - 머신러닝_나이브베이즈]★string.punctuation 특수문자★join함수★nltk.download('stopword')★불용어★ MultinomialNB★오차행렬
1. 나이브 베이즈
==> 조건부 확률 기반의 분류 모델
https://knowallworld.tistory.com/232
EX) 무료라는 단어가 들어 있을 때 해당 메일이 스팸일 확률
==> 범용성이 높지는 않지만 독립변수들이 모두 독립적이라면 경쟁력있는 알고리즘
장점 :
㉠ 간단한 알고리즘에 속하며, 속도가 빠르다.
㉡ 작은 훈련셋으로도 잘 예측한다.
단점 :
㉠ 모든 독립변수가 각각 독립적임을 전제로 한다. ==> 실제 데이터가 독립적이지 않으면 문제 발생
2. 데이터 확인
data['target'].value_counts()
==> 고윳값 2개 (ham , spam)
3. 전처리
import string
string.punctuation #특수 기호 목록 출력
sample_string = data['text'].loc[0]
for i in sample_string:
if i not in string.punctuation:
print(i)
==> 특수문자 제외하고 출력
new_string = ''.join(new_string)
new_string
==> join함수 활용하여 문자열 붙이기
data['text'].apply(remove_punc)
==> apply 함수를 활용하여 데이터프레임의 한 줄 한 줄을 따로 함수에 적용시킨다.
4. 전처리 : 불용어 제거
==>불용어(stopword) ==> 자연어 분석에 큰 도움이 안되는 단어
import nltk
nltk.download('stopwords') # 불용어 목록 갖고 오기
from nltk.corpus import stopwords #불용어 목록 임포트
stopwords.words('english') #영어 불용어 선택
['i',
'me',
'my',
'myself',
'we',
'our',
'ours',
'ourselves', ......]
==> 한국어 불용어의 경우 되지 않는다. ==> www.ranks.nl 등에서 받는다.
sample_string = data['text'].loc[0]
sample_string.split() #단어 단위로 문장 분할
for i in sample_string.split() :
if i.lower() not in stopwords.words('english'): #불용어가 아니라면 소문자로 변환
print(i.lower())
== stopwords.words('english') ==> 불용어 목록
go
jurong
point
crazy
available
bugis
def stop_words(x):
new_string = []
for i in x.split() : #순회
if i.lower() not in stopwords.words('english'):
new_string.append(i.lower()) #문자 단위로 추가
new_string = ' '.join(new_string)
return new_string
data['text'] = data['text'].apply(stop_words) #텍스트에 stop_words 함수 적용
data['text']
==> 불용어 제거한 문장 출력
5. 전처리 : 목표 컬럼 형태 변경하기
map()함수 : 딕셔너리 타입의 데이터를 사용하여 매칭되는 값을 불러오도록 사용할 수 있다.
data['target'] = data['target'].map({'spam' : 1 , 'ham' : 2}) #텍스트를 숫자로 변환
data['target']
6. 전처리 : 카운트 기반으로 벡터화 하기
==> 문자를 개수 기반으로 벡터화 하기
==> 데이터 전체에 존재하는 모든 단어들을 사전처럼 모은 뒤에 인덱스를 부여하고, 문장마다 속한 단어가 있는 인덱스를 카운트하는 것이다.
x = data['text'] #독립변수
y = data['target'] #종속변수
from sklearn.feature_extraction.text import CountVectorizer
cv = CountVectorizer() # 객체 생성
cv.fit(x) #학습하기
cv.vocabulary_ #단어와 인덱스 출력
==> sklearn.feature_extraction.text 라이브러리의 CountVectorizer 모듈 임포트한다.
{'go': 3791,
'jurong': 4687,
'point': 6433,
'crazy': 2497,
'available': 1414,
'bugis': 1881,
'great': 3888,
'world': 9184,
'la': 4847, ... } ==> 단어와 인덱스 출력
x = cv.transform(x) #transform
print(x) # (데이터의 행 번호(데이터 프레임의 행 번호) , 단어의 인덱스 값) 행에서 출현 횟수
(0, 1181) 1
(0, 1414) 1
(0, 1879) 1
(0, 1881) 1
(0, 2214) 1
(0, 2497) 1
(0, 3791) 1
(0, 3848) 1
(0, 3888) 1
(0, 4687) 1
==> (데이터의 행 번호(데이터 프레임의 행 번호) , 단어의 인덱스 값) 행에서 출현 횟수
print(cv.vocabulary_['go'])
print(cv.vocabulary_['jurong'])
print(cv.vocabulary_['point'])
3791
4687
6433
==> 인덱스값 출력
7. 모델링 및 예측/평가하기
from sklearn.model_selection import train_test_split
X_train , X_test , y_train , y_test = train_test_split(x,y , test_size= 0.2 , random_state= 100) #학습셋 시험셋 분활
from sklearn.naive_bayes import MultinomialNB # 나이브 베이즈 알고리즘으로 MultinomialNB 모듈 사용한다.
#==> 다항분포(Multinormial)외에 정규분포 베르누이분포에 따른 NB 모듈이 있다.
model = MultinomialNB() #모델 객체 생성
model.fit(X_train , y_train) #학습
pred = model.predict(X_test) #예측
from sklearn.metrics import accuracy_score , confusion_matrix
print(f'정확도 계산 : {accuracy_score(y_test, pred)}') # 정확도 계산
print(confusion_matrix(y_test , pred)) # 혼동(오차) 행렬 출력
==> MultinomialNB ==> 나이브 베이즈 알고리즘
==> confusion_matrix() ==> 오차 행렬 출력
정확도 계산 : 0.9856502242152466
[[134 4]
[ 12 965]]
0 | 1 | |
0 | 134 | 4 |
1 | 12 | 965 |
==> 실제값이 0 이고, 예측값이 0인 경우는 134건
==> 실제값이 1이고, 예측값이 1인 경우는 965건이다.
sns.heatmap(confusion_matrix(y_test , pred) , annot= True , fmt= '.0f')
제 1 종 오류 : 실제 음성인 것을 양성으로 예측하는 오류
제 2 종 오류 : 실제 양성인 것을 음성으로 예측하는 오류
EX) 건강한 사람(음성) ==> 당신은 코로나19에 걸렸다.(양성) ==> 음성인데 양성으로 판단( 제 1종오류 , 거짓 양성)
코로나에 걸린 사람(양성) ==> 당신은 건강하다.(음성) ==> 양성인데 음성으로 판단(제 2종오류 , 거짓 음성)
8. 나이브 베이즈 모델
https://knowallworld.tistory.com/233
어떤 사건 A가 이미 발생했다는 조건 아래서, 사건 B가 일어날 확률을 의미 ==> P(B|A)
P(A | B) : 사후확률 ==> B가 발생했을 때, A가 발생할 확률 ==> 스팸문자의 B라는 특정 단어가 등장했을 때, A가 스팸일 확률
P(A) : 사전확률 ==> B의 발생유무와 관련없이 기본적으로 A가 발생할 확률로서 , 전체 문자 중 스팸문자의 비율
P(B|A) : 우도(Likelihood) 혹은 가능도, A가 발생했을 때 , B가 발생할 확률, 스팸 메일인 경우 B라는 특정 단어가 들어 있을 확률
P(B) : 전체에서 B가 발생할 확률, 전체 문자에서 B라는 특정 단어가 들어 있을 확률
# 1. 청소년중 1명 선택 ==> 염색을 원할 확률 ==> P(청소년 | 하고 싶다.) =
p_handa = round(A.loc['합계' , '하고 싶다.'] , 4)
print(p_handa)
# 2. 남자가 선정 ==> 이 사람이 염색을 원할 확률 ==> P(남자 | 하고 싶다.) =
P_nam_handa = round(A.loc['남자' , '하고 싶다.'] / A.loc['남자' , '합계'] , 4)
print(P_nam_handa)
# 3. 여자가 선정 ==> 이 사람이 염색을 원할 확률 ==> P(여자 | 하고 싶다.) =
P_woman_handa = round(A.loc['여자' , '하고 싶다.'] / A.loc['여자' , '합계'] , 4)
print(P_woman_handa)
==> '합계' 행의 '하고싶다.' 열
출처 : 데싸노트의 실전에서 통하는 머신러닝
(Golden Rabbit , 저자 : 권시현)
※혼자 공부용