ragkasi commited on
Commit
0403b6d
·
verified ·
1 Parent(s): 677d607

Upload 20 files

Browse files
.gitattributes ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ data/raw/fake-and-real-news-2/fake_and_real_news.csv filter=lfs diff=lfs merge=lfs -text
2
+ data/raw/fake-and-real-news/Fake.csv filter=lfs diff=lfs merge=lfs -text
3
+ data/raw/fake-and-real-news/True.csv filter=lfs diff=lfs merge=lfs -text
.gitignore ADDED
@@ -0,0 +1,121 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ venv
2
+ models
3
+
4
+ # Python virtual environments
5
+ venv/
6
+ .venv/
7
+ env/
8
+ .env/
9
+ ENV/
10
+ env.bak/
11
+ venv.bak/
12
+
13
+ # Python cache and compiled files
14
+ __pycache__/
15
+ *.py[cod]
16
+ *$py.class
17
+ *.so
18
+ .Python
19
+ build/
20
+ develop-eggs/
21
+ dist/
22
+ downloads/
23
+ eggs/
24
+ .eggs/
25
+ lib/
26
+ lib64/
27
+ parts/
28
+ sdist/
29
+ var/
30
+ wheels/
31
+ share/python-wheels/
32
+ *.egg-info/
33
+ .installed.cfg
34
+ *.egg
35
+ MANIFEST
36
+
37
+ # Jupyter Notebook checkpoints
38
+ .ipynb_checkpoints/
39
+ notebooks/.ipynb_checkpoints/
40
+ */.ipynb_checkpoints/
41
+
42
+ # Model files and training outputs
43
+ models/
44
+ *.h5
45
+ *.hdf5
46
+ *.pkl
47
+ *.pickle
48
+ *.joblib
49
+ *.pt
50
+ *.pth
51
+ *.ckpt
52
+ *.safetensors
53
+ wandb/
54
+ tensorboard_logs/
55
+ mlruns/
56
+
57
+ # Data files (uncomment if you have large datasets)
58
+ # data/
59
+ # *.csv
60
+ # *.json
61
+ # *.parquet
62
+ # *.feather
63
+
64
+ # Training and evaluation results
65
+ results/
66
+ outputs/
67
+ logs/
68
+ *.log
69
+
70
+ # Environment variables and configuration
71
+ .env
72
+ .env.local
73
+ .env.*.local
74
+ config.ini
75
+ secrets.json
76
+
77
+ # IDE and editor files
78
+ .vscode/
79
+ .idea/
80
+ *.swp
81
+ *.swo
82
+ *~
83
+ .DS_Store
84
+ Thumbs.db
85
+ .project
86
+ .pydevproject
87
+
88
+ # Temporary files
89
+ *.tmp
90
+ *.temp
91
+ temp/
92
+ tmp/
93
+
94
+ # Coverage and testing
95
+ .coverage
96
+ .pytest_cache/
97
+ .tox/
98
+ .nox/
99
+ .coverage.*
100
+ htmlcov/
101
+ .cache
102
+
103
+ # Documentation builds
104
+ docs/_build/
105
+ .sphinx/
106
+
107
+ # PyInstaller
108
+ *.manifest
109
+ *.spec
110
+
111
+ # Unit test / coverage reports
112
+ .coverage
113
+ .pytest_cache/
114
+ cover/
115
+
116
+ # Rope project settings
117
+ .ropeproject
118
+
119
+ # Spyder project settings
120
+ .spyderproject
121
+ .spyproject
.streamlit/config.toml ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ [server]
2
+ # Disable file watcher to prevent PyTorch compatibility issues
3
+ fileWatcherType = "none"
4
+
5
+ # Disable usage stats collection
6
+ gatherUsageStats = false
7
+
8
+ # Set headless mode for better performance
9
+ headless = true
10
+
11
+ # Disable CORS protection for local development
12
+ enableCORS = false
13
+
14
+ [browser]
15
+ # Disable automatic browser opening
16
+ gatherUsageStats = false
17
+
18
+ [theme]
19
+ # Optional: set a nice theme
20
+ primaryColor = "#1f77b4"
21
+ backgroundColor = "#ffffff"
22
+ secondaryBackgroundColor = "#f0f2f6"
23
+ textColor = "#262730"
README.md ADDED
@@ -0,0 +1,165 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Fake News Detection Project
2
+
3
+ A machine learning project that classifies news articles as real or fake using both traditional NLP techniques and advanced transformer models.
4
+
5
+ ## 🎯 Project Overview
6
+
7
+ This project implements multiple approaches to detect fake news:
8
+ - **Traditional ML**: TF-IDF vectorization with Logistic Regression
9
+ - **Deep Learning**: Fine-tuned BERT model for sequence classification
10
+
11
+ ## 📊 Performance Results
12
+
13
+ ### TF-IDF + Logistic Regression Model
14
+ - **Accuracy**: 98.62%
15
+ - **F1 Score**: 98.67%
16
+
17
+ #### Detailed Classification Report:
18
+ ```
19
+ precision recall f1-score support
20
+
21
+ 0 0.98 0.99 0.99 4284 (Real News)
22
+ 1 0.99 0.98 0.99 4696 (Fake News)
23
+
24
+ accuracy 0.99 8980
25
+ macro avg 0.99 0.99 0.99 8980
26
+ weighted avg 0.99 0.99 0.99 8980
27
+ ```
28
+
29
+ ## 📁 Project Structure
30
+
31
+ ```
32
+ FakeNewsDetector/
33
+ ├── README.md
34
+ ├── requirements.txt
35
+ ├── notebooks/
36
+ │ └── FakeNewsClassifier_HuggingFace.ipynb
37
+ ├── scripts/
38
+ │ └── train.py
39
+ ├── models/
40
+ │ └── bert-fake-news/ (generated after training)
41
+ ├── data/
42
+ ├── app/
43
+ └── venv/
44
+ ```
45
+
46
+ ## 🚀 Quick Start
47
+
48
+ ### 1. Clone and Setup
49
+ ```bash
50
+ git clone <repository-url>
51
+ cd FakeNewsDetector
52
+ ```
53
+
54
+ ### 2. Create Virtual Environment
55
+ ```bash
56
+ python -m venv venv
57
+
58
+ # Windows PowerShell
59
+ .\venv\Scripts\Activate.ps1
60
+
61
+ # Windows CMD
62
+ .\venv\Scripts\activate.bat
63
+
64
+ # Git Bash
65
+ source venv/Scripts/activate
66
+ ```
67
+
68
+ ### 3. Install Dependencies
69
+ ```bash
70
+ pip install -r requirements.txt
71
+ ```
72
+
73
+ ### 4. Launch Jupyter Notebook
74
+ ```bash
75
+ jupyter notebook
76
+ ```
77
+
78
+ ## 📚 Dataset
79
+
80
+ The project uses the `mrm8488/fake-news` dataset from Hugging Face, which contains:
81
+ - **Total articles**: ~45,000
82
+ - **Training split**: 80% (~36,000 articles)
83
+ - **Test split**: 20% (~9,000 articles)
84
+ - **Classes**:
85
+ - 0: Real News
86
+ - 1: Fake News
87
+
88
+ ## 🔧 Models Implemented
89
+
90
+ ### 1. TF-IDF + Logistic Regression
91
+ - **Vectorizer**: TF-IDF with 5,000 max features, n-grams (1,2)
92
+ - **Classifier**: Logistic Regression with balanced class weights
93
+ - **Performance**: 98.62% accuracy
94
+
95
+ ### 2. BERT Fine-tuning
96
+ - **Base Model**: `bert-base-uncased`
97
+ - **Training**: 3 epochs with evaluation per epoch
98
+ - **Optimizer**: AdamW with learning rate 2e-5
99
+ - **Batch Size**: 8 per device
100
+
101
+ ## 🛠️ Usage
102
+
103
+ ### Running the Notebook
104
+ 1. Ensure your virtual environment is activated
105
+ 2. Start Jupyter: `jupyter notebook`
106
+ 3. Open `notebooks/FakeNewsClassifier_HuggingFace.ipynb`
107
+ 4. Make sure the kernel is set to "venv" or "FakeNewsDetector (venv)"
108
+ 5. Run all cells
109
+
110
+ ### Training BERT Model
111
+ ```bash
112
+ python scripts/train.py
113
+ ```
114
+
115
+ The trained model will be saved to `models/bert-fake-news/`
116
+
117
+ ## 📋 Requirements
118
+
119
+ - Python 3.8+
120
+ - pandas
121
+ - scikit-learn
122
+ - datasets (Hugging Face)
123
+ - transformers
124
+ - torch
125
+ - matplotlib
126
+ - seaborn
127
+ - jupyter
128
+ - ipywidgets
129
+
130
+ ## 🎯 Key Features
131
+
132
+ - **High Accuracy**: Achieves 98.6% accuracy on test set
133
+ - **Multiple Approaches**: Compares traditional ML vs. transformer models
134
+ - **Easy Setup**: Simple virtual environment setup
135
+ - **Comprehensive Analysis**: Includes confusion matrix and detailed metrics
136
+ - **Production Ready**: Trained models can be saved and deployed
137
+
138
+ ## 🔍 Model Analysis
139
+
140
+ The TF-IDF + Logistic Regression model shows excellent performance:
141
+ - **Balanced Performance**: High precision and recall for both classes
142
+ - **Low False Positives**: 98% precision for fake news detection
143
+ - **Low False Negatives**: 99% recall for real news detection
144
+ - **Robust**: Handles class imbalance well with balanced weights
145
+
146
+ ## 🚀 Future Improvements
147
+
148
+ - [ ] Implement ensemble methods combining multiple models
149
+ - [ ] Add cross-validation for more robust evaluation
150
+ - [ ] Experiment with other transformer models (RoBERTa, DistilBERT)
151
+ - [ ] Deploy model as a web API
152
+ - [ ] Add real-time news article classification
153
+ - [ ] Implement explainability features (LIME, SHAP)
154
+
155
+ ## 🤝 Contributing
156
+
157
+ Contributions, issues, and feature requests are welcome! Feel free to check the [issues page](../../issues).
158
+
159
+ ## 📧 Contact
160
+
161
+ For questions or suggestions, please open an issue or contact the project maintainer.
162
+
163
+ ---
164
+
165
+ **Note**: This project is for educational and research purposes. Always verify news from multiple reliable sources.
app/app.py ADDED
@@ -0,0 +1,36 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ from transformers import AutoTokenizer, AutoModelForSequenceClassification, pipeline
3
+
4
+ # Set page config
5
+ st.set_page_config(page_title="Fake News Detector", page_icon="📰")
6
+
7
+ # Hugging Face model path (change this to your actual repo ID)
8
+ MODEL_DIR = "ragkasi/bert-fake-news"
9
+
10
+ @st.cache_resource
11
+ def load_pipeline():
12
+ tokenizer = AutoTokenizer.from_pretrained(MODEL_DIR)
13
+ model = AutoModelForSequenceClassification.from_pretrained(MODEL_DIR)
14
+ return pipeline("text-classification", model=model, tokenizer=tokenizer)
15
+
16
+ classifier = load_pipeline()
17
+
18
+ # UI
19
+ st.title("📰 Fake News Detector")
20
+ st.markdown("Enter a news **headline** or **statement**, and this app will predict if it's **real** or **fake**.")
21
+
22
+ news_input = st.text_area("✏️ News Text", height=150)
23
+
24
+ if st.button("🔍 Check News"):
25
+ if news_input.strip():
26
+ result = classifier(news_input)[0]
27
+ label = result["label"]
28
+ score = result["score"]
29
+
30
+ # Adjust label display
31
+ if label == "LABEL_1":
32
+ st.error(f"🚨 Likely **Fake News** (Confidence: `{score:.2f}`)")
33
+ else:
34
+ st.success(f"✅ Likely **Real News** (Confidence: `{score:.2f}`)")
35
+ else:
36
+ st.warning("⚠️ Please enter a news statement.")
data/raw/fake-and-real-news-2/fake_and_real_news.csv ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:1c27a9eba250b78e392310f35876fe47623768d447715d8784850f91936539be
3
+ size 25876225
data/raw/fake-and-real-news/Fake.csv ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:bebf8bcfe95678bf2c732bf413a2ce5f621af0102c82bf08083b2e5d3c693d0c
3
+ size 62789876
data/raw/fake-and-real-news/True.csv ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:ba0844414a65dc6ae7402b8eee5306da24b6b56488d6767135af466c7dcb2775
3
+ size 53582940
data/raw/liar/README ADDED
@@ -0,0 +1,41 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ LIAR: A BENCHMARK DATASET FOR FAKE NEWS DETECTION
2
+
3
+ William Yang Wang, "Liar, Liar Pants on Fire": A New Benchmark Dataset for Fake News Detection, to appear in Proceedings of the 55th Annual Meeting of the Association for Computational Linguistics (ACL 2017), short paper, Vancouver, BC, Canada, July 30-August 4, ACL.
4
+ =====================================================================
5
+ Description of the TSV format:
6
+
7
+ Column 1: the ID of the statement ([ID].json).
8
+ Column 2: the label.
9
+ Column 3: the statement.
10
+ Column 4: the subject(s).
11
+ Column 5: the speaker.
12
+ Column 6: the speaker's job title.
13
+ Column 7: the state info.
14
+ Column 8: the party affiliation.
15
+ Column 9-13: the total credit history count, including the current statement.
16
+ 9: barely true counts.
17
+ 10: false counts.
18
+ 11: half true counts.
19
+ 12: mostly true counts.
20
+ 13: pants on fire counts.
21
+ Column 14: the context (venue / location of the speech or statement).
22
+
23
+ Note that we do not provide the full-text verdict report in this current version of the dataset,
24
+ but you can use the following command to access the full verdict report and links to the source documents:
25
+ wget http://www.politifact.com//api/v/2/statement/[ID]/?format=json
26
+
27
+ ======================================================================
28
+ The original sources retain the copyright of the data.
29
+
30
+ Note that there are absolutely no guarantees with this data,
31
+ and we provide this dataset "as is",
32
+ but you are welcome to report the issues of the preliminary version
33
+ of this data.
34
+
35
+ You are allowed to use this dataset for research purposes only.
36
+
37
+ For more question about the dataset, please contact:
38
+ William Wang, william@cs.ucsb.edu
39
+
40
+ v1.0 04/23/2017
41
+
data/raw/liar/test.tsv ADDED
The diff for this file is too large to render. See raw diff
 
