나이브 베이즈(Naive Bayes)를 이용한 스팸 분류
ㄴ5,574개의 이메일 메시지가 있으며, 스팸인지 아닌지의 정보를 가지고 있다.
ㄴ 컬럼 : text, spam
ㄴ spam 컬럼의 값이 1이면 스팸이고, 0이면 스팸이 아닙니다.
ㄴ 스팸인지 아닌지 분류하는 인공지능을 만들자 - 수퍼바이즈드 러닝의 분류 문제!
- 구글 Colab 코랩 작업환경
import pandas as pd import numpy as np import matplotlib.pyplot as plt import seaborn as sns %matplotlib inline |
- 구글 코랩에서 csv 파일 읽기
from google.colab import drive drive.mount('/content/drive') import os os.chdir('/content/drive/MyDrive/Colab Notebooks') # 지금 작업하고 있는 주피터노트북의 경로를 구글에 맞춰주는 것 # 파일의 경로가 같아야 파일을 읽어올 수 있음 # 디렉토리 = 폴더 # 같은 폴더에 있어야 불러올 수 있다. spam_df = pd.read_csv('emails.csv') |
ex) 스팸은 몇개이고, 아닌것은 몇개인지 확인하시오.
spam_df['spam'].value_counts() sns.countplot(data = spam_df, x ='spam') plt.show() |
ex) 이메일의 길이가 스팸과 관련이 있는지 확인해 보려 합니다. 이메일의 문자 길이를 구해서, length 라는 컬럼을 만드세요.
spam_df['length'] = spam_df['text'].apply(len) # spam_df['text'].str.len() 이랑 같은 뜻 |
ex) 글자 길이를 히스토그램으로 나타내시오.
spam_df['length'].hist() plt.show() spam_df.corr() |
ex) 가장 긴 이메일을 찾아서 스팸인지 아닌지 확인하고, 이메일 내용을 확인하시오.
spam_df.loc[spam_df['length'] == spam_df['length'].max(),] spam_df.loc[spam_df['length'] == spam_df['length'].max(),'text'][2650] # 판다스 시리즈, |
ex) 0은 스팸이 아니고, 1은 스팸입니다. 파이차트를 통해, 스팸과 스팸이 아닌것이 몇 퍼센트인지, 소수점 1자리 까지만 보여주세요.
spam_count = spam_df['spam'].value_counts() plt.pie(spam_df['spam'].value_counts(), autopct='%.1f', labels = spam_df['spam'].value_counts().index) plt.show() |
ex) 스팸이 아닌것은 ham 변수로, 스팸인것은 spam 변수로 저장하시오.
ham = spam_df.loc[spam_df['spam'] == 0,] spam = spam_df.loc[spam_df['spam'] == 1,] # 스팸의 이메일 길이를 히스토그램으로 나타내시오. spam['length'].hist() plt.show() |
ex) 쉼표, 마침표 등의 구두점 제거하기.
ex) 위의 문장에서, 글자를 앞에서부터 하나씩 가져와서, 구두점인지 확인한 후, 구두점이 아닌 문자만 리스트로 저장하시오.
# 결과 예시) [ 'H', 'e', 'l', ... 'M', 'r', ' ','F' ... ] Test = 'hello Mr.Future. I am so happy to be learning AI now~' import string Test_punc_removed = [] for char in Test: if char not in string.punctuation: Test_punc_removed.append(char) [char for char in Test if char not in string.punctuation ] # 상기 for 문이랑 같은 뜻 |
ex) 위의 리스트에 있는 문자들을, 하나의 문자열로 만드시오.
결과 예시) ‘Hello Mr Future…’
Test_punc_removed_join =''.join(Test_punc_removed) |
''.join(리스트)
ex) STOPWORDS(불용어) 제거하기
ㄴ Stopwords(불용어)란? https://bit.ly/34Ipha2
import nltk # 내추럴 랭귀지 툴킷 nltk.download('stopwords') from nltk.corpus import stopwords my_stopwords = stopwords.words('english') |
import nltk # 내추럴 랭귀지 툴킷 nltk.download('stopwords') from nltk.corpus import stopwords my_stopwords = stopwords.words('english') # ㄴ ‘english’ 영어의 불용어 |
ex) 구두점 제거한 문자열을, 이제 불용어 단어에 해당하지 않는 단어들만 모아서 리스트로 만드시오.
결과 예시) [‘Hello’,’Mr’,’Future’...]
Test_punc_removed_join_clean = [] for word in Test_punc_removed_join.split(): if word.lower() not in my_stopwords: Test_punc_removed_join_clean.append(word) Test_punc_removed_join_clean |
ex) 카운트 벡터라이저 (Count Vectorizer)
결과 예시) [‘Hello’,’Mr’,’Future’...]
# 의미 없는 구두점도 제거했고, 의미 없는 단어도 제거했으면, # 이제는, 남아있는 단어들을 숫자로 바꿔줘야 한다. # 단어를 숫자로 바꿔주는 것을 벡터라이징 이라고 한다. from sklearn.feature_extraction.text import CountVectorizer sample_data = ['This is the first document', 'I loved them', 'This document is the secon document', 'I am loving you', 'And this is the third one'] vec = CountVectorizer() # 여기에 사용된 모든 단어를 다 뽑는다. # 다 뽑아서, 알파벳 순으로 정리한다. # 정렬해서 컬럼으로 만든다. X = vec.fit_transform(sample_data) # 5행 14열의 많은 행렬이 만들어졌습니다. # 5개의 문장이여서, 5행, 단어를 알파벳순으로 나열하니 14개의 컬럼 # 학습을 시킬 때 항상 넘파이가 들어가야한다. X = X.toarray() vec.get_feature_names_out() |
from sklearn.feature_extraction.text import CountVectorizer sample_data = ['This is the first document', 'I loved them', 'This document is the secon document', 'I am loving you', 'And this is the third one'] vec = CountVectorizer() X = vec.fit_transform(sample_data) X = X.toarray() vec.get_feature_names_out() |
ex) 데이터프레임에 있는, 이메일 내용을 Cleaning 한다.
# 이제는 실제 이메일의 데이터를 가지고, 지금까지 한 작업들을 종합해서 처리해보자 # 1. 구두점 제거 # 2. 불용어 제거 # 이 두가지를 하나의 함수로 묶어서 사용하겠습니다. => 파이프라이닝 한다 ! import string import nltk nltk.download('stopwords') from nltk.corpus import stopwords my_stopwords = stopwords.words('english') def message_cleaning(sentence) : # 1. 구두점 제거 Test_punc_removed = [char for char in sentence if char not in string.punctuation] # 2. 각 글자들을 하나의 문자열로 합친다. Test_punc_removed_join = ''.join(Test_punc_removed) # 3. 문자열에 불용어가 포함되어잇는지 확인해서, 불용어 제거한다. Test_punc_removed_join_clean = [word for word in Test_punc_removed_join.split() if word.lower() not in my_stopwords] # 4. 결과로 남은 단어들만 리턴한다. return Test_punc_removed_join_clean |
message_cleaning('Hello~~!! my name is, hehehe! nice to meet you!! @') spam_df['text'].apply(message_cleaning) |
ex) 이메일의 내용을 벡터라이징 한다.
# 카운트 벡터라이저의, 애널라이저 파라미터에, # 우리가 만든 구두점과 불용어 제거해주는 함수를, 세팅해주면, # 카운트 백터라이저가 자신이 알아서 문자열을 깨끗하게 먼저 처리한 후에, 숫자로 바꿔준다. vec = CountVectorizer(analyzer = message_cleaning) X = vec.fit_transform(spam_df['text']) # fit: 텍스트에 있는 내용을 몇개가 문자가 나왔는지, 구두점 제거하고 전체 리뷰에서 몇개가 쓰였는지, 컬럼으로 만든다. X = X.toarray() # 학습할 때는 넘파이 어레이로 되어있어야 한다. vec.get_feature_names_out() # 이메일에 등장하는 모든 단어들이 나온다. (불용어 제외) |
vec = CountVectorizer(analyzer = message_cleaning) # ㄴ카운트 백터라이저가 자신이 알아서 문자열을 깨끗하게 먼저 처리한 후에, 숫자로 전환해준다. X = vec.fit_transform(spam_df['text']) X = X.toarray() vec.get_feature_names_out() #ㄴ 불용어를 제외하고, 이메일에 등장하는 모든 단어들이 나온다. |
ex) 데이터 셋으로 훈련 및 모델링
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=15) # 모델링 from sklearn.naive_bayes import MultinomialNB,GaussianNB # 두개 중에 성능 좋은 걸로 사용하시죠 classifier1 = MultinomialNB() # 다항식이라는 뜻 classifier2 = GaussianNB() # 가우시안 classifier1.fit(X_train, y_train) classifier2.fit(X_train,y_train) # 검증 from sklearn.metrics import confusion_matrix,accuracy_score y_pred1 = classifier1.predict(X_test) # 예측한값 y_pred1 # 정답 y_test.values confusion_matrix(y_test,y_pred1) accuracy_score(y_test,y_pred1) y_pred2 = classifier2.predict(X_test) confusion_matrix(y_test, y_pred2) accuracy_score(y_test,y_pred2) |
from sklearn.naive_bayes import MultinomialNB,GaussianNB classifier1 = MultinomialNB() classifier2 = GaussianNB() classifier1.fit(X_train, y_train) classifier2.fit(X_train,y_train) |
ex) 다음 2개의 문장을 테스트 해보시오.
1. Free money!!!
2. Hi Kim, Please let me know if you need any further information. Thanks
testing_sample = ['Free money!!!', "Hi Kim, Please let me know if you need any further information. Thanks"] new_data = np.array(testing_sample) X = vec.transform(new_data) X = X.toarray() classifier1.predict(X) |
Word Cloud Visualizing
ex) 스팸 이메일에는 어떤 단어들이 많이 들어있는지 Visualizing
- Word Cloud 활용 예:
from wordcloud import wordcloud,STOPWORDS # 스팸이메일에는 어떤 단어가 많이 들어있을까요! # 워드 클라우드를 사용하려면, # 1. 판다스의 스팸컬럼에 저장된 문자열을, 리스트로 먼저 받아오고 # 2. 리스트에 있는 문자열을 다 합쳐서, 하나의 문자열로 만들어준다. spam_email_list = spam['text'].tolist() spam_email = ''.join(spam_email_list) |
from wordcloud import wordcloud,STOPWORDS spam_email_list = spam['text'].tolist() spam_email = ''.join(spam_email_list) |
my_stopwords = STOPWORDS my_stopwords.add('subject') my_stopwords.add('us') from PIL import Image img = Image.open('spam.jpg') img_mask = np.array(img) wc = wordcloud.WordCloud(background_color='white', mask = img_mask ,stopwords = my_stopwords) wc.generate(spam_email) plt.figure(figsize = (10,6)) plt.imshow(wc) plt.axis('off') # 이미지 하나 저장하여, 구글 드라이브-작업하고 있는 경로에 업로드한다. # 업르드 하면, 자동으로 연동된다. # Image.open : 이미지를 가져온다. # 이미지는 컴퓨터가 바로 처리 못하니까, 넘파이 어레이로 바꿔준다. # 워드 클라우드 |
'Python-머신러닝' 카테고리의 다른 글
가격 예측 알고리즘: Facebook Prophet (0) | 2022.05.15 |
---|---|
댓글의 긍정/부정 인공지능 알고리즘(나이브 베이즈/서포터 백터 머신) (0) | 2022.05.15 |
실습 및 피쳐스케일링에서 원래 값으로 되돌리기, inverse_transform() (1) | 2022.05.15 |
Count Vectorizing 카운트 벡터라이징: CountVectorizer() (0) | 2022.05.15 |
Word Cloud 1 (0) | 2022.05.10 |