diff --git a/Spam_Classifiier_NLP.ipynb b/Spam_Classifiier_NLP.ipynb new file mode 100644 index 0000000..f0e0f10 --- /dev/null +++ b/Spam_Classifiier_NLP.ipynb @@ -0,0 +1,438 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "import pandas as pd\n", + "import sqlite3\n", + "import regex as re\n", + "import matplotlib.pyplot as plt\n", + "\n", + "from wordcloud import WordCloud" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
textspam
0Subject: naturally irresistible your corporate...1
1Subject: the stock trading gunslinger fanny i...1
2Subject: unbelievable new homes made easy im ...1
3Subject: 4 color printing special request add...1
4Subject: do not have money , get software cds ...1
\n", + "
" + ], + "text/plain": [ + " text spam\n", + "0 Subject: naturally irresistible your corporate... 1\n", + "1 Subject: the stock trading gunslinger fanny i... 1\n", + "2 Subject: unbelievable new homes made easy im ... 1\n", + "3 Subject: 4 color printing special request add... 1\n", + "4 Subject: do not have money , get software cds ... 1" + ] + }, + "execution_count": 2, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df = pd.read_csv('emails.csv')\n", + "df.head()" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "spam count: 1368\n", + "not spam count: 4360\n", + "(5728, 2)\n", + "(5695, 2)\n" + ] + } + ], + "source": [ + "print(\"spam count: \" +str(len(df.loc[df.spam==1])))\n", + "print(\"not spam count: \" +str(len(df.loc[df.spam==0])))\n", + "print(df.shape)\n", + "df['spam'] = df['spam'].astype(int)\n", + "\n", + "df = df.drop_duplicates()\n", + "print(df.shape)\n", + "\n", + "df = df.reset_index(inplace = False)[['text','spam']]" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
textspam
0Subject: naturally irresistible your corporate...1
1Subject: the stock trading gunslinger fanny i...1
2Subject: unbelievable new homes made easy im ...1
3Subject: 4 color printing special request add...1
4Subject: do not have money , get software cds ...1
\n", + "
" + ], + "text/plain": [ + " text spam\n", + "0 Subject: naturally irresistible your corporate... 1\n", + "1 Subject: the stock trading gunslinger fanny i... 1\n", + "2 Subject: unbelievable new homes made easy im ... 1\n", + "3 Subject: 4 color printing special request add... 1\n", + "4 Subject: do not have money , get software cds ... 1" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df.head()" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
indextextspam
00subject naturally irresistible your corporate ...1
11subject the stock trading gunslinger fanny is ...1
22subject unbelievable new homes made easy im wa...1
\n", + "
" + ], + "text/plain": [ + " index text spam\n", + "0 0 subject naturally irresistible your corporate ... 1\n", + "1 1 subject the stock trading gunslinger fanny is ... 1\n", + "2 2 subject unbelievable new homes made easy im wa... 1" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "clean_desc = []\n", + "for w in range(len(df.text)):\n", + " desc = df['text'][w].lower()\n", + " \n", + " #remove punctuation\n", + " desc = re.sub('[^a-zA-Z]', ' ', desc)\n", + " \n", + " #remove tags\n", + " desc=re.sub(\"</?.*?>\",\" <> \",desc)\n", + " \n", + " #remove digits and special chars\n", + " desc=re.sub(\"(\\\\d|\\\\W)+\",\" \",desc)\n", + " \n", + " clean_desc.append(desc)\n", + "#assign the cleaned descriptions to the data frame\n", + "df['text'] = clean_desc\n", + "df = df.reset_index() \n", + "df.head(3)" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + " precision recall f1-score support\n", + "\n", + " 0 0.98 0.99 0.98 1926\n", + " 1 0.97 0.94 0.95 637\n", + "\n", + " accuracy 0.98 2563\n", + " macro avg 0.97 0.96 0.97 2563\n", + "weighted avg 0.98 0.98 0.98 2563\n", + "\n" + ] + } + ], + "source": [ + "from sklearn.feature_extraction.text import CountVectorizer\n", + "text_vec = CountVectorizer().fit_transform(df['text'])\n", + "\n", + "from sklearn.metrics import classification_report\n", + "from sklearn.model_selection import train_test_split\n", + "X_train, X_test, y_train, y_test = train_test_split(text_vec, df['spam'], test_size = 0.45\n", + " , random_state = 42, shuffle = True)\n", + "#from sklearn.tree import DecisionTreeClassifier\n", + "#classifier = DecisionTreeClassifier(max_depth = 7)\n", + "\n", + "#from sklearn.ensemble import RandomForestClassifier, AdaBoostClassifier\n", + "#classifier = RandomForestClassifier(max_depth=6, n_estimators=8)\n", + "#classifier = AdaBoostClassifier()\n", + "\n", + "from sklearn.svm import SVC\n", + "classifier = SVC(kernel=\"linear\", C=0.025)\n", + "\n", + "#from sklearn import ensemble \n", + "#classifier = ensemble.GradientBoostingClassifier(\n", + "# n_estimators = 100, #how many decision trees to build\n", + "# learning_rate = 0.5, #controls rate at which additional decision trees influes overall prediction\n", + "# max_depth = 6, \n", + "# min_samples_split = 21,\n", + "# min_samples_leaf = 19, \n", + " #max_features = 0.9,\n", + " #loss = 'huber'\n", + "#)\n", + "\n", + "classifier.fit(X_train, y_train)\n", + "\n", + "predictions = classifier.predict(X_test)\n", + "\n", + "print(classification_report(y_test, predictions))" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + " precision recall f1-score support\n", + "\n", + " 0 1.00 1.00 1.00 2401\n", + " 1 1.00 0.99 1.00 731\n", + "\n", + " accuracy 1.00 3132\n", + " macro avg 1.00 1.00 1.00 3132\n", + "weighted avg 1.00 1.00 1.00 3132\n", + "\n", + "Confusion Matrix: \n", + " [[2401 0]\n", + " [ 4 727]]\n", + "\n", + "Accuracy: 0.9987228607918263\n" + ] + } + ], + "source": [ + "from sklearn.metrics import classification_report,confusion_matrix, accuracy_score\n", + "pred = classifier.predict(X_train)\n", + "print(classification_report(y_train ,pred ))\n", + "print('Confusion Matrix: \\n',confusion_matrix(y_train,pred))\n", + "print()\n", + "print('Accuracy: ', accuracy_score(y_train,pred))" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + " precision recall f1-score support\n", + "\n", + " 0 0.98 0.99 0.98 1926\n", + " 1 0.97 0.94 0.95 637\n", + "\n", + " accuracy 0.98 2563\n", + " macro avg 0.97 0.96 0.97 2563\n", + "weighted avg 0.98 0.98 0.98 2563\n", + "\n", + "Confusion Matrix: \n", + " [[1906 20]\n", + " [ 40 597]]\n", + "\n", + "Accuracy: 0.9765899336714787\n" + ] + } + ], + "source": [ + "pred = classifier.predict(X_test)\n", + "print(classification_report(y_test ,pred ))\n", + "print('Confusion Matrix: \\n', confusion_matrix(y_test,pred))\n", + "\n", + "print()\n", + "print('Accuracy: ', accuracy_score(y_test,pred))" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.6.10" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +}