a77an commited on
Commit
f4b426e
·
verified ·
1 Parent(s): 1fbf2ee

Upload 2 files

Browse files
Files changed (2) hide show
  1. templates/app.py +107 -0
  2. templates/index.html +200 -0
templates/app.py ADDED
@@ -0,0 +1,107 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import torch
2
+ import pandas as pd
3
+ import re
4
+ from flask import Flask, render_template, request, jsonify
5
+ from transformers import AutoTokenizer, AutoModelForSequenceClassification
6
+ from sklearn.metrics import classification_report
7
+ import io
8
+ import sys
9
+
10
+ # Define model names
11
+ bert_model_name = "bert-base-uncased"
12
+ hatebert_model_name = "GroNLP/hateBERT"
13
+
14
+ # Initialize Flask app
15
+ app = Flask(__name__)
16
+
17
+ class CyberbullyingDetector:
18
+ def __init__(self, model_type="bert"):
19
+ if model_type == "bert":
20
+ self.tokenizer = AutoTokenizer.from_pretrained(bert_model_name)
21
+ self.model = AutoModelForSequenceClassification.from_pretrained(bert_model_name)
22
+ elif model_type == "hatebert":
23
+ self.tokenizer = AutoTokenizer.from_pretrained(hatebert_model_name)
24
+ self.model = AutoModelForSequenceClassification.from_pretrained(hatebert_model_name)
25
+ else:
26
+ raise ValueError("Invalid model_type. Choose 'bert' or 'hatebert'.")
27
+
28
+ self.device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
29
+ self.model.to(self.device)
30
+
31
+ self.cyberbullying_threshold = 0.7
32
+ self.borderline_threshold = 0.4
33
+ self.trigger_words = [
34
+ 'buang', 'pokpok', 'bogo', 'linte', 'tanga', 'diputa', 'salamat', 'Padayon lang', 'mayo gid', 'Nagapasalamat',
35
+ 'gago', 'law-ay', 'bilatibay', 'yudipota', 'pangit', 'tikalon', 'tinikal', 'hambog',
36
+ 'batinggilan', 'biga-on', 'bulay-ug', 'agi', 'agitot', 'alpot', 'hangag'
37
+ ]
38
+
39
+ def find_triggers(self, text):
40
+ text_lower = text.lower()
41
+ return [word for word in self.trigger_words if word in text_lower]
42
+
43
+ def predict(self, text):
44
+ triggers = self.find_triggers(text)
45
+
46
+ inputs = self.tokenizer(
47
+ text,
48
+ return_tensors="pt",
49
+ truncation=True,
50
+ max_length=128,
51
+ padding=True
52
+ ).to(self.device)
53
+
54
+ with torch.no_grad():
55
+ outputs = self.model(**inputs)
56
+
57
+ probs = torch.nn.functional.softmax(outputs.logits, dim=1)
58
+ pred_class = torch.argmax(probs).item()
59
+ confidence = probs[0][pred_class].item()
60
+
61
+ if confidence >= self.cyberbullying_threshold or (pred_class == 1) or (len(triggers) > 0):
62
+ label = "Cyberbullying"
63
+ is_cyberbullying = True
64
+ elif confidence >= self.borderline_threshold:
65
+ label = "Borderline"
66
+ is_cyberbullying = False
67
+ else:
68
+ label = "Safe"
69
+ is_cyberbullying = False
70
+
71
+ return {
72
+ "text": text,
73
+ "label": label,
74
+ "confidence": confidence,
75
+ "language": "hil",
76
+ "triggers": triggers,
77
+ "is_cyberbullying": is_cyberbullying
78
+ }
79
+
80
+ # Initialize the detector
81
+ detector = CyberbullyingDetector(model_type="bert")
82
+
83
+ @app.route('/')
84
+ def index():
85
+ return render_template('index.html', classification_report="Loading...")
86
+
87
+ @app.route('/predict', methods=['POST'])
88
+ def predict():
89
+ data = request.get_json()
90
+ text = data.get('text', '')
91
+
92
+ if not text:
93
+ return jsonify({"error": "No text provided"}), 400
94
+
95
+ # Make prediction using the model
96
+ result = detector.predict(text)
97
+
98
+ # Generate the classification report
99
+ true_labels = ["Cyberbullying" if "cyberbullying" in text else "Safe" for text in [text]]
100
+ predicted_labels = [result['label']]
101
+ report = classification_report(true_labels, predicted_labels, zero_division=0)
102
+
103
+ # Render the template with the classification report
104
+ return render_template('index.html', classification_report=report)
105
+
106
+ if __name__ == '__main__':
107
+ app.run(debug=True)
templates/index.html ADDED
@@ -0,0 +1,200 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
6
+ <title>Cyberbullying Detection</title>
7
+ <style>
8
+ * {
9
+ box-sizing: border-box;
10
+ }
11
+
12
+ body {
13
+ margin: 0;
14
+ font-family: Arial, sans-serif;
15
+ background-color: black;
16
+ color: white;
17
+ display: flex;
18
+ flex-direction: column;
19
+ min-height: 100vh;
20
+ }
21
+
22
+ header {
23
+ background-color: #000;
24
+ color: red;
25
+ padding: 15px 20px;
26
+ font-size: 24px;
27
+ text-align: center;
28
+ }
29
+
30
+ main {
31
+ flex: 1;
32
+ display: flex;
33
+ justify-content: center;
34
+ align-items: center;
35
+ padding: 20px;
36
+ }
37
+
38
+ .container {
39
+ width: 100%;
40
+ max-width: 700px;
41
+ background-color: #1e1e1e;
42
+ padding: 30px;
43
+ border-radius: 8px;
44
+ box-shadow: 0 4px 8px rgba(255, 255, 255, 0.1);
45
+ }
46
+
47
+ h1 {
48
+ text-align: center;
49
+ margin-top: 0;
50
+ color: #fff;
51
+ }
52
+
53
+ textarea {
54
+ width: 100%;
55
+ height: 150px;
56
+ padding: 10px;
57
+ margin: 10px 0;
58
+ border-radius: 5px;
59
+ border: 1px solid #ccc;
60
+ font-family: Arial, sans-serif;
61
+ resize: vertical;
62
+ }
63
+
64
+ .button-group {
65
+ display: flex;
66
+ justify-content: space-between;
67
+ gap: 10px;
68
+ }
69
+
70
+ button {
71
+ padding: 10px 20px;
72
+ font-size: 16px;
73
+ background-color: #4CAF50;
74
+ color: white;
75
+ border: none;
76
+ border-radius: 5px;
77
+ cursor: pointer;
78
+ width: 48%;
79
+ }
80
+
81
+ #clearBtn {
82
+ background-color: #f44336;
83
+ }
84
+
85
+ button:hover {
86
+ opacity: 0.9;
87
+ }
88
+
89
+ #result {
90
+ margin-top: 20px;
91
+ display: none;
92
+ }
93
+
94
+ #error {
95
+ color: #f44336;
96
+ margin-top: 10px;
97
+ }
98
+
99
+ footer {
100
+ background-color: #000;
101
+ color: red;
102
+ text-align: center;
103
+ padding: 10px 0;
104
+ }
105
+ </style>
106
+ </head>
107
+ <body>
108
+
109
+ <header>
110
+ Paculan & Coloso
111
+ </header>
112
+
113
+ <main>
114
+ <div class="container">
115
+ <h1>Cyberbullying Detection</h1>
116
+ <form id="predictionForm" method="post">
117
+ <textarea id="inputText" placeholder="Enter text here..."></textarea>
118
+ <div class="button-group">
119
+ <button type="submit">Get Prediction</button>
120
+ <button type="button" id="clearBtn">Clear</button>
121
+ </div>
122
+ </form>
123
+
124
+ <!-- Error message section -->
125
+ <div id="error"></div>
126
+
127
+ <!-- Prediction result section -->
128
+ <div id="result">
129
+ <h3>Prediction Result:</h3>
130
+ <p id="prediction"></p>
131
+ <p id="confidence"></p>
132
+ <p id="triggers"></p>
133
+ </div>
134
+ </div>
135
+ </main>
136
+
137
+ <footer>
138
+ &copy; 2025 Paculan & Coloso Research Worx.
139
+ </footer>
140
+
141
+ <script>
142
+ const form = document.getElementById('predictionForm');
143
+ const inputText = document.getElementById('inputText');
144
+ const predictionEl = document.getElementById('prediction');
145
+ const confidenceEl = document.getElementById('confidence');
146
+ const triggersEl = document.getElementById('triggers');
147
+ const resultBox = document.getElementById('result');
148
+ const errorBox = document.getElementById('error');
149
+
150
+ // Handle form submission
151
+ form.addEventListener('submit', function(e) {
152
+ e.preventDefault();
153
+ const text = inputText.value.trim();
154
+
155
+ if (!text) {
156
+ errorBox.textContent = "Please enter text before submitting.";
157
+ resultBox.style.display = "none";
158
+ return;
159
+ }
160
+
161
+ // Clear previous error messages
162
+ errorBox.textContent = "";
163
+
164
+ // Fetch prediction from Flask backend
165
+ fetch('http://127.0.0.1:5000/predict', {
166
+ method: 'POST',
167
+ headers: { 'Content-Type': 'application/json' },
168
+ body: JSON.stringify({ text: text })
169
+ })
170
+ .then(response => {
171
+ if (!response.ok) throw new Error("Server error");
172
+ return response.json();
173
+ })
174
+ .then(data => {
175
+ // Update the result section
176
+ predictionEl.textContent = "Label: " + data.label;
177
+ confidenceEl.textContent = "Confidence: " + data.confidence;
178
+ triggersEl.textContent = "Detected Triggers: " + (data.triggers.length ? data.triggers.join(', ') : "None");
179
+ resultBox.style.display = "block";
180
+ })
181
+ .catch(error => {
182
+ errorBox.textContent = "Something went wrong. Please try again.";
183
+ console.error(error);
184
+ resultBox.style.display = "none";
185
+ });
186
+ });
187
+
188
+ // Handle clearing the form
189
+ document.getElementById('clearBtn').addEventListener('click', function () {
190
+ inputText.value = '';
191
+ predictionEl.textContent = '';
192
+ confidenceEl.textContent = '';
193
+ triggersEl.textContent = '';
194
+ resultBox.style.display = 'none';
195
+ errorBox.textContent = '';
196
+ });
197
+ </script>
198
+
199
+ </body>
200
+ </html>