<jupyter_start><jupyter_text>**Spam Mail Classifier**![alt text](https://miro.medium.com/max/1536/1*mzIPUxnxbzdjlJusLnkNRQ.jpeg)  Import Libraries<jupyter_code># Handling Data
import pandas as pd
import numpy as np

# Visialization
import matplotlib.pyplot as plt
import seaborn as sns
sns.set_style('whitegrid')

# For Text processing 
import nltk
from nltk.corpus import stopwords 
from nltk.tokenize import word_tokenize
# nltk.download('punkt')
# nltk.download('stopwords')

# ML
from sklearn.model_selection import train_test_split
from sklearn.feature_extraction.text import CountVectorizer
from sklearn.linear_model import LogisticRegression

#Accuracy Metrics
from sklearn.metrics import accuracy_score, classification_report, confusion_matrix

# Change to current working directory
%cd /content/drive/My Drive/DataScience/Data_Science_Head_Start<jupyter_output>/content/drive/My Drive/DataScience/Data_Science_Head_Start<jupyter_text>Reading Data<jupyter_code>df = pd.read_csv('data/Spam_Mail_Dataset.csv')
# Removing Unnecessary column
df.drop('Unnamed: 0', axis=1, inplace = True)
# Changing column names
df.columns = ['label', 'text', 'class']
df.head()
df.shape
df.info()
# No NaN in the data
df.isna().sum()
# Barplot describes the count of the class labels
plt.figure(figsize = (12, 6))
sns.countplot(data = df, x = 'label');<jupyter_output><empty_output><jupyter_text>Remove stopwords from the data<jupyter_code>%%time
stop_words = set(stopwords.words('english')) 

df['text'] = df['text'].apply(lambda x: ' '.join([ word for word in word_tokenize(x)  if not word in stop_words]))
df.sample(10)
X = df.loc[:, 'text']
y = df.loc[:, 'class']

print(f"Shape of X: {X.shape}\nshape of y: {y.shape}")<jupyter_output>Shape of X: (5171,)
shape of y: (5171,)<jupyter_text>Split data into **train** and **test** in 80:20<jupyter_code>X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.20, random_state=11)
print(f"Train Data Shape: {X_train.shape}\nTest Data Shape: {X_test.shape}")<jupyter_output>Train Data Shape: (4136,)
Test Data Shape: (1035,)<jupyter_text>Preprocess text to build the ML mdel<jupyter_code>cVect = CountVectorizer()
cVect.fit(X_train)<jupyter_output><empty_output><jupyter_text>Let's see the vocabulary that has extracted by hte count vextorizer<jupyter_code>print('NO.of Tokens: ',len(cVect.vocabulary_.keys()))
# document term vector (dtv)
dtv = cVect.transform(X_train)
type(dtv)
dtv = dtv.toarray()
print(f"Number of Observations: {dtv.shape[0]}\nTokens/Features: {dtv.shape[1]}")
# Let's see an sample that has been preprocessed
dtv[1]
%%time
lr = LogisticRegression(solver='lbfgs')
lr.fit(dtv, y_train)<jupyter_output>CPU times: user 31.4 s, sys: 768 ms, total: 32.2 s
Wall time: 16.8 s<jupyter_text>Evaluate on the Test data<jupyter_code># Preprocess the test data
test_dtv = cVect.transform(X_test)
test_dtv = test_dtv.toarray()
print(f"Number of Observations: {test_dtv.shape[0]}\nTokens/Features: {test_dtv.shape[1]}")
%%time
pred = lr.predict(test_dtv)
print('Accuracy: ', accuracy_score(y_test, pred) * 100)<jupyter_output>Accuracy:  98.45410628019323<jupyter_text>Classification Report of the classifier<jupyter_code># 0 - Not Spam / Ham
# 1 - Spam 
print(classification_report(y_test, pred))<jupyter_output>precision    recall  f1-score   support

           0       1.00      0.98      0.99       744
           1       0.95      0.99      0.97       291

    accuracy                           0.98      1035
   macro avg       0.98      0.99      0.98      1035
weighted avg       0.99      0.98      0.98      1035<jupyter_text>Confusion Matrix<jupyter_code>cmat = confusion_matrix(y_test, pred)
plt.figure(figsize = (6, 6))
sns.heatmap(cmat, annot = True, cmap = 'Paired', cbar = False, fmt="d", xticklabels=['Not Spam', 'Spam'], yticklabels=['Not Spam', 'Spam']);<jupyter_output><empty_output><jupyter_text>Predict Class label for the unseen data i.e., Spam or Not Spam<jupyter_code>def predict_class(lr):
  text = input('Enter Text(Subject of the mail): ')
  text = [' '.join([ word for word in word_tokenize(text)  if not word in stop_words])]
  t_dtv = cVect.transform(text).toarray()
  print('Predicted Class:', end = ' ')
  print('Spam' if lr.predict(t_dtv)[0] else 'Not Spam') 
  prob = lr.predict_proba(t_dtv)*100
  print(f"Not Spam: {prob[0][0]}%\nSpam: {prob[0][1]}%")

predict_class(lr)<jupyter_output>Enter Text(Subject of the mail): 'You won 1000$ prize money in lottery. Click here to avail'
Predicted Class: Spam
Not Spam: 4.453477590482279%
Spam: 95.54652240951772%
{'fraction_non_alphanumeric': 0.13038698328935797, 'fraction_numerical': 0.039797713280562884, 'mean_word_length': 5.139001349527665, 'pattern_counts': {'":': 0, '<': 34, '<?xml version=': 0, '>': 34, 'https://': 1, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 6, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '10', 'dir': 'jupyter-structured-clean-dedup', 'id': '541362', 'license': 'MIT', 'n_tokens_mistral': 1831, 'n_tokens_neox': 1692, 'n_words': 399, 'path': 'Machine_Learning/Spam_Mail_Classifier.ipynb', 'repo_name': 'syamkakarla98/Data_Science_Head_Start', 'size': '4548'}