Implementing a spam detector using Bernoulli and Multinomial NB
As an exercise, I am implementing two Naïve Bayes models for spam detection. I am using SMS Spam Collection Dataset for this task. Here is the code :
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
dataset=pd.read_csv("spam.csv")
x=dataset.iloc[:,1].values
y=dataset.iloc[:, 0].values
from sklearn.model_selection import train_test_split
x_train , x_test, y_train , y_test = train_test_split(x,y,test_size=0.25,random_state=0)
# Creating the word counts matrix
from sklearn.feature_extraction.text import CountVectorizer
cv = CountVectorizer()
x_train = cv.fit_transform(x_train)
x_test=cv.transform(x_test)
# Creating the models
from sklearn.naive_bayes import MultinomialNB
from sklearn.naive_bayes import BernoulliNB
multi_model = MultinomialNB()
multi_model.fit(x_train, y_train)
bern_model = BernoulliNB(binarize=0.0)
bern_model.fit(x_train, y_train)
# The achieved accuracy value is 98% using the multinomial NB
y_pred=multi_model.predict(x_test)
from sklearn.metrics import accuracy_score
print(accuracy_score(y_test, y_pred))
# making a prediction using multinomial NB
test_msg = ['you won a free trip to USA']
test_msg=cv.transform(test_msg)
print(multi_model.predict(test_msg))
# The achieved accuracy value is 96% using the Bernoulli NB
y_pred=bern_model.predict(x_test)
print(accuracy_score(y_test, y_pred))
# making a prediction using Bernoulli NB
from sklearn.preprocessing import Binarizer
test_msg = ['You have been selected to receive a $1000 prize reward ! To claim your reward call 090654414']
test_msg=cv.transform(test_msg)
transformer = Binarizer(threshold=0.0)
test_msg=transformer.fit_transform(test_msg)
print(bern_model.predict(test_msg))
Now I have several questions to fully understand Bernoulli and Multinomial NB : 1) Bernoulli NB works when the data ( features and target variables) take only binary values. 392
Is that right ? Moreover, can we still say that the data follows a Bernoulli distribution if only the features take binary values but not the target variable?
2) Multinomial NB works when every feature represents a count or relative frequency, like the one generated from CountVectorizer(). Is that right ? Moreover, can we still say that the data follows a multinomial distribution if only the features represents a count or relative frequency but the target variable represents continuous values?
3) The SMS Spam Collection Dataset have a categorical target variable with values either "spam" or "ham". As you can see in my code, I didn't encode the target variable using for example label encoder , but still the code works ! Why is that ? I was expecting that the code will not work when I run it ! Did both models implicitly done the encoding ?
4) If there is a new word in the test set, the CountVectorizer() will drop it and will not include it in the vectorized test set ( the output of CountVectorizer.transform(x_test)) and hence it will not be fed into the model for prediction, is that right ?
5) Did I done the correct steps for the prediction of test_msgusing <PERSON><PHONE_NUMBER>']
test_msg=cv.transform(test_msg)
transformer = Binarizer(threshold=0.0)
test_msg=transformer.fit_transform(test_msg)
print(bern_model.predict(test_msg))
Now I have several questions to fully understand Bernoulli and Multinomial NB : 1) Bernoulli NB works when the data ( features and target variables) take only binary values. Is that right ? 458