We’re living in an era of data. With every click on the internet, we’re collectively contributing to a huge amount of data and businesses are using all of it to their advantage. However, amidst all this scenario, there is a lot of scamming going on as well, in the form of spam messages.
Not only do spam messages collect a lot of user data without their consent, but they also end up wasting a lot of your time. So, in this article, we will see how we can easily build a scam message detector in Python all by ourselves. We will be using the scikit-learn library for training the model and spam message datasetfrom Kaggle. Let’s start!
If you want to jump onto the binder to run the code, feel free to click here.
Implementation in Python
Let’s see how we can implement a spam message detector in Python using scikit-learn. Don’t worry, it won’t be as difficult of a problem as it might seem.
Let’s kick things off by importing the basic libraries we need first.
Now, we need to import the dataset. I have uploaded the dataset to Google Drive so I don’t have to upload it every time I need to run the notebook. Let’s mount the drive so we can access the dataset from there.
This command will work if you’re using Google Colab and want to mount the drive on it. Otherwise, if you manually need to upload the dataset, you don’t need to do this step.
Next, we need to access the dataset from the drive we just mounted.
We will use the head function of pandas now to see how the dataframe looks like.
As we can see, the columns are not named correctly. That’s an issue we want to address. Other than that, we can also see that there are three columns that we don’t really need. The unnamed ones to be more precise.
So, let’s name the columns in a way that they make sense and remove the ones we don’t need. Also, we will convert the target column to a binary form so it becomes easier to see if a certain message is spam or not. For the spams, we will use ‘1’, and ‘0’ for the ones that are not spams.
That’s all done there. Let’s see how the data looks like now; again, using the head function.
As you can see, the dataframe has gotten a lot cleaner now. We could also rename the ‘v2’ column for further convenience, but this will do for now.
Next up, we need to split the data into testing and training sets now, since we don’t have a separate dataset for testing purposes once we’re done training our model. If you don’t know why it’s necessary to use a different dataset for testing, jump on here to know more about it in detail.
Let’s check the class distribution and see what ratio of spam messages we are dealing with. A very low ratio could be an obstacle in successful model training. Let’s see.
There are approximately 13.5% of the total messages that are marked as spam as can be seen. This confirms that the instances of spam messages are not too few and we can successfully train our model. Let’s move on.
We need to make a vocabulary of all the words in our dataset. This can be done using the count vectorizer. What it does it that it takes in all the words in the dataset and makes a vocabulary using it. Let’s fit it on our training data. Needless to say, we need to import the module from sklearn’s feature extraction library before using it first.
Let’s see the vocabulary made by the count vectorizer using the vocabulary_ function.
And the list goes on. This dictionary contains all the tokens in the training data along with their frequency (the number of times they appear).
This step confirms that we have successfully made the vocabulary and can move forward.
Training the Model
While there are a lot of models we could use, I’ve decided to use Multinomial Naïve Bayes Classifier since it’s suitable for this use case. Feel free to use any classifier if you think it would be more suitable.
Let’s import the classifier and feed the training data to it.
It’s important to note that since the data is in textual form, we first need to convert it using the countVectorizer and then transform it before we can feed it to the model. Here’s how it can be done.
Now we need to make an instance of the Naïve Bayes Classifier and fit this training data on it.
That’s it. Once you’re able to run this cell, your model will be trained and ready to make new predictions. The output will show you the default parameters for the classifier.
Before making any predictions, let’s check the AUC score for the classifier to see its performance using the testing set we set aside earlier. Make sure you use the transformed testing set and not the one in raw form.
If you wish to know what AUC score is and how it works, don’t hesitate to dive into detail here. Also, you could use any other accuracy metrics here as well.
Let’s run this cell and see how good our model is performing.
Amazing!! This score tells us that the model is performing great! Even more than what we aimed for. However, this dataset might have one problem that’s not quite easy to spot. There might be some tokens having less frequency and hence they might not have a huge influence over detecting if the message is spam or not.
Nevertheless, these tokens contribute to the model as much as the others do so we need to remove these tokens having a low frequency from our dataset.
For this purpose, we will be using the Tfidf vectorizer and after fitting it onto the training data, we will limit the minimum number of tokens to be 5. After that, the process will be pretty much similar. Let’s see.
As you can see, the AUC score has decreased since we’re ignoring the documents with a frequency of less than 5. But don’t worry, our model will perform better than before.
That’s it, this step marks the end of model development and we’re ready to use it and predict if messages are spam or not.
Detecting Spam Messages
Finally, it’s time to test what we built. We will simply input the string we want to check into the model and the resulting output will tell us if it’s a spam or not. Remember, an output of 1 means that the message is a spam while 0 would mean it’s not a spam.
Let’s input some sample values and see how it goes.
Great! We can see that our model has successfully detected a spam message. Now let’s test it using some legit message and see if our model is able to detect that.
Amazing! So that’s it with testing and you can now use this model anytime you wish to detect spam messages automatically.
As you can see, it wasn’t that hard building a spam message detector which seems like a big job at first. Not that this is the most accurate model and ready for commercial usage, it’s a good start for beginners and they could certainly use this as a reference point.
If you want the full code used throughout this tutorial, you can download it from my GitHub.