data/raw/liar/train.tsv ADDED
The diff for this file is too large to render. See raw diff
 
data/raw/liar/valid.tsv ADDED
The diff for this file is too large to render. See raw diff
 
data/test.csv ADDED
File without changes
data/train.csv ADDED
File without changes
notebooks/FakeNewsClassifier_HuggingFace.ipynb ADDED
The diff for this file is too large to render. See raw diff
 
notebooks/FakeNews_EDA.ipynb ADDED
@@ -0,0 +1,177 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "cells": [
3
+ {
4
+ "cell_type": "code",
5
+ "execution_count": 1,
6
+ "metadata": {},
7
+ "outputs": [
8
+ {
9
+ "name": "stderr",
10
+ "output_type": "stream",
11
+ "text": [
12
+ "c:\\Users\\super\\Documents\\CSE Projects\\FakeNewsDetector\\venv\\Lib\\site-packages\\tqdm\\auto.py:21: TqdmWarning: IProgress not found. Please update jupyter and ipywidgets. See https://ipywidgets.readthedocs.io/en/stable/user_install.html\n",
13
+ " from .autonotebook import tqdm as notebook_tqdm\n",
14
+ "Generating train split: 100%|██████████| 44898/44898 [00:01<00:00, 25984.86 examples/s]\n"
15
+ ]
16
+ }
17
+ ],
18
+ "source": [
19
+ "from datasets import load_dataset\n",
20
+ "\n",
21
+ "dataset = load_dataset(\"mrm8488/fake-news\")\n",
22
+ "dataset = dataset['train'].train_test_split(test_size=0.2)\n",
23
+ "\n",
24
+ "# Split out sets\n",
25
+ "train_ds = dataset['train']\n",
26
+ "test_ds = dataset['test']\n"
27
+ ]
28
+ },
29
+ {
30
+ "cell_type": "code",
31
+ "execution_count": 2,
32
+ "metadata": {},
33
+ "outputs": [],
34
+ "source": [
35
+ "import pandas as pd\n",
36
+ "\n",
37
+ "train_df = train_ds.to_pandas()\n",
38
+ "test_df = test_ds.to_pandas()\n"
39
+ ]
40
+ },
41
+ {
42
+ "cell_type": "code",
43
+ "execution_count": 4,
44
+ "metadata": {},
45
+ "outputs": [
46
+ {
47
+ "data": {
48
+ "image/png": "iVBORw0KGgoAAAANSUhEUgAAAk0AAAHHCAYAAACiOWx7AAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjMsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvZiW1igAAAAlwSFlzAAAPYQAAD2EBqD+naQAAOepJREFUeJzt3Ql4FFXa//07gGFRFiFAiEZ22QkSFVFB0EhABuURN0BBRVAHlM2AcZBVJwoiIijRUQRHmEFckO1BILIpQSDsIMgSRP8ScAEiWwKh3+s+11P9dmc9hCTdHb6f6yqSrjpdXd1Up359tg5yuVwuAQAAQK5K5L4ZAAAAitAEAABggdAEAABggdAEAABggdAEAABggdAEAABggdAEAABggdAEAABggdAEAABggdCEYq9WrVry+OOPS6AbPXq0BAUFFcljtWvXziyOlStXmsf+7LPPiuTx9f9L/998Zf369RIcHCw//fSTFGf6Gv/tb3/z9WFctjK/p8+dOyfh4eHy7rvv+vS4kDNCEwLW/v375emnn5Y6depImTJlpEKFCnLbbbfJ5MmT5cyZM+LPZsyYYf5YOosef1hYmERHR8vbb78tf/31V4E8zq+//mr+MG/ZskX8jT8f2z/+8Q/p3r271KxZ02v9Dz/8IB07dpSrrrpKKleuLI899pj89ttvPgk7nueP53L27FnxdxpK//73v0tkZKRcccUVRfZhIDv64cDz9Stbtqw0b95c3nrrLblw4UKRHou+FkOGDJFXX301IP4fL0elfH0AQH4sWrRIHnzwQSldurT06tVLmjZtKunp6fLtt99KTEyM7Ny5U95//33xd2PHjpXatWubT5gpKSmmRmfQoEHy5ptvyvz5880fb8eIESPkxRdfvOhgMmbMGHORbdGihfX9li5dKoUtt2P717/+VeQXLIeGuOXLl8vatWu91v/yyy/Stm1bqVixovzzn/+UkydPyhtvvCHbt29310wVJX3Nhg4dmmV9UR9HfixevFg++OADc37rh54ff/zRp8dz7bXXSlxcnPn9999/l9mzZ8vgwYNNINYAU5SeeOIJ8z7XY3jyySeL9LGRN0ITAk5ycrI88sgjphbgm2++kRo1ari39e/fX/bt22dCVSDo1KmT3Hjjje7bsbGx5jlpk8m9995rajb0k68qVaqUWQrT6dOnpVy5cj6/8Oon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iI6Olj179sixY8fcZfR+nrSMrs9JWlqaqcXyXAAAQPHl16FJa38+/vhjSUhIkNdff11WrVplaqYyMjLM9pSUFBOoPJUqVUoqV65stjllqlev7lXGuZ1XGWd7duLi4qRixYruRftKAQCA4sunzXN5eeSRR9y/a+fs5s2bS926dU3t01133eXTY4uNjZUhQ4a4b2tNE8EJAIDiy69rmjKrU6eOhISEyL59+8xt7et09OhRrzLnz583I+qcflD688iRI15lnNt5lcmpL5XT10pH7HkuAACg+Aqo0PTLL7+YPk01atQwt1u3bi3Hjx83o+Ic33zzjVy4cEFatWrlLqMj6s6dO+cuo528tY/U1Vdf7S6jTYCetIyuBwAA8Hlo0vmUdCSbLio5Odn8fujQIbNNR7OtW7dODh48aELNfffdJ/Xq1TOdtFWjRo1Mv6e+ffvK+vXr5bvvvpMBAwaYZj0dOad69OhhOoHrdAI6NcGcOXPMaDnPprWBAweaUXgTJ06U3bt3mykJNm7caPYFAADg89CkweSGG24wi9Igo7+PHDlSSpYsaSalvPfee+X66683oScyMlLWrFljmsYcOqWATkqpfZx0qoHbb7/daw4m7aS9dOlSE8j0/kOHDjX795zL6dZbb5XZs2eb++m8UZ999pmZaLNp06ZF/IoAAAB/FeRyuVy+PojiQDuCa0A7ceJEofZvioz5uND2DQSqpAm9pDjg/Q0U/fv7Yq7fAdWnCQAAwFcITQAAABYITQAAABYITQAAABYITQAAABYITQAAABYITQAAABYITQAAABYITQAAABYITQAAABYITQAAABYITQAAABYITQAAABYITQAAABYITQAAABYITQAAABYITQAAABYITQAAABYITQAAABYITQAAABYITQAAABYITQAAABYITQAAABYITQAAABYITQAAABYITQAAABYITQAAABYITQAAABYITQAAABYITQAAABYITQAAABYITQAAABYITQAAABYITQAAABYITQAAABYITQAAAP4emlavXi1dunSRsLAwCQoKknnz5rm3nTt3ToYPHy7NmjWTK6+80pTp1auX/Prrr177qFWrlrmv5/Laa695ldm2bZu0adNGypQpI+Hh4TJ+/PgsxzJ37lxp2LChKaOPuXjx4kJ85gAAIND4NDSdOnVKIiIi5J133smy7fTp07Jp0yZ5+eWXzc8vvvhC9uzZI/fee2+WsmPHjpXDhw+7l+eee869LTU1VTp06CA1a9aUpKQkmTBhgowePVref/99d5m1a9dK9+7dpU+fPrJ582bp2rWrWXbs2FGIzx4AAASSUr588E6dOpklOxUrVpRly5Z5rZs6darcfPPNcujQIbnuuuvc68uXLy+hoaHZ7mfWrFmSnp4u06dPl+DgYGnSpIls2bJF3nzzTenXr58pM3nyZOnYsaPExMSY2+PGjTOPrY8XHx9fgM8YAAAEqoDq03TixAnT/FapUiWv9docV6VKFbnhhhtMTdL58+fd2xITE6Vt27YmMDmio6NNrdWxY8fcZaKiorz2qWV0fU7S0tJMLZbnAgAAii+f1jRdjLNnz5o+TtqMVqFCBff6559/Xlq2bCmVK1c2zWyxsbGmiU5rklRKSorUrl3ba1/Vq1d3b7v66qvNT2edZxldn5O4uDgZM2ZMAT9LAADgrwIiNGmn8IceekhcLpdMmzbNa9uQIUPcvzdv3tzUKD399NMm1JQuXbrQjknDmedja02TdjIHAADFU6lACUw//fSTfPPNN161TNlp1aqVaZ47ePCgNGjQwPR1OnLkiFcZ57bTDyqnMjn1k1IayAozlAEAAP9SIhAC0969e2X58uWm31JetJN3iRIlpFq1auZ269atzdQGui+HdvLWQKVNc06ZhIQEr/1oGV0PAADg85qmkydPyr59+9y3k5OTTejR/kk1atSQBx54wEw3sHDhQsnIyHD3MdLt2gynHbW///57ad++vRlBp7cHDx4sjz76qDsQ9ejRw/Q90ukEtE+UTiOgo+UmTZrkftyBAwfKHXfcIRMnTpTOnTvLf//7X9m4caPXtAQAAODy5tPQpMFEA4/D6SPUu3dvM5fS/Pnzze0WLVp43W/FihXSrl070zymAUfL6mg27fCtocmzr5FOXbB06VLp37+/REZGSkhIiIwcOdI93YC69dZbZfbs2TJixAh56aWXpH79+maizaZNmxbBqwAAAAKBT0OTBh/t3J2T3LYpHTW3bt26PB9HO4ivWbMm1zIPPvigWQAAAAKuTxMAAIC/IDQBAABYIDQBAABYIDQBAABYIDQBAABYIDQBAABYIDQBAABYIDQBAABYIDQBAABYIDQBAABYIDQBAABYIDQBAABYIDQBAABYIDQBAABYIDQBAABYIDQBAABYIDQBAABYIDQBAABYIDQBAABYIDQBAABYIDQBAABYIDQBAABYIDQBAABYIDQBAABYIDQBAABYIDQBAAAUVmi688475fjx41nWp6ammm0AAADFTb5C08qVKyU9PT3L+rNnz8qaNWsK4rgAAAD8SqmLKbxt2zb377t27ZKUlBT37YyMDFmyZIlcc801BXuEAAAAgRaaWrRoIUFBQWbJrhmubNmyMmXKlII8PgAAgMALTcnJyeJyuaROnTqyfv16qVq1qntbcHCwVKtWTUqWLFkYxwkAABA4oalmzZrm54ULFwrreAAAAAI/NHnau3evrFixQo4ePZolRI0cObIgjg0AACCwQ9O//vUvefbZZyUkJERCQ0NNHyeH/k5oAgAAxU2+QtMrr7wir776qgwfPrzgjwgAAKC4zNN07NgxefDBBwv+aAAAAIpTaNLAtHTp0kt+8NWrV0uXLl0kLCzMNOvNmzfPa7uO1NOmvho1apjpDKKiokxfKk9//vmn9OzZUypUqCCVKlWSPn36yMmTJ7PML9WmTRspU6aMhIeHy/jx47Mcy9y5c6Vhw4amTLNmzWTx4sWX/PwAAMBl3jxXr149efnll2XdunUmYFxxxRVe259//nmr/Zw6dUoiIiLkySeflPvvvz/Ldg03b7/9tsycOVNq165tHjM6OtpMrKnhRmlgOnz4sCxbtkzOnTsnTzzxhPTr109mz57t/mqXDh06mMAVHx8v27dvN4+nAUvLqbVr10r37t0lLi5O/va3v5n7du3aVTZt2iRNmzbNz0sEAACKmSCXVudcJA0wOe4wKEgOHDhw8QcSFCRffvmlCStKD0troIYOHSovvPCCWXfixAmpXr26zJgxQx555BH54YcfpHHjxrJhwwa58cYbTRmdlfyee+6RX375xdx/2rRp8o9//MPMXq5zSakXX3zR1Grt3r3b3H744YdNgFu4cKH7eG655RYzmacGLRsazipWrGiOUWu9CktkzMeFtm8gUCVN6CXFAe9voOjf3xdz/c5X85xOcpnTkp/AlNNjaNDRGiKHPqlWrVpJYmKiua0/tcbICUxKy5coUUK+//57d5m2bdu6A5PS2qo9e/aYvllOGc/Hcco4j5OdtLQ080J7LgAAoPjKV2gqCs732mnNkie97WzTnzoLuadSpUpJ5cqVvcpktw/Px8ipjOd362Wm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OQMAAP8SEKFJm+V0gkodNedJpwvQbRqMGjZsKEOHDpVu3brJggUL3GVKliwpCxcuND+15ujRRx81wcpzXiedbmDRokWmdikiIsJMPfDBBx8w3QAAAAisPk0ailwuV5b12vF61apVed5fR9ctXrw41zI6s/jmzZsv6TgBAEDxFRA1TQAAAL5GaAIAALBAaAIAALBAaAIAALBAaAIAALBAaAIAALBAaAIAALBAaAIAALBAaAIAALBAaAIAALBAaAIAALBAaAIAALBAaAIAALBAaAIAALBAaAIAALBAaAIAALBAaAIAALBAaAIAALBAaAIAALBAaAIAALBAaAIAALBAaAIAALBAaAIAALBAaAIAALBAaAIAALBAaAIAALBAaAIAALBAaAIAALBAaAIAALBAaAIAALBAaAIAALBAaAIAALBAaAIAALBAaAIAALBAaAIAALBAaAIAAAj00DR69GgJCgryWho2bOjefvbsWenfv79UqVJFrrrqKunWrZscOXLEax+HDh2Szp07S7ly5aRatWoSExMj58+f9yqzcuVKadmypZQuXVrq1asnM2bMKLLnCAAAAoNfhybVpEkTOXz4sHv59ttv3dsGDx4sCxYskLlz58qqVavk119/lfvvv9+9PSMjwwSm9PR0Wbt2rcycOdMEopEjR7rLJCcnmzLt27eXLVu2yKBBg+Spp56Sr7/+usifKwAA8F+lxM+VKlVKQkNDs6w/ceKEfPjhhzJ79my58847zbqPPvpIGjVqJOvWrZNbbrlFli5dKrt27ZLly5dL9erVpUWLFjJu3DgZPny4qcUKDg6W+Ph4qV27tkycONHsQ++vwWzSpEkSHR1d5M8XAAD4J7+vadq7d6+EhYVJnTp1pGfPnqa5TSUlJcm5c+ckKirKXVab7q677jpJTEw0t/Vns2bNTGByaBBKTU2VnTt3ust47sMp4+wjJ2lpaWY/ngsAACi+/Do0tWrVyjSnLVmyRKZNm2aa0tq0aSN//fWXpKSkmJqiSpUqed1HA5JuU/rTMzA5251tuZXREHTmzJkcjy0uLk4qVqzoXsLDwwvseQMAAP/j181znTp1cv/evHlzE6Jq1qwpn376qZQtW9anxxYbGytDhgxx39aQRXACAKD48uuapsy0Vun666+Xffv2mX5O2sH7+PHjXmV09JzTB0p/Zh5N59zOq0yFChVyDWY60k7LeC4AAKD4CqjQdPLkSdm/f7/UqFFDIiMj5YorrpCEhAT39j179pg+T61btza39ef27dvl6NGj7jLLli0zAadx48buMp77cMo4+wAAAPD70PTCCy+YqQQOHjxopgz4n//5HylZsqR0797d9CPq06ePaSJbsWKF6Rj+xBNPmLCjI+dUhw4dTDh67LHHZOvWrWYagREjRpi5nbSmSD3zzDNy4MABGTZsmOzevVveffdd0/yn0xkAAAAERJ+mX375xQSkP/74Q6pWrSq33367mU5Af1c6LUCJEiXMpJY6mk1HvWnocWjAWrhwoTz77LMmTF155ZXSu3dvGTt2rLuMTjewaNEiE5ImT54s1157rXzwwQdMNwAAALwEuVwul/cq5Id2BNfaL50/qjD7N0XGfFxo+wYCVdKEXlIc8P4Giv79fTHXb79ungMAAPAXhCYAAAALhCYAAAALhCYAAAALhCYAAAALhCYAAAALhCYAAAALhCYAAAALhCYAAAALhCYAAAALhCYAAAALhCYAAAALhCYAAAALhCYAAAALhCYAAAALhCYAAAALhCYAAAALhCYAAAALhCYAAAALhCYAAAALhCYAAAALhCYAAAALhCYAAAALhCYAAAALhCYAAAALhCYAAAALhCYAAAALhCYAAAALhCYAAAALhCYAAAALhCYAAAALhCYAAAALhCYAAAALhCYAAAALhCYAAIBAD01xcXFy0003Sfny5aVatWrStWtX2bNnj1eZdu3aSVBQkNfyzDPPeJU5dOiQdO7cWcqVK2f2ExMTI+fPn/cqs3LlSmnZsqWULl1a6tWrJzNmzCiS5wgAAAKDX4emVatWSf/+/WXdunWybNkyOXfunHTo0EFOnTrlVa5v375y+PBh9zJ+/Hj3toyMDBOY0tPTZe3atTJz5kwTiEaOHOkuk5ycbMq0b99etmzZIoMGDZKnnnpKvv766yJ9vgAAwH+VEj+2ZMkSr9sadrSmKCkpSdq2beterzVIoaGh2e5j6dKlsmvXLlm+fLlUr15dWrRoIePGjZPhw4fL6NGjJTg4WOLj46V27doyceJEc59GjRrJt99+K5MmTZLo6OhCfpYAACAQ+HVNU2YnTpwwPytXruy1ftasWRISEiJNmzaV2NhYOX36tHtbYmKiNGvWzAQmhwah1NRU2blzp7tMVFSU1z61jK4HAADw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",
49
+ "text/plain": [
50
+ "<Figure size 640x480 with 1 Axes>"
51
+ ]
52
+ },
53
+ "metadata": {},
54
+ "output_type": "display_data"
55
+ },
56
+ {
57
+ "name": "stdout",
58
+ "output_type": "stream",
59
+ "text": [
60
+ "label\n",
61
+ "1 18743\n",
62
+ "0 17175\n",
63
+ "Name: count, dtype: int64\n"
64
+ ]
65
+ }
66
+ ],
67
+ "source": [
68
+ "import matplotlib.pyplot as plt\n",
69
+ "import seaborn as sns\n",
70
+ "\n",
71
+ "sns.countplot(data=train_df, x=\"label\")\n",
72
+ "plt.title(\"Class Distribution (0 = Fake, 1 = Real)\")\n",
73
+ "plt.show()\n",
74
+ "\n",
75
+ "# Optional: exact counts\n",
76
+ "print(train_df['label'].value_counts())\n"
77
+ ]
78
+ },
79
+ {
80
+ "cell_type": "code",
81
+ "execution_count": 5,
82
+ "metadata": {},
83
+ "outputs": [
84
+ {
85
+ "name": "stdout",
86
+ "output_type": "stream",
87
+ "text": [
88
+ "text 0\n",
89
+ "label 0\n",
90
+ "dtype: int64\n",
91
+ " text label\n",
92
+ "29516 A federal aid package was all set to pass the ... 1\n",
93
+ "26424 MOSCOW (Reuters) - Russia s lower house of par... 0\n",
94
+ "12155 The information below is disturbing and should... 1\n",
95
+ "14098 There are people out there who are giving the... 1\n",
96
+ "21622 CARACAS (Reuters) - Cuba’s main regional ally,... 0\n"
97
+ ]
98
+ }
99
+ ],
100
+ "source": [
101
+ "print(train_df.isnull().sum())\n",
102
+ "\n",
103
+ "# You can also visually inspect\n",
104
+ "print(train_df.sample(5))\n"
105
+ ]
106
+ },
107
+ {
108
+ "cell_type": "code",
109
+ "execution_count": 6,
110
+ "metadata": {},
111
+ "outputs": [
112
+ {
113
+ "data": {
114
+ "image/png": "iVBORw0KGgoAAAANSUhEUgAAAk0AAAHHCAYAAACiOWx7AAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjMsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvZiW1igAAAAlwSFlzAAAPYQAAD2EBqD+naQAAWDtJREFUeJzt3Qd8FHX6x/EnPSEQCC2A0hSUXgRFULCAIPZy97egoiI2OAseCJ4FQcUDUVERTk9FDzzBUxBRKQKKFOmgICAKCioQKQkhvcz/9fySWXaTTbKp2z5vX+Puzk52Z3aX7DfPr0yIZVmWAAAAoEShJd8NAAAARWgCAADwAKEJAADAA4QmAAAADxCaAAAAPEBoAgAA8AChCQAAwAOEJgAAAA8QmgAAADxAaALK4Pbbb5cWLVqU+ef0Z/Rng90vv/wiISEh8sILL1Tbc86YMcM8pz53dX8+qvt4x44da57PW/bv3y/R0dGyatWqCv+b8Sf6mutrXxY33nij/N///V+V7ROqBqEJAen11183v8h69OhR5p/9448/zC/ALVu2iK+68MILpUOHDuKrPv/88zJ/iXjiq6++Mu+rvURFRUlCQoJ5PZ577jn5888/K+V50tLSzP7r8/kaX963cePGmX9z5513nrd3xec9+uij8tFHH8nWrVu9vSsoA0ITAtKsWbPMX7fr1q2Tn376qcyh6emnn3Ybmt58803ZtWtXJe5pYNLQpK9hVXnggQfkP//5j7zxxhsycuRIqVu3rjz11FPStm1bWbZsmcu2t956q6Snp0vz5s3LFEx0/8saTKrj81HSvj3++OPmWL1BA+u7774r9957r8t6/s2417VrV+nevbtMnjzZ27uCMiA0IeDs3btXVq9eLS+++KI0aNDABChP5OTkSFZWVonbREREmOoGvKt3795yyy23yODBg+Xvf/+7fPzxx7JhwwYJCwuT66+/Xg4cOODYVtdpk1FVNlulpqb6xOcjPDzcHKs3zJw50zz/lVde6bLe269JZb6/lU2b5/Sze+LEiSp5fFQ+QhMCjoak+Ph4ufzyy+Uvf/mL29Dk3Nfk5ZdfltNPP938YtdmvbPPPttsc8cddziagbRfTHH9M/Ly8mTKlCnSsWNH84WlQe3SSy81X+IlSUpKkoceekiaNm1qnrtVq1byz3/+0zxeZfniiy9MwIiNjZVatWqZ12T79u0u2+gx1axZU37//Xe55pprzHU9Bg0jubm5LtseOXLEVG7i4uKkTp06JrRo80Lh12jq1KnmunNTWmFaJbJfd33N169fX6Fj7dy5s3kv9XV97bXXSuzTpO/NgAEDpH79+hITEyMtW7aUO++809yn2+nxK63o2PtvNzfar9fPP/8sl112mXldBw0aVGr/nZdeeslUu/T5LrjgAtm2bZvL/drEqEthzo9Z2r6569OkfwyMHz/e8VrrYz322GOSmZnpsp2uv+KKK2TlypVyzjnnmM/yaaedJu+9955Hr/+8efNM05y+NsXtf+F/e2X9DOh7qyH4lVdecaw7fPiwhIaGSr169cSyLMf6++67Txo1auTy8x9++KF069bNvAf63mvw1s994f0t7v3V1+zhhx8274Guv+qqq+S3334rsp8pKSnm37Yetx5bw4YN5ZJLLpFNmza5bKfrNJAtWbKklFcXviLc2zsAVDYNSdddd51ERkbKTTfdJNOmTTO/jO0w5Oydd96RjIwMufvuu80vt2uvvdb8wnvyySfNOg0cqlevXsU+35AhQ8wX88CBA+Wuu+4yX1LffPONfPvtt6b8XlwTi35x6i/se+65R5o1a2aqY2PGjDFVEv3yryhtvtJQo+FAw5g+p74W559/vmzevNnli0zDkW6nX3r6Zfbll1+aZgP9QtMvH6VhTqsI2uSp69q0aSOffPKJeQ5nejzaxKlfBLoP7rz//vvmddZt9Qt04sSJ5j3bs2ePqUyUl4ZkfT8WL14szz77rNttEhMTpX///uaLb/To0Sb86Re5/sWvdL2+TnqM+nnQ/VKdOnVyPIa+x/p66Wupr1eNGjVK3C8NHnq8w4YNM583DdkXX3yxfP/996ZPlqc82bfC9DOpzWb62jzyyCOydu1amTBhguzYsUPmzp3rsq02Zduvob6vb7/9tgkRGjTat29f7HNkZ2ebf2P2Z8UT5fkM6HulfflWrFhhmmiVhjz9+aNHj8oPP/zg2E/9N2j/+1X6b1T/ENLfA3r8hw4dMu+DdlrXfw/62KW9v/paakXt5ptvNr8TtClY/xApTJso//e//8nw4cOlXbt25o8N3U99zc866yzHdnqfBjjdB30/4QcsIIBs2LBB/9S0lixZYm7n5eVZp556qvXggw+6bLd3716zXVxcnJWYmOhy3/r1681977zzTpHH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pgB2omD0XGlTDjj3a6LSBACAe4SmAJZWMHqupgfNcyfnaqLSBACAO4SmAHbCw8ktXWYFp9IEAIBbhKYg6AjuWZ8mRs8BAFASQlMwTDngQWiKsDuCM08TAABuEZoCWFmmHHB0BKfSBACAW4SmAJZWUGkqW/MclSYAANwhNAVFR3BPKk10BAcAoCSEpgBWtsktaZ4DAKAkhKYAlZdnOTqCezLlQERBpYmO4AAA+GFoys3NlSeeeEJatmwpMTExcvrpp8v48ePFsk5WQ/T6k08+KY0bNzbb9OvXT3bv3u3yOEePHpVBgwZJXFyc1KlTR4YMGSInTpxw2ea7776T3r17S3R0tDRt2lQmTpwo/iw9Oz8wKSpNAAAEeGj65z//KdOmTZPXXntNduzYYW5rmHn11Vcd2+jtV155RaZPny5r166V2NhYGTBggGRkZDi20cC0fft2WbJkiSxYsEBWrFghd999t+P+48ePS//+/aV58+ayceNGmTRpkowdO1beeOMN8feRczooLjoitAynUaHSBACAO6WXILxo9erVcvXVV8vll19ubrdo0UL++9//yrp16xxVppdfflkef/xxs5167733JCEhQebNmyc33nijCVsLFy6U9evXS/fu3c02Grouu+wyeeGFF6RJkyYya9YsycrKkrffflsiIyOlffv2smXLFnnxxRddwpVfztEUGS4hIfmByJMT9lJpAgDADytNvXr1kqVLl8qPP/5obm/dulVWrlwpAwcONLf37t0rBw8eNE1yttq1a0uPHj1kzZo15rZeapOcHZiUbh8aGmoqU/Y2ffr0MYHJptWqXbt2ybFjx9zuW2ZmpqlQOS++WGnyZGJLFcEJewEA8N/QNHr0aFMtatOmjUREREjXrl3loYceMs1tSgOT0sqSM71t36eXDRs2dLk/PDxc6tat67KNu8dwfo7CJkyYYAKavWg/qOry0cbf5J7/bHCckLeiE1s6V5qymacJAAD/C01z5swxTWfvv/++bNq0Sd59913TpKaX3jZmzBhJTk52LPv376+2537zmz2yaPshWbYzsdhtUgsClSedwF37NFFpAgDA7/o0jRw50lFtUh07dpRff/3VVHkGDx4sjRo1MusPHTpkRs/Z9HaXLl3Mdd0mMdE1XOTk5JgRdfbP66X+jDP7tr1NYVFRUWbx5qSVOw4clys6NSlmG3u6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tnH3GM7PUdiECRNMQLMXrYhVpZDQamyeo9IEAEDlVJoSExNNFeerr74yVRyVlJRk+h598MEHpu9RZcjLyzMVoueee87c7tq1q5kLSvsdeXs+qDFjxsiIESNcKk1VGpyqs9JU0KcplUoTAAAVqzT97W9/k5SUFNm+fbsZmaaLhhkNDloJqiw6Iq5du3Yu69q2bSv79u0z1xs1amQuDx065LKN3rbv00sNec5ycnLMPjtv4+4xnJ+jsKioKDMaz3mpUmFemHKA0AQAQMVCk3asfv31102AsWm4mTp1qhnlVll05NyuXbtc1v3444/SvHlzR6dwDTVLly513K/BTfsq9ezZ09zWS62CaVOi82letIqlfZ/sbVasWGFG1tl0pJ12bnfXn8krqrF5jo7gAABUUmjSwBERcfJcaDZdp/dVlocffli+/fZb0zz3008/mSkC3njjDRk2bJi5X2fGfuihh+SZZ54xncZ1qoDbbrvNjIi75pprzDYa7C699FLTeXzdunWyatUqGT58uGle1O3UzTffbDqB6/xNWj2bPXu2TJkyxaX5zWemHKjO0XNUmgAAqFhouvjii+XBBx+UP/74w2USSg05ffv2lcpy9tlny9y5c+W///2vdOjQQcaPH2+mGNB5l2yjRo0yzYU6NYBur5NWaiXMeZJNnVKgTZs2Zt90qoHzzz/fhC+bduRevHixGY3XrVs3eeSRR8yEmT4z3UB1N8855mkiNAEAUKGO4K+99ppcddVV0qJFC0fn5/3795tgoyPpKtMVV1xhluJotUnnh9KlODpSzp7IsjidOnWSb775RnwWzXMAAPhfaNKgtGnTJvnyyy9l586djmYw5/mS4MczgtMRHACAijXPaQdq7fCtna21wnPJJZeYpjFdtGlMZ9L26WqNP6vG5jl7ygEqTQAAlDM0aX8i7VDtbni99gu65557zKlHUHXNc+EhlXqO5RKb59KzcyUnt/I69gMA4M/K9A28detWMxKtOHreOeeh/fDX5rn80KRSM3Or/vkAAAi00KQTPrqbasD59CR//vlnZewXCqvO0JSXI5Hh+R+NlMyTc1cBABDMyhSa9IS5OvN3cb777jszizeqQGg1TjkgIrWi8kNaCv2aAAAoe2jSOY6eeOIJycg42XxjS09Pl6eeeqrE6QHgJ5Um7aMWkx/SktOpNAEAUOYpBx5//HH5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tGjRQqKjo6VHjx6ybt068TUrVqyQK6+80symqrOhz5s3z+V+HWug0zg0btxYYmJizEmQd+/e7bKNzqY+aNAgM6GZThI6ZMgQOXHC9Txx3333nfTu3du8Fjpr7MSJE6v82CZMmCBnn3221KpVSxo2bGgmPt21a5fLNhkZGTJs2DAzG3zNmjXl+uuvLzKz/L59++Tyyy+XGjVqmMcZOXKk5OTkuGzz1VdfyVlnnWVGjrRq1UpmzJhR5cc3bdo06dSpk2MyuZ49e8oXX3wREMdW2PPPP28+nw899JDfH9/YsWMLTiZ8cmnTpo3fH5ez33//XW655RZzDPp7o2PHjrJhwwa//72iv88Lv3e66PsVCO9dbm6uPPHEE9KyZUvzvpx++ukyfvx4l/O6+et7Z+88fNQHH3xgRUZGWm+//ba1fft2a+jQoVadOnWsQ4cOWb7k888/t/7xj39YH3/8sTl/z9y5c13uf/75563atWtb8+bNs7Zu3WpdddVVVsuWLa309HTHNpdeeqnVuXNn69tvv7W++eYbq1WrVtZNN93kuD85OdlKSEiwBg0aZG3bts3673//a8XExFj/+te/qvTYBgwYYL3zzjvmObds2WJddtllVrNmzawTJ044trn33nutpk2bWkuXLrU2bNhgnXvuuVavXr0c9+fk5FgdOnSw+vXrZ23evNm8XvXr17fGjBnj2GbPnj1WjRo1rBEjRlg//PCD9eqrr1phYWHWwoULq/T45s+fb3322WfWjz/+aO3atct67LHHrIiICHO8/n5sztatW2e1aNHC6tSpk/Xggw861vvr8em5L9u3b28dOHDAsfz5559+f1y2o0ePWs2bN7duv/12a+3atWZfFi1aZP30009+/3slMTHR5X1bsmSJ+b25fPnygHjvnn32WatevXrWggULrL1791offvihVbNmTWvKlCl+/94pQpMP0xMFDxs2zHE7NzfXatKkiTVhwgTLVxUOTXl5eVajRo2sSZMmOdYlJSVZUVFR5kOu9B+1/tz69esd23zxxRdWSEiIOZGyev311634+HgrMzPTsc2jjz5qnXnmmVZ10l94uq9ff/2141g0ZOgvBtuOHTvMNmvWrDG39ZdaaGiodfDgQcc206ZNs+Li4hzHM2rUKPMl6OyGG24woa266ev873//O2COLSUlxWrdurX5crrgggscocmfj09Dk36huOPPx+X8b/v8888v9v5A+r2in8fTTz/dHFMgvHeXX365deedd7qsu+6660y4CYT3juY5H5WVlSUbN240ZUtbaGioub1mzRrxF3v37jWzqzsfh57jR5sa7ePQSy2/6ulrbLq9Hu/atWsd2/Tp08ecI9A2YMAA01R27Nixajue5ORkc1m3bl1zqe9Rdna2y/FpM0mzZs1cjk+bFpxnltd915NTbt++3bGN82PY21Tne61l9Q8++MCcOkib6QLl2LSpQ5syCu+Dvx+fNmdok/hpp51mmjG0ySYQjkvNnz/f/D7461//apqfunbtKm+++WbA/V7R3/MzZ86UO++80zTRBcJ716tXL3PO1h9//NHc3rp1q6xcuVIGDhwYEO8doclHHT582HyJFT6Fi97WD5y/sPe1pOPQS/3F6Cw8PNwEE+dt3D2G83NUNT2Bs/aHOe+886RDhw6O59Z/tIVP1lz4+Erb9+K20V+E6enpVXpc33//vek7oX0f7r33Xpk7d660a9cuII5NQ+CmTZtM37TC/Pn49AtG+6joaZ60X5p+EWnfDj1Tuz8fl23Pnj3muFq3bi2LFi2S++67Tx544AF59913A+r3ivb/TEpKkttvv93xnP7+3o0ePVpuvPFGE/YiIiJM4NXfmxrsA+G94zQqQBkqFtu2bTN/NQWSM888U7Zs2WKqaP/73//MSau//vpr8Xf79++XBx98UJYsWWI6igYS+692pR35NUQ1b95c5syZYzrW+jv9A0WrDM8995y5rV+8+m9v+vTp5vMZKN566y3zXmrFMFDMmTNHZs2aJe+//760b9/e/G7R0KTHGAjvHZUmH1W/fn0JCwsrMmpCbzdq1Ej8hb2vJR2HXiYmJrrcryNBdPSE8zbuHsP5OaqSno9wwYIFsnz5cjn11FMd6/W5tcSufy0W3rey7Htx2+jIkar+EtS/bHV0Tbdu3UxFpnPnzjJlyhS/PzZt6tDPlY4g0r9SddEw+Morr5jr+lepPx+fM61MnHHGGfLTTz/5/fumdFSVVjudtW3b1tEEGQi/V3799Vf58ssv5a677nKsC4T3buTIkY5qkzYj3nrrrfLwww87qr3+/t4RmnyUfpHpl5i2DTv/9aW3tb+Jv9Bhp/oBdj4OLRFru7R9HHqpvyT0S862bNkyc7z6F7S9jU5toO39Nq0gaJUkPj6+yvZf+7ZrYNImK90nPR5n+h5pCdr5+LRNXX+5Ox+fNoE5/xLQfddfYPYXg27j/Bj2Nt54r/V1z8zM9Ptj69u3r9k3/UvXXrR6oc0E9nV/Pj5nOhT7559/NmHD3983pU3ghaf20D4yWk0LhN8r6p133jFNUNrfzhYI711aWprpe+RMCwD6ugfEe1el3cxR4SkHdETBjBkzzGiCu+++20w54Dxqwhfo6CQd+qqLfqRefPFFc/3XX391DC/V/f7kk0+s7777zrr66qvdDi/t2rWrGV68cuVKM9rJeXipjq7Q4aW33nqrGV6qr40Oqa3q4aX33XefGRr71VdfuQwTTktLc2yjQ4R1GoJly5aZIcI9e/Y0S+Ehwv379zfTFuiw3wYNGrgdIjxy5EgzWmbq1KnVMkR49OjRZiSgDg3W90Zv6wiVxYsX+/2xueM8es6fj++RRx4xn0l931atWmWGn+uwcx3d6c/H5TxFRHh4uBm+vnv3bmvWrFlmX2bOnOnYxp9/r+hIaH1/dLRXYf7+3g0ePNg65ZRTHFMO6FQ0+tnUEX2B8N4Rmnyczq+h/4B0viadgkDnrPA1Or+IhqXCi/7jsYeYPvHEE+YDriGwb9++Zk4gZ0eOHDH/IHQ+Dx06e8cdd5gw5kzn89BhyPoY+o9S/+FVNXfHpYvO3WTTf+j333+/Gf6q/2ivvfZaE6yc/fLLL9bAgQPNPCL6C0S/9LKzs4u8jl26dDHv9WmnnebyHFVFhwbrfDj6nPqLV98bOzD5+7F5Epr89fh0+Hjjxo3N8+m/Bb3tPIeRvx6Xs08//dSEA/333qZNG+uNN95wud+ff6/onFP6e6Tw/gbCe3f8+HHzb0y/t6Kjo81z6zx+zlMD+PN7F6L/q7o6FgAAQGCgTxMAAIAHCE0AAAAeIDQBAAB4gNAEAADgAUITAACABwhNAAAAHiA0AQAAeIDQBAAicuGFF5oTiwJAcQhNALxOz15fq1Ytc1JO5/Op6Xm4NMw4++qrryQkJMSca6266clUJ06caE5qXKNGDXNibT1Pmp5HzPkcWNWBkAdUv3AvPCcAuLjoootMSNqwYYOce+65Zt0333xjTuypJ/LMyMiQ6Ohos3758uXSrFkzOf3008v8PHoChNzcXAkPDy9XYBowYIBs3bpVxo8fb8KSniT122+/lRdeeEG6du0qXbp0KfPjAvAfVJoAeJ2embxx48amimTT61dffbU5K7oGE+f1GrJUZmamPPDAA+Zs8Rqqzj//fFm/fn2RqtQXX3xhziAfFRUlK1eulNTUVLntttukZs2a5nknT55c6j6+/PLL5qzqenb2YcOGmYB02mmnyc0332yCXevWrT3apxkzZkidOnVcHnvevHlmP21jx441j/+f//xHWrRoIbVr15Ybb7xRUlJSzP233367fP311zJlyhTzc7r88ssv5Xz1AXiK0ATAJ2gQ0iqSTa9rE9QFF1zgWJ+enm4Cih2aRo0aJR999JG8++67smnTJmnVqpWpBh09etTlsUePHi3PP/+87NixQzp16iQjR440oeOTTz6RxYsXm3ClP1+SWbNmSb9+/UxFqTBtRoyNjS3TPpVGmx81TC1YsMAsur96DErDUs+ePWXo0KFy4MABszRt2rRMjw+g7AhNAHyCBqFVq1aZfk1aUdm8ebMJTH369HFUoNasWWMqObqtVoumTZsmkyZNkoEDB0q7du3kzTfflJiYGHnrrbdcHnvcuHFyySWXmCa9yMhIc782qfXt21c6duxoAo5zfyp3du/eLW3atClxm7LsU2ny8vJMVapDhw7Su3dvufXWW02VS2nlSY9D+1VpE6YuYWFhZXp8AGVHaALgE7SqpKFDm7K0P9MZZ5whDRo0MMHJ7tek4UmbxLRPk1ZitPO19i1yrvicc845pqLkrHv37o7r+nPaP6lHjx6OdXXr1jVNhKX1hypNWfapNNosp53jbdqMmJiYWKbHAFC56AgOwCdoM9app55qmuKOHTtmwpJq0qSJaXpavXq1ue/iiy8u82PbTWcVoSFu586dFX6c0NDQIgHM3cg7DVvOtN+SVp8AeA+VJgA+Q5vdtJqki/NUA9pEp525161b5+jPZDe1aZOec/jQSpU2ixVHf04DiVavbBrSfvzxxxL3TTt8f/nll6bZsDB9Xq2SebJPWj3T5kfd3rZlyxYpK30eHQkIoPoQmgD4DA1EOrpNQ4RdaVJ6/V//+pdpVrNDk1aP7rvvPtOpe+HChfLDDz+YjtFpaWkyZMiQYp9DR8zp/fpzy5Ytk23btpnRaFoBKonOiaTNbtoPaurUqWbqgT179sicOXPMNAna58mTfdJmQe2L9Nhjj5nmvPfff9/0XSorbb7T4Kej5g4fPkwVCqgGNM8B8BkaiHSEnHa4TkhIcAlNWp2xpyaw6WgyDQvaSVrv175LixYtkvj4+BKfRztq67xQV155pek39Mgjj0hycnKJP6PTFSxZskReeuklE+D+/ve/m/DTtm1bM8WAdtj2ZJ+0/9TMmTNNsNJO4hrCdIqBu+++u0yvlT7/4MGDTQVLX7O9e/eaIAWg6oRYnvRuBAAACHI0zwEAAHiA0AQAAOABQhMAAIAHCE0AAAAeIDQBAAB4gNAEAADgAUITAACABwhNAAAAHiA0AQAAeIDQBAAA4AFCEwAAgAcITQAAAFK6/wcBlJmtQProtAAAAABJRU5ErkJggg==",
115
+ "text/plain": [
116
+ "<Figure size 640x480 with 1 Axes>"
117
+ ]
118
+ },
119
+ "metadata": {},
120
+ "output_type": "display_data"
121
+ }
122
+ ],
123
+ "source": [
124
+ "# Add new column for text length\n",
125
+ "train_df['text_length'] = train_df['text'].apply(lambda x: len(x.split()))\n",
126
+ "\n",
127
+ "# Plot distribution\n",
128
+ "sns.histplot(train_df['text_length'], bins=50, kde=True)\n",
129
+ "plt.title(\"Article Length Distribution (in words)\")\n",
130
+ "plt.xlabel(\"Word Count\")\n",
131
+ "plt.show()\n"
132
+ ]
133
+ },
134
+ {
135
+ "cell_type": "code",
136
+ "execution_count": 7,
137
+ "metadata": {},
138
+ "outputs": [
139
+ {
140
+ "name": "stdout",
141
+ "output_type": "stream",
142
+ "text": [
143
+ "Min: 0\n",
144
+ "Max: 8135\n",
145
+ "Mean: 404.48017706999275\n"
146
+ ]
147
+ }
148
+ ],
149
+ "source": [
150
+ "print(\"Min:\", train_df['text_length'].min())\n",
151
+ "print(\"Max:\", train_df['text_length'].max())\n",
152
+ "print(\"Mean:\", train_df['text_length'].mean())\n"
153
+ ]
154
+ }
155
+ ],
156
+ "metadata": {
157
+ "kernelspec": {
158
+ "display_name": "venv",
159
+ "language": "python",
160
+ "name": "python3"
161
+ },
162
+ "language_info": {
163
+ "codemirror_mode": {
164
+ "name": "ipython",
165
+ "version": 3
166
+ },
167
+ "file_extension": ".py",
168
+ "mimetype": "text/x-python",
169
+ "name": "python",
170
+ "nbconvert_exporter": "python",
171
+ "pygments_lexer": "ipython3",
172
+ "version": "3.12.2"
173
+ }
174
+ },
175
+ "nbformat": 4,
176
+ "nbformat_minor": 2
177
+ }
requirements.txt ADDED
@@ -0,0 +1,73 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ aiohappyeyeballs==2.6.1
2
+ aiohttp==3.12.6
3
+ aiosignal==1.3.2
4
+ altair==5.5.0
5
+ attrs==25.3.0
6
+ blinker==1.9.0
7
+ cachetools==5.5.2
8
+ certifi==2025.4.26
9
+ charset-normalizer==3.4.2
10
+ click==8.2.1
11
+ colorama==0.4.6
12
+ contourpy==1.3.2
13
+ cycler==0.12.1
14
+ datasets==3.6.0
15
+ dill==0.3.8
16
+ filelock==3.18.0
17
+ fonttools==4.58.1
18
+ frozenlist==1.6.0
19
+ fsspec==2025.3.0
20
+ gitdb==4.0.12
21
+ GitPython==3.1.44
22
+ huggingface-hub==0.32.3
23
+ idna==3.10
24
+ Jinja2==3.1.6
25
+ joblib==1.5.1
26
+ jsonschema==4.24.0
27
+ jsonschema-specifications==2025.4.1
28
+ kiwisolver==1.4.8
29
+ MarkupSafe==3.0.2
30
+ matplotlib==3.10.3
31
+ mpmath==1.3.0
32
+ multidict==6.4.4
33
+ multiprocess==0.70.16
34
+ narwhals==1.41.0
35
+ networkx==3.5
36
+ numpy==2.2.6
37
+ packaging==24.2
38
+ pandas==2.2.3
39
+ pillow==11.2.1
40
+ propcache==0.3.1
41
+ protobuf==6.31.1
42
+ pyarrow==20.0.0
43
+ pydeck==0.9.1
44
+ pyparsing==3.2.3
45
+ python-dateutil==2.9.0.post0
46
+ pytz==2025.2
47
+ PyYAML==6.0.2
48
+ referencing==0.36.2
49
+ regex==2024.11.6
50
+ requests==2.32.3
51
+ rpds-py==0.25.1
52
+ safetensors==0.5.3
53
+ scikit-learn==1.6.1
54
+ scipy==1.15.3
55
+ setuptools==80.9.0
56
+ six==1.17.0
57
+ smmap==5.0.2
58
+ streamlit==1.45.1
59
+ sympy==1.14.0
60
+ tenacity==9.1.2
61
+ threadpoolctl==3.6.0
62
+ tokenizers==0.21.1
63
+ toml==0.10.2
64
+ torch==2.7.0
65
+ tornado==6.5.1
66
+ tqdm==4.67.1
67
+ transformers==4.52.4
68
+ typing_extensions==4.13.2
69
+ tzdata==2025.2
70
+ urllib3==2.4.0
71
+ watchdog==6.0.0
72
+ xxhash==3.5.0
73
+ yarl==1.20.0
scripts/evaluate.py ADDED
@@ -0,0 +1,29 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from datasets import load_dataset
2
+ from transformers import (AutoTokenizer, AutoModelForSequenceClassification,
3
+ TrainingArguments, Trainer)
4
+ # Reload dataset and tokenizer
5
+ dataset = load_dataset("liar")
6
+ dataset = dataset["train"].train_test_split(test_size=0.2, seed=42)
7
+
8
+ def simplify_label(example):
9
+ name = dataset["train"].features["label"].names[ example["label"] ]
10
+ example["label"] = int(name in ["pants‑fire","false","barely‑true"])
11
+ return example
12
+
13
+ dataset = dataset.map(simplify_label)
14
+
15
+ tokenizer = AutoTokenizer.from_pretrained("bert-base-uncased")
16
+ # Tokenize the text field (can try combining title + text later for improved performance):
17
+ def tokenize(example):
18
+ return tokenizer(example["statement"], truncation=True, padding="max_length", max_length=128)
19
+ # Tokenize the dataset
20
+ tokenized_dataset = dataset.map(tokenize, batched=True)
21
+ tokenized_dataset.set_format("torch", columns=["input_ids", "attention_mask", "label"])
22
+ # Load model
23
+ model = AutoModelForSequenceClassification.from_pretrained("models/bert-liar-fake-news")
24
+ # Set up Trainer for evaluation
25
+ training_args = TrainingArguments(output_dir="./results", per_device_eval_batch_size=8)
26
+ trainer = Trainer(model=model, args=training_args)
27
+ # Evaluate
28
+ metrics = trainer.evaluate(eval_dataset=tokenized_dataset["test"])
29
+ print(metrics)
scripts/predict.py ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from transformers import pipeline
2
+ # Load the classifier
3
+ classifier = pipeline("text-classification", model="models/bert-liar-fake-news", tokenizer="bert-base-uncased")
4
+ # Define the predict function
5
+ def predict(text):
6
+ result = classifier(text)
7
+ label = result[0]['label']
8
+ score = result[0]['score']
9
+ return label, score
10
+ # Example usage
11
+ if __name__ == "__main__":
12
+ text = input("Enter a statement to evaluate:\n")
13
+ label, score = predict(text)
14
+ print(f"Prediction: {label} (Confidence: {score:.2f})")
scripts/train.py ADDED
@@ -0,0 +1,54 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from datasets import load_dataset
2
+ from transformers import (AutoTokenizer, AutoModelForSequenceClassification,
3
+ TrainingArguments, Trainer)
4
+ # Get
5
+ # dataset['train'] — 80%
6
+ # dataset['test'] — 20%
7
+ dataset = load_dataset("liar")
8
+ dataset = dataset["train"].train_test_split(test_size=0.2, seed=42)
9
+
10
+ def simplify_label(example):
11
+ name = dataset["train"].features["label"].names[ example["label"] ]
12
+ example["label"] = int(name in ["pants‑fire","false","barely‑true"])
13
+ return example
14
+
15
+ dataset = dataset.map(simplify_label)
16
+
17
+ # Load the tokenizer
18
+ tokenizer = AutoTokenizer.from_pretrained("bert-base-uncased")
19
+
20
+ # Tokenize the text field (could also try combining title + text later for improved performance):
21
+ def tokenize(example):
22
+ return tokenizer(example["statement"], truncation=True, padding="max_length", max_length=128)
23
+
24
+ tokenized_dataset = dataset.map(tokenize, batched=True)
25
+ # Set the format to torch and specify the columns to include
26
+ tokenized_dataset.set_format("torch", columns=["input_ids", "attention_mask", "label"])
27
+ # Load the model
28
+ model = AutoModelForSequenceClassification.from_pretrained("bert-base-uncased", num_labels=2)
29
+
30
+ # Define the training arguments
31
+ training_args = TrainingArguments(
32
+ output_dir="./results",
33
+ eval_strategy="epoch",
34
+ save_strategy="epoch",
35
+ num_train_epochs=3,
36
+ per_device_train_batch_size=8,
37
+ per_device_eval_batch_size=8,
38
+ learning_rate=2e-5,
39
+ weight_decay=0.01,
40
+ )
41
+ # Initialize the Trainer
42
+ trainer = Trainer(
43
+ model=model,
44
+ args=training_args,
45
+ train_dataset=tokenized_dataset["train"],
46
+ eval_dataset=tokenized_dataset["test"],
47
+ )
48
+ # Train the model
49
+ trainer.train()
50
+ # Evaluate the model
51
+ trainer.save_model("models/bert-liar-fake-news")
52
+
53
+
54
+
scripts/utils.py ADDED
File without changes