-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmodel.py
More file actions
192 lines (169 loc) · 7.25 KB
/
model.py
File metadata and controls
192 lines (169 loc) · 7.25 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
#importing the necessary libraries
import numpy as np
import pandas as pd
from sklearn.preprocessing import LabelEncoder
import matplotlib.pyplot as plt
import nltk
import seaborn as sns
from nltk.corpus import stopwords
import string
from nltk.stem import PorterStemmer
from wordcloud import WordCloud
from collections import Counter
from sklearn.feature_extraction.text import CountVectorizer, TfidfVectorizer
from sklearn.model_selection import train_test_split
from sklearn.naive_bayes import GaussianNB, MultinomialNB, BernoulliNB
from sklearn.metrics import accuracy_score, precision_score, confusion_matrix
#reading the CSV file
df = pd.read_csv("sms-spam.csv")
#displaying the dataframe
# print(df)
#column 2, 3, 4 have majority missing values, so it is better to drop them.
df.drop(columns=['Unnamed: 2', 'Unnamed: 3', 'Unnamed: 4'], inplace = True)
#renaming the column names to a better and meaningful column name
df.rename(columns = {'v1':'result', 'v2':'input'}, inplace=True)
#result has categorical labels, we need to convert it into numerical values - enbcoding
#for that we will be using 'LabelEncoder' from sklearn
encoder = LabelEncoder()
df['result'] = encoder.fit_transform(df['result'])
#so 0 means no SPAM, 1 means SPAM
#the dataset has NO null values, so don't need to handel them
#the dataset has DUPLICATE values, so we will have to REMOVE them
df = df.drop_duplicates(keep='first')
#the given problem is a classification problem, so we need to understand the data first by performing EDA.
#the dataset has only 2 columns, so less analysis required.
#now we will be analysing the number of alphabets/words/sentences being used in the TEXT
#for this, will create 3 new columns: (1) no. of characters (2) no. of words (3) no. of sentences in SMS
#using 'nltk' library for this.
#Natural Language Toolkit for text processing
#(pip install nltk)
import warnings
warnings.filterwarnings('ignore')
#downloading the dependencies
#punkt package includes pre-trained models for tokenizing text in many languages
import nltk
nltk.download('all')
#creating a new column with count of characters
df['countCharacters'] = df['input'].apply(len)
#creating a new column with count of words
df['countWords'] = df['input'].apply(lambda i:len(nltk.word_tokenize(i)))
#'word_tokenize' function takes a string of text as input and returns a list of words
#creating a new column with count of sentences
df['countSentences'] = df['input'].apply(lambda i:len(nltk.sent_tokenize(i)))
#'sent_tokenize' function takes a string of text as input and returns a list of sentences
#peforming preprocessing such as tokenization (converting the text into tokens or words), removing special characters,
#removing stop words and punctuation and finallying stemming the data.
#also, converting to lower case first and then pre-processing the data
from nltk.corpus import stopwords
stop_words=stopwords.words('english')
def transformtext(text):
usefule_words=[]
text=text.lower()
words=nltk.word_tokenize(text)
for word in words:
if word not in stop_words:
usefule_words.append(word)
print(usefule_words)
# Ye mai dubara likh raha hu
def transform_text (text):
#converting to lower case
text = text.lower()
#tokenization
text = nltk.word_tokenize(text)
#removing special characters
removedSC = list()
for i in text:
if i.isalnum():
removedSC.append(i)
#updating the text after removed special characters
text = removedSC[:]
#removing stop words and punctuation characters
removedSWPC = list()
for i in text:
#stopwords.words('english') is a function of 'nltk', returns list of english stop words
#string.punctuation is a part of 'string' module, containing the ASCII punctuation characters
if i not in stopwords.words('english') and i not in string.punctuation:
removedSWPC.append(i)
#updating the text after removed stop words and punctuation characters
text = removedSWPC[:]
#stemming the data using 'PorterStemmer' algorithm.
#nltk module provides this class to use.
ps = PorterStemmer()
stemmed = list()
for i in text:
stemmed.append(ps.stem(i))
text = stemmed[:]
return " ".join(text)
#will create a new column to store the transformed text -> 'processed'
df['processed'] = df['input'].apply(transform_text)
#will be creating word cloud for data visualization to display the most frequently occurring words in the processed dataset.
#using 'WordCloud' class
wc = WordCloud(width=500, height=500, min_font_size=10, background_color='white')
#NaiveBayes classifier works BEST on textual data, so will firstly perform it on the dataset.
#we need to give numerical inputs to the classifier model, so will have to convert the 'processed' column into vectors.
#using 'bag of words'
#converting the collection of text into a matrix of token counts
cv = CountVectorizer()
#transforming the data of processed column
X = cv.fit_transform(df['processed']).toarray()
df#storing the values of the 'result' column
y = df['result'].values
#splitting the training and testing dataset
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size = 0.2, random_state = 49)
#creating the objects for the models
gnb = GaussianNB()
mnb = MultinomialNB()
bnb = BernoulliNB()
#training the dataset for GaussianNB
gnb.fit(X_train, y_train)
y_pred1 = gnb.predict(X_test)
print(accuracy_score(y_test, y_pred1))
print(confusion_matrix(y_test, y_pred1))
print(precision_score(y_test, y_pred1))
#training the dataset for MultinomialnNB
mnb.fit(X_train, y_train)
y_pred2 = mnb.predict(X_test)
print(accuracy_score(y_test, y_pred2))
print(confusion_matrix(y_test, y_pred2))
print(precision_score(y_test, y_pred2))
#training the dataset for BernoulliNB
bnb.fit(X_train, y_train)
y_pred3 = bnb.predict(X_test)
print(accuracy_score(y_test, y_pred3))
print(confusion_matrix(y_test, y_pred3))
print(precision_score(y_test, y_pred3))
#we have to focus mainly on 'precision' value
#the max precision we got is 9.45 with 9.64 as accuracy
#using 'TfidfVectorizer' for vectorization
tf = TfidfVectorizer()
#transforming the data of processed column
X = tf.fit_transform(df['processed']).toarray()
#storing the values of the 'result' column
y = df['result'].values
#splitting the training and testing dataset
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size = 0.2, random_state = 49)
#training the dataset for GaussianNB
gnb.fit(X_train, y_train)
y_pred1 = gnb.predict(X_test)
print(accuracy_score(y_test, y_pred1))
print(confusion_matrix(y_test, y_pred1))
print(precision_score(y_test, y_pred1))
#training the dataset for MultinomialnNB
mnb.fit(X_train, y_train)
y_pred2 = mnb.predict(X_test)
print(accuracy_score(y_test, y_pred2))
print(confusion_matrix(y_test, y_pred2))
print(precision_score(y_test, y_pred2))
#training the dataset for BernoulliNB
bnb.fit(X_train, y_train)
y_pred3 = bnb.predict(X_test)
print(accuracy_score(y_test, y_pred3))
print(confusion_matrix(y_test, y_pred3))
print(precision_score(y_test, y_pred3))
#model is PREPARED.
#now we have to host the website, for that pipeling needs to be done
#the text which we will get, has to be transformed first, then vectorized and then apply the algorithm
#we will pickle 2 files
import pickle
pickle.dump(tf,open('vectorizer.pkl','wb'))
pickle.dump(mnb,open('model.pkl','wb'))