728x90
반응형
스팸 메일 분류 예측 모델에 대하여 진행해 보고자 합니다.
데이터는 kaggle 스팸 수집 데이터셋 에서 다운로드 받으시면 됩니다.
SMS Spam Collection Dataset
Collection of SMS messages tagged as spam or legitimate
www.kaggle.com
위 데이터를 colab에 올려서 사용 하시면됩니다.
데이터 읽기
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
from sklearn.model_selection import train_test_split
df = pd.read_csv('/content/spam.csv', encoding='latin1') # 파일위치는 커스터마이징
encoding = 'latin1'으로 하지 않으면 read_csv에서 인코딩 문제가 발생하니 주의해 주시기 바랍니다.
불필요한 컬럼 삭제
#df.head() #컬럼이름 확인 후 불필요한 컬럼 삭제
df.drop(['Unnamed: 2', 'Unnamed: 3', 'Unnamed: 4'], axis=1, inplaced=True)
#
#df.dropna(how="any", inplace=True, axis=1) 도 가능 how: any, all
컬럼이름 변경
df = df.rename(columns={'v1':'Category','v2':'Message'})
df
데이터 확인
df.isnull().sum() # null 체크
df.shape #(행 수, 열 수) 형식의 튜플(tuple) 나타냄
df.info() #DataFrame의 전체 구조를 요약해서 보여주는 함수입니다.
df.describe(include='all').T
df['Category'].value_counts() #category 갯수
위 내용은 각각 실행해 보시기 바랍니다.
저는 기존에 학습한 dfSummary(df)로 확인해 보겠습니다.
#!pip install summarytools # colab에서 실행시 설치
from summarytools import dfSummary
dfSummary(df)
데이터 전처리
import nltk
import re
from nltk.corpus import stopwords
from nltk.stem import PorterStemmer
nltk.download('stopwords')
ps = PorterStemmer()
def preprocess_message(message):
message = message.lower()
message = re.sub('[^a-zA-Z]', ' ', message)
message = message.split()
message = [ps.stem(word) for word in message if not word in set(stopwords.words('english'))]
message = ' '.join(message)
return message
df['Message'] = df['Message'].apply(preprocess_message)
df.head()
nltk.download('stopwords')
- NLTK에서 영어 불용어(stopwords) 리스트를 다운로드합니다.
- 불용어란 분석에 큰 의미가 없는 단어들 (예: is, the, a, and 등)
ps = PorterStemmer()
- PorterStemmer는 단어의 어간(stem)을 추출해주는 도구입니다.(예: running, runner → run)
message = re.sub('[^a-zA-Z]', ' ', message)
- 알파벳 이외의 문자는 공백으로 대체 (숫자, 특수문자 제거)
문자데이터 숫자변환( TfidfVectorizer)
from sklearn.feature_extraction.text import TfidfVectorizer
vectorizer = TfidfVectorizer(max_features=5572)
#vecotrizer = TfidfVectorizer(min_df=1, stop_words='english', lowercase=True)
X= vectorizer.fit_transform(df['Message']).toarray()
y= df['Category'].map({'ham': 0, 'spam': 1})
X.shape, y.shape
TfidfVectorizer는 문자열 텍스트를 TF-IDF 수치 벡터로 변환하는 도구입니다.
- TF (Term Frequency): 단어가 문서 내에 얼마나 자주 등장하는가
- IDF (Inverse Document Frequency): 문서 전체에서 얼마나 드문 단어인가
- 문서 간 차별화되는 단어들에 높은 가중치를 부여
- max_features=5572는 가장 많이 등장한 단어 5,572개까지만 사용하겠다는 의미
- len(df) = 5572
데이터 Split
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=42)
모델 훈련 및 예측
#MultinomialNB
from sklearn.naive_bayes import MultinomialNB
from sklearn.metrics import accuracy_score, classification_report
nb_model = MultinomialNB()
nb_model.fit(X_train,y_train)
y_pred=nb_model.predict(X_test)
print(f"정확도: {accuracy_score(y_test, y_pred)}")
정확도: 0.967713004484305
- Multinomial Naive Bayes 모델은 주로 텍스트 분류, 문서 분류, 이메일 스팸 필터링에 사용되는 분류기입니다..
- 단어 빈도 기반 벡터(ex: TF, TF-IDF)에 적합합니다.
#LogisticRegression
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import accuracy_score
lr = LogisticRegression()
lr.fit(X_train, y_train)
y_pred = lr.predict(X_test)
from sklearn.metrics import accuracy_score
print(f"정확도: {accuracy_score(y_test, y_pred)}")
정확도: 0.95695067264574
분류 보고서(Metric)
print(classification_report(y_test, y_pred))
MultinomialNB가 로지스틱회귀보다 정확도가 높게 나타났습니다.
728x90
반응형
'머신러닝' 카테고리의 다른 글
[ML] 타이타닉 생존 예측 분류모델 (0) | 2025.04.16 |
---|---|
[ML]Wine Quality Classification (0) | 2025.04.01 |