-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathfootball_fake_vs_real_news (1).py
More file actions
348 lines (254 loc) · 9.45 KB
/
Copy pathfootball_fake_vs_real_news (1).py
File metadata and controls
348 lines (254 loc) · 9.45 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
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
# -*- coding: utf-8 -*-
"""Football_Fake_Vs_Real_News.ipynb
Automatically generated by Colaboratory.
Original file is located at
https://colab.research.google.com/drive/114ZXBgGYbI8WKybfCpnDfA4xG_yLhGTf
**ADEYEMO SUNDAY ABDULLAHI - OlabisiDS Notebook**
**ABOUT DATASET**
**Abstract**💡
A king of yellow journalism, fake news is false information and hoaxes spread through social media and other online media to achieve a chaos agenda
**About this dataset** 📭
The dataset contains 20,000 real news and 20,000 fake news
The dataset is collected from Twitter and Youm7
**Objective of Notebook**
Building a model that differentiate between fake and real football news
**Exploration Environment Set-Up**
"""
import numpy as np
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
from wordcloud import WordCloud
import nltk
from textblob.download_corpora import download_all
download_all()
from nltk.corpus import stopwords
from textblob import Word, TextBlob
nltk.download('stopwords')
import re, string
from collections import Counter
from nltk.stem import WordNetLemmatizer
#To ignore warnings
import warnings
warnings.filterwarnings("ignore")
real_news = pd.read_csv("/content/real.csv")
fake_news = pd.read_csv("/content/fake.csv")
real_news.head()
fake_news.head()
real_news["news_class"] = "real"
fake_news["news_class"] = "fake"
football_news = pd.concat([real_news, fake_news])
football_news.head()
print(football_news.shape)
football_news.info()
football_news.duplicated().sum()
football_news.drop_duplicates(inplace=True)
football_news.duplicated().sum()
football_news.isnull().sum()
football_news.dropna(inplace=True)
football_news.isnull().sum()
football_news.shape
"""**Checking Distribution of Fake and Real News**"""
plt.figure(figsize=(10,5))
ax = sns.countplot(x="news_class", data=football_news, palette="viridis")
ax.bar_label(ax.containers[0], label_type="edge")
plt.title("Distribution of News")
plt.xlabel("News Class")
plt.ylabel("Count")
plt.show();
"""**Cleaning Tweets/News**"""
#Incase there are upper case alphabets, convert all to lower case in tweets
football_news["tweet"] = football_news["tweet"].str.lower()
#Removing punctuation marks in tweets
football_news["tweet"] = football_news["tweet"].str.replace("[^\w\s]", "")
#Removing numbers in tweets
football_news["tweet"] = football_news["tweet"].str.replace("\d", "")
#Removing stop words in tweets. words that are commonly used i.e the, and etc
stop_words = set(stopwords.words("english"))
football_news["tweet"] = football_news["tweet"].apply(lambda x: " ".join(x for x in x.split() if x not in stop_words))
#Removing URL links
football_news["tweet"] = football_news["tweet"].apply(lambda x: " ".
join(re.sub(r"http\S+", "", x) for x in x.split()))
#Lemmatization of words in tweets
football_news["tweet"] = football_news["tweet"].apply(lambda x: " ".
join([Word(word).lemmatize() for word in x.split()]))
#Checking tweet head
football_news.head()
"""**WordCloud for Real News**"""
words = " ".join(str(i) for i in football_news[football_news["news_class"] == "real"]["tweet"])
wc = WordCloud(
background_color="white",
width=800,
height=400,
max_words=400
).generate(words)
plt.figure(figsize=(20, 10))
plt.imshow(wc, interpolation="bilinear")
plt.axis("off")
plt.show()
"""**WordCloud for Fake News**"""
words = " ".join(str(i) for i in football_news[football_news["news_class"] == "fake"]["tweet"])
wc = WordCloud(
background_color="white",
width=800,
height=400,
max_words=400
).generate(words)
plt.figure(figsize=(20, 10))
plt.imshow(wc, interpolation="bilinear")
plt.axis("off")
plt.show()
"""**Counting Words Apperances/Popularity in News**"""
#Get words from tweet and append to corpus list
corpus = []
for i in football_news.tweet:
for j in i.split():
corpus.append(j.strip())
#count the words
counter = Counter(corpus)
common_words = counter.most_common(15)
dict(common_words)
"""**Modelling**
**Modelling Environment Set-Up**
"""
from sklearn.model_selection import train_test_split, GridSearchCV
from sklearn.preprocessing import LabelEncoder
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.ensemble import RandomForestClassifier
from xgboost import XGBClassifier
from sklearn import metrics
from sklearn.metrics import confusion_matrix , classification_report, roc_curve, auc
X = football_news["tweet"]
y = football_news["news_class"]
#Vectorizing feature X
tfidf_vectorizer = TfidfVectorizer(max_features=1000)
X = tfidf_vectorizer.fit_transform(X)
#Encoding target
label = LabelEncoder()
y = label.fit_transform(y)
"""**Splitting Data into Training and Test Set**"""
X_train, X_test, y_train, y_test= train_test_split(X, y, test_size=0.2, random_state=42)
print("X_train:", X_train.shape)
print("X_test:", X_test.shape)
print("y_train:", y_train.shape)
print("y_test:", y_test.shape)
"""**Random Forest Classifier Model**"""
rfc_param_grid = {
"n_estimators": [50, 100, 200],
"max_depth": [10, 20],
"min_samples_split": [2, 5, 10],
"min_samples_leaf": [1, 2, 4]
}
model_rfc = RandomForestClassifier()
rfc_model = GridSearchCV(
model_rfc,
param_grid=rfc_param_grid,
cv=5)
#fit rfc_model to training set
rfc_model.fit(X_train, y_train)
#Checking rfc_model best param
rfc_best_params = rfc_model.best_params_
print("RFC Best Params:", rfc_best_params)
#Checking rfc_model accuracy on training set
rfc_acc = rfc_model.score(X_train, y_train)
print("RFR Training Accuracy:", rfc_acc.round(2))
#Prediction on test set
rfc_test_pred = rfc_model.predict(X_test)
"""**Classification Report for Random Forest Classifier Predictions**"""
rfc_classification_report = classification_report(y_test, rfc_test_pred)
print(rfc_classification_report)
"""**Confusion Matrix for Random Forest Classifier Predictions**"""
plt.figure(figsize = (8,6))
sns.heatmap(confusion_matrix(y_test, rfc_test_pred),
annot=True,
fmt='', cmap="Purples")
plt.xlabel("Predicted")
plt.ylabel("Actual")
plt.show();
"""**Plotting ROC Curve for Random Forest Classifier**"""
fpr, tpr, _ = roc_curve(y_test, rfc_test_pred)
roc_auc = auc(fpr, tpr)
plt.figure(figsize=(8, 6))
plt.plot(fpr, tpr, color="darkorange", lw=2, label="ROC curve (AUC = {:.2f})".format(roc_auc))
plt.plot([0, 1], [0, 1], color="navy", lw=2, linestyle="--")
plt.xlabel("RFC False Positive Rate")
plt.ylabel("RFC True Positive Rate")
plt.title("Random Forest Classifier ROC Curve")
plt.legend(loc="lower right")
plt.show();
"""**XGBoost Classifier Model**"""
from sklearn.model_selection import RandomizedSearchCV
xgb_param_grid = {
"learning_rate": [0.01, 0.1],
"n_estimators": [50, 100],
"max_depth": [10, 20],
"min_child_weight": [1, 3],
"subsample": [0.8, 1.0],
"colsample_bytree": [0.8, 1.0],
}
model_xgb = XGBClassifier()
xgb_model = RandomizedSearchCV(
model_xgb,
param_distributions=xgb_param_grid,
n_iter=7,
cv=5
)
#Fit xgb_model to the training set
xgb_model.fit(X_train, y_train)
#Checking xgb_model best params
xgb_best_params = xgb_model.best_params_
print("XGBoost Best Params:", xgb_best_params)
#Checking xgb_model accuracy on training set
xgb_acc = xgb_model.score(X_train, y_train)
print("XGB Training Accuracy:", xgb_acc.round(2))
#Prediction on test set
xgb_test_pred = xgb_model.predict(X_test)
"""**Classification Report for XGBoost Classifier Predictions**"""
xgb_classification_report = classification_report(y_test, xgb_test_pred)
print(xgb_classification_report)
"""**Confusion Matrix for XGBoost Classifier Predictions**"""
plt.figure(figsize = (8,6))
sns.heatmap(confusion_matrix(y_test, xgb_test_pred),
annot=True,
fmt='', cmap="Purples")
plt.xlabel("Predicted")
plt.ylabel("Actual")
plt.show();
"""**Plotting ROC Curve for XGBoost Classifier**"""
fpr, tpr, _ = roc_curve(y_test, xgb_test_preod)
roc_auc = auc(fpr, tpr)
plt.figure(figsize=(8, 6))
plt.plot(fpr, tpr, color="darkorange", lw=2, label="ROC curve (AUC = {:.2f})".format(roc_auc))
plt.plot([0, 1], [0, 1], color="navy", lw=2, linestyle="--")
plt.xlabel("XGB False Positive Rate")
plt.ylabel("XGB True Positive Rate")
plt.title("XGBoost Classifier ROC Curve")
plt.legend(loc="lower right")
plt.show();
"""**Creating Dataframe to Evaluate Both Models Performances Metrics**"""
#Creating a new classification report that returns output as strings
rfc_report_str = classification_report(y_test, rfc_test_pred, output_dict=True)
xgb_report_str = classification_report(y_test, xgb_test_pred, output_dict=True)
#Extracting metrics for RFC model
rfc_metrics = {
"Model": "Random Forest Classifier",
"Accuracy": f"{rfc_report_str['accuracy']:.2%}",
"Precision": f"{rfc_report_str['macro avg']['precision']:.2%}",
"Recall": f"{rfc_report_str['macro avg']['recall']:.2%}",
"F1 Score": f"{rfc_report_str['macro avg']['f1-score']:.2%}"
}
#Extracting metrics for XGB Classifier model
xgb_metrics = {
"Model": "XGBoost Classifier",
"Accuracy": f"{xgb_report_str['accuracy']:.2%}",
"Precision": f"{xgb_report_str['macro avg']['precision']:.2%}",
"Recall": f"{xgb_report_str['macro avg']['recall']:.2%}",
"F1 Score": f"{xgb_report_str['macro avg']['f1-score']:.2%}"
}
#Creating DataFrame
classification_metrics_comparison = pd.DataFrame([rfc_metrics, xgb_metrics])
#Displaying the DataFrame
print(classification_metrics_comparison)
"""**XGBoost performed slightly better than Random Forest Classifier**
**Thank You**
"""