notebook
Spam Text ๋ฐ์ดํฐ์
https://www.kaggle.com/datasets/team-ai/spam-text-message-classification
Spam Text Message Classification
Let's battle with annoying spammer with data science.
www.kaggle.com
Write-up
๋ฐ์ดํฐ ๊ด๋ฆฌ์ ํ์ํ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ค import
import numpy as np # linear algebra
import pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)
SPAM Text ๋ฐ์ดํฐ์ ๋ถ๋ฌ์ค๊ธฐ ๋ฐ ๋ฐ์ดํฐ ์์ฝ
df = pd.read_csv("/kaggle/input/spam-text-message-classification/SPAM text message 20170820 - Data.csv")
df.head()
์์ฝ ๊ฒฐ๊ณผ ํ ์ด๋ธ์ ์ปฌ๋ผ์ Category, Message๋ก ๊ตฌ๋ถ์ด ๋์ด ์๋ค. ๋ฉ์์ง ๋ด์ฉ์ด ์คํธ์ธ ๊ฒฝ์ฐ ์นดํ ๊ณ ๋ฆฌ๊ฐ spam ์๋ ๊ฒฝ์ฐ๋ ham์ผ๋ก ๊ตฌ๋ถ
๋ฉ์์ง๋ค์ X ๋ณ์์ ํ ๋น, ์นดํ ๊ณ ๋ฆฌ๋ y ๋ณ์์ ํ ๋นํ๋ค.
X = df['Message']
y = df['Category']
len(X)
train_test_split() : ๋จธ์ ๋ฌ๋ ๋ชจ๋ธ ํ์ต ๋ฐ ํ๊ฐ ๊ณผ์ ์์ ์ค์ํ ์ญํ ์ ํ๋ ๋ฐ์ดํฐ ๋ถํ ํจ์
์ถ๋ ฅ ๊ฒฐ๊ณผ๋ก๋ ํ์ต์ ํ์ํ (X_train, y_train) ์ถ๋ ฅ๊ณผ ํ ์คํธ์ ์ฌ์ฉํ๋ (X_test, y_test)๊ฐ ๋ฆฌํด๋๋ค.
์ถ๋ ฅ ๊ฒฐ๊ณผ๋ ๋๋ค์ด๋ค.
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=22)
๋ค์ ๋จธ์ ๋ฌ๋์ ์ฌ์ฉํ๋ ํ์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ค์ import
from sklearn.pipeline import Pipeline
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.naive_bayes import MultinomialNB, ComplementNB
from sklearn.svm import LinearSVC
from sklearn.metrics import accuracy_score, classification_report
ํ์ดํ๋ผ์ธ(Pipeline) : ๋ฐ์ดํฐ ์ ์ฒ๋ฆฌ์์ ํ์ต๊น์ง์ ๊ณผ์ ์ ํ๋๋ก ์ฐ๊ฒฐํด์ฃผ๋ ๊ฒ
ํ์ดํ๋ผ์ธ ํจ์ ๊ตฌ์กฐ
ํ์ดํ๋ผ์ธ์ ๋ ๊ฐ๋ก ์ด๋ฃจ์ด์ง ํํ์ ๋ฆฌ์คํธ๋ก ์ธ์๋ฅผ ๋ฐ๋๋ค.
pipeline( [ ('์์
๋ช
1', ์์
ํด๋์ค 1), ('์์
๋ช
2', ์์
ํด๋์ค 2) ] )
ํ์ดํ๋ผ์ธ์ด ์์ด๋ ํ์ต์ ๊ฐ๋ฅํ์ง๋ง ์ผ๋ จ์ ๊ณผ์ ๋ค(๋ณ์ ์ ํ, ํ์คํ, ๋ชจ๋ธ ํ์ต)์ ํ๋ํ๋ ์ฝ๋ฉ์ ํด์ผ ํ๋ฏ๋ก ๋ณต์กํด์ง๋๋ฐ ํ์ดํ๋ผ์ธ์ ์ฌ์ฉํ๋ฉด ์ผ๋ จ์ ๊ณผ์ ๋ค์ ํ ๋ฒ์ ํด๊ฒฐ ๊ฐ๋ฅํ๋ค.
ํ์ดํ๋ผ์ธ ์ฌ์ฉ ์์
์๋๋ ํ์ดํ๋ผ์ธ์ผ๋ก ํ์ต ๋ถํฐ ์์ธก, ์ฑ๋ฅ ํ๊ฐ๋ฅผ ๊ตฌํํ ์ฝ๋์ด๋ค. (์ถ์ฒ : https://zephyrus1111.tistory.com/254)
## ์์
๋ฑ๋ก
pipeline = Pipeline([('Feature_Selection', SelectKBest(f_classif, k=2)), ## ๋ณ์ ์ ํ
('Standardization', StandardScaler()), ## ํ์คํ
('Decision_Tree', DecisionTreeClassifier(max_depth=3)) ## ํ์ต ๋ชจ๋ธ
])
pipeline.fit(X, y) ## ๋ชจํ ํ์ต
print(pipeline.predict(X)[:3]) ## ์์ธก
print(pipeline.score(X, y)) ## ์ฑ๋ฅ ํ๊ฐ
์ ์ฒ๋ฆฌ & ๋ถ๋ฅ๊ธฐ ์ ํ
TfidfVectorizer()๋ ์ฐ๋ฆฌ๊ฐ ์ฝ์ ์ ์๋ ๊ธ์๋ฅผ ์์ฐ์ด๋ผ๊ณ ํ๋๋ฐ ์ด๋ฅผ ์ปดํจํฐ๊ฐ ์ฒ๋ฆฌํ๊ธฐ ์ฝ๋๋ก ๋ฐ์ด๋๋ฆฌ ํํ์ ๊ฐ์ ๋ฌธ์ฅ ๋ฒกํฐํ ์ฒ๋ฆฌํ๋ ์ ์ฒ๋ฆฌ ํจ์์ด๋ค. ํ์ดํ๋ผ์ธ ํจ์ ๊ตฌ์กฐ์์๋ ์์ ํด๋์ค 1์ ์์นํ๋ค.
๊ทธ ์ธ์ MultinomialNB, ComplementNB๋ LinearSVC๋ ๋ถ๋ฅ ๋ฌธ์ ์์ ์ฌ์ฉ๋๋ ํด๋์ค์ด๋ฉฐ ํ์ดํ๋ผ์ธ ํจ์ ๊ตฌ์กฐ์์๋ ์์ ํด๋์ค 2์ ์์นํ๋ค.
pipeMNB = Pipeline([('tfidf', TfidfVectorizer(stop_words='english', ngram_range=(1,3))), ('clf', MultinomialNB())])
pipeCNB = Pipeline([('tfidf', TfidfVectorizer(ngram_range=(1,3))), ('clf', ComplementNB())])
pipeSVC = Pipeline([('tfidf', TfidfVectorizer(ngram_range=(1,3))), ('clf', LinearSVC())])
ํ์ต(fit) ๋ฐ ์์ธก(predict)
์ด์ ๋ง๋ ํ์ดํ๋ผ์ธ์ผ๋ก ํ์ต(fit)๊ณผ ์์ธก(predict)์ ํ๊ณ ์ ํ๋(accuracy score)๋ฅผ ์ถ๋ ฅํ๋ค.
pipeMNB.fit(X_train, y_train)
predictMNB = pipeMNB.predict(X_test)
print(f"MNB: {accuracy_score(y_test, predictMNB):.2f}")
pipeCNB.fit(X_train, y_train)
predictCNB = pipeCNB.predict(X_test)
print(f"CNB: {accuracy_score(y_test, predictCNB):.2f}")
pipeSVC.fit(X_train, y_train)
predictSVC = pipeSVC.predict(X_test)
print(f"SVC: {accuracy_score(y_test, predictSVC):.2f}")
MNB: 0.95
CNB: 0.98
SVC: 0.99
๊ฐ ๋ถ๋ฅ๊ธฐ๋ง๋ค ์ ์์ ์ฝ๊ฐ์ ์ฐจ์ด๊ฐ ์์์ผ๋ฉฐ, ์ฌ๊ธฐ์ ๊ฐ์ฅ ์ ํ๋๊ฐ ๋์ pipeSVC๋ฅผ ์คํธ ๋ถ๋ฅ๊ธฐ๋ก ์ ํ์ ํด์ค๋ค.
์๋ก์ด ๋ฌธ์ฅ์ ์์ธก์ ์์ผ๋ณด๋ฉด spam์ด๋ผ๊ณ ๋์จ ๊ฒ์ ํ์ธํ ์ ์์๋ค.
msg = "you have won a $10000 prize! contact us for eh reward!"
clsf = pipeSVC.predict([msg])
print(clsf[0])
> spam
์ฐธ๊ณ :
https://yumdata.tistory.com/383
https://zephyrus1111.tistory.com/254
https://scikit-learn.org/stable/modules/generated/sklearn.pipeline.Pipeline.html
https://www.youtube.com/watch?v=eOu-h_XxjHQ&t=1713s