Galle, LK--:--5/6 sites live

ML Use Case 3 Spam Mail Prediction using Machine Learning

Text pre-processing සහ TF-IDF, වැඩ කරන spam filter එකකට කෙලින්ම සම්බන්ධ කරන්නෙ මේකෙන් — email provider කෙනෙක්ගේ spam folder එකෙනුත් වැඩ කරන්නෙ මේ core idea එකෙන්ම.

This connects text pre-processing and TF-IDF straight to a working spam filter — the same core idea behind every email provider's spam folder.

9 May 20264 min readSelf Guide · Stage 13#Python & Data Basics#Hands-on Projects#Machine learning

Lesson 24 of 64 · Part 1 · Python & Data Basics · Hands-on Projects · bilingual notes (English + සිංහල)

Why this matters. This connects text pre-processing and TF-IDF straight to a working spam filter — the same core idea behind every email provider's spam folder.

සිංහලෙන්: Text pre-processing සහ TF-IDF, වැඩ කරන spam filter එකකට කෙලින්ම සම්බන්ධ කරන්නෙ මේකෙන් — email provider කෙනෙක්ගේ spam folder එකෙනුත් වැඩ කරන්නෙ මේ core idea එකෙන්ම.

What you'll use this for. Any project where you classify free-form text — reviews, tickets, comments — follows this exact same recipe: vectorize the text, then classify.

සිංහලෙන්: Free-form text classify කරන ඕනම project එකක් — reviews, tickets, comments — follow කරන්නෙ මේම recipe එකම: text එක vectorize කරන්න, එහෙනම් classify කරන්න.

Key principles

  • The model never reads the email — it reads numbers derived from it. TF-IDF turns each email into a row of numbers first. Logistic Regression then works purely on those numbers — the "reading" already happened in the vectorizer.
    Model එක email එක කියවන්නෙ නෑ — ඒකෙන් derive කරපු numbers කියවනවා

Walkthrough

Importing the Dependencies

ExamplePython
import numpy as np
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import accuracy_score

Data Collection & Pre-Processing

ExamplePython
# loading the data from csv file to a pandas Dataframe
raw_mail_data = pd.read_csv('/content/mail_data.csv')
ExamplePython
print(raw_mail_data)

Output

Output
     Category                                            Message
0         ham  Go until jurong point, crazy.. Available only ...
1         ham                      Ok lar... Joking wif u oni...
2        spam  Free entry in 2 a wkly comp to win FA Cup fina...
3         ham  U dun say so early hor... U c already then say...
4         ham  Nah I don't think he goes to usf, he lives aro...
...       ...                                                ...
5567     spam  This is the 2nd time we have tried 2 contact u...
5568      ham               Will ü b going to esplanade fr home?
5569      ham  Pity, * was in mood for that. So...any other s...
5570      ham  The guy did some bitching but I acted like i'd...
5571      ham                         Rofl. Its true to its name

[5572 rows x 2 columns]
ExamplePython
# replace the null values with a null string
mail_data = raw_mail_data.where((pd.notnull(raw_mail_data)),'')
ExamplePython
# printing the first 5 rows of the dataframe
mail_data.head()
CategoryMessage
0hamGo until jurong point, crazy.. Available only ...
1hamOk lar... Joking wif u oni...
2spamFree entry in 2 a wkly comp to win FA Cup fina...
3hamU dun say so early hor... U c already then say...
4hamNah I don't think he goes to usf, he lives aro...
ExamplePython
# checking the number of rows and columns in the dataframe
mail_data.shape

Output

Output
(5572, 2)

Label Encoding

ExamplePython
# label spam mail as 0;  ham mail as 1;

mail_data.loc[mail_data['Category'] == 'spam', 'Category',] = 0
mail_data.loc[mail_data['Category'] == 'ham', 'Category',] = 1

spam - 0

ham - 1

ExamplePython
# separating the data as texts and label

X = mail_data['Message']

Y = mail_data['Category']
ExamplePython
print(X)

Output

Output
0       Go until jurong point, crazy.. Available only ...
1                           Ok lar... Joking wif u oni...
2       Free entry in 2 a wkly comp to win FA Cup fina...
3       U dun say so early hor... U c already then say...
4       Nah I don't think he goes to usf, he lives aro...
                              ...                        
5567    This is the 2nd time we have tried 2 contact u...
5568                 Will ü b going to esplanade fr home?
5569    Pity, * was in mood for that. So...any other s...
5570    The guy did some bitching but I acted like i'd...
5571                           Rofl. Its true to its name
Name: Message, Length: 5572, dtype: object
ExamplePython
print(Y)

Output

Output
0       1
1       1
2       0
3       1
4       1
       ..
5567    0
5568    1
5569    1
5570    1
5571    1
Name: Category, Length: 5572, dtype: object

Splitting the data into training data & test data

ExamplePython
X_train, X_test, Y_train, Y_test = train_test_split(X, Y, test_size=0.2, random_state=3)
ExamplePython
print(X.shape)
print(X_train.shape)
print(X_test.shape)

Output

Output
(5572,)
(4457,)
(1115,)

Feature Extraction

ExamplePython
# transform the text data to feature vectors that can be used as input to the Logistic regression

feature_extraction = TfidfVectorizer(min_df = 1, stop_words='english', lowercase='True')

X_train_features = feature_extraction.fit_transform(X_train)
X_test_features = feature_extraction.transform(X_test)

# convert Y_train and Y_test values as integers

Y_train = Y_train.astype('int')
Y_test = Y_test.astype('int')
ExamplePython
print(X_train)
ExamplePython
print(X_train_features)

Training the Model

Logistic Regression

ExamplePython
model = LogisticRegression()
ExamplePython
# training the Logistic Regression model with the training data
model.fit(X_train_features, Y_train)

Output

Output
LogisticRegression(C=1.0, class_weight=None, dual=False, fit_intercept=True,
                   intercept_scaling=1, l1_ratio=None, max_iter=100,
                   multi_class='auto', n_jobs=None, penalty='l2',
                   random_state=None, solver='lbfgs', tol=0.0001, verbose=0,
                   warm_start=False)

Evaluating the trained model

ExamplePython
# prediction on training data

prediction_on_training_data = model.predict(X_train_features)
accuracy_on_training_data = accuracy_score(Y_train, prediction_on_training_data)
ExamplePython
print('Accuracy on training data : ', accuracy_on_training_data)

Output

Output
Accuracy on training data :  0.9670181736594121
ExamplePython
# prediction on test data

prediction_on_test_data = model.predict(X_test_features)
accuracy_on_test_data = accuracy_score(Y_test, prediction_on_test_data)
ExamplePython
print('Accuracy on test data : ', accuracy_on_test_data)

Output

Output
Accuracy on test data :  0.9659192825112107

Building a Predictive System

ExamplePython
input_mail = ["I've been searching for the right words to thank you for this breather. I promise i wont take your help for granted and will fulfil my promise. You have been wonderful and a blessing at all times"]

# convert text to feature vectors
input_data_features = feature_extraction.transform(input_mail)

# making prediction

prediction = model.predict(input_data_features)
print(prediction)

if (prediction[0]==1):
  print('Ham mail')

else:
  print('Spam mail')

Output

Output
[1]
Ham mail

Keep going: ← Lesson 23 · Lesson 25 → · Track it in the Self Guide