Upload 3 files
Browse files- .huggingface.yaml +2 -0
- app.py +106 -0
- requirements.txt +4 -0
.huggingface.yaml
ADDED
@@ -0,0 +1,2 @@
|
|
|
|
|
|
|
1 |
+
sdk: gradio
|
2 |
+
python_version: "3.10"
|
app.py
ADDED
@@ -0,0 +1,106 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
|
2 |
+
import requests
|
3 |
+
from collections import Counter
|
4 |
+
from transformers import pipeline, AutoTokenizer, AutoModelForSequenceClassification
|
5 |
+
import re
|
6 |
+
import gradio as gr
|
7 |
+
|
8 |
+
# β
Load Roberta fake news model
|
9 |
+
model_name = "hamzab/roberta-fake-news-classification"
|
10 |
+
tokenizer = AutoTokenizer.from_pretrained(model_name)
|
11 |
+
model = AutoModelForSequenceClassification.from_pretrained(model_name)
|
12 |
+
classifier = pipeline("text-classification", model=model, tokenizer=tokenizer)
|
13 |
+
|
14 |
+
# β
API Keys
|
15 |
+
GOOGLE_API_KEY = "AIzaSyCKnDlhWih34GdCuheNusnrEw_YE_q6GWQ"
|
16 |
+
NEWSAPI_KEY = "fcb304918fce4fb29b17b6c95dbc7518"
|
17 |
+
|
18 |
+
# β
Keyword extractor
|
19 |
+
def extract_keywords(text, max_words=5):
|
20 |
+
words = re.findall(r'\b\w+\b', text.lower())
|
21 |
+
stopwords = {"the", "and", "is", "in", "to", "of", "a", "on", "for", "with", "as", "by", "at", "an", "be", "are", "from", "this", "it", "that"}
|
22 |
+
filtered = [w for w in words if w not in stopwords and len(w) > 2]
|
23 |
+
return " ".join([w for w, _ in Counter(filtered).most_common(max_words)])
|
24 |
+
|
25 |
+
# β
Google Fact Check
|
26 |
+
def check_google_fact_check(query):
|
27 |
+
try:
|
28 |
+
response = requests.get("https://factchecktools.googleapis.com/v1alpha1/claims:search", params={"query": query, "key": GOOGLE_API_KEY}).json()
|
29 |
+
if "claims" in response and response["claims"]:
|
30 |
+
result = ""
|
31 |
+
for claim in response["claims"][:3]:
|
32 |
+
text = claim.get("text", "")
|
33 |
+
review = claim.get("claimReview", [{}])[0]
|
34 |
+
rating = review.get("textualRating", "Unrated")
|
35 |
+
source = review.get("publisher", {}).get("name", "Unknown")
|
36 |
+
url = review.get("url", "")
|
37 |
+
result += f"β
Claim: {text}\nπ Verdict: {rating}\nπ° Source: {source}\nπ {url}\n\n"
|
38 |
+
return result.strip()
|
39 |
+
return None
|
40 |
+
except Exception as e:
|
41 |
+
return f"β Google API error: {e}"
|
42 |
+
|
43 |
+
# β
NewsAPI fallback
|
44 |
+
def search_newsapi(query):
|
45 |
+
try:
|
46 |
+
response = requests.get("https://newsapi.org/v2/everything", params={
|
47 |
+
"q": query, "apiKey": NEWSAPI_KEY, "language": "en", "sortBy": "relevancy", "pageSize": 3
|
48 |
+
}).json()
|
49 |
+
if response.get("status") != "ok":
|
50 |
+
return f"β NewsAPI error: {response.get('message')}"
|
51 |
+
articles = response.get("articles", [])
|
52 |
+
if not articles:
|
53 |
+
return "βΉοΈ No similar real news articles found."
|
54 |
+
output = "π° No official fact-check found.\n\nBut here are similar real news articles:\n\n"
|
55 |
+
for article in articles:
|
56 |
+
title = article.get("title", "No title")
|
57 |
+
source = article.get("source", {}).get("name", "Unknown")
|
58 |
+
url = article.get("url", "#")
|
59 |
+
output += f"β’ π° Source: {source}\n π Title: {title}\n π {url}\n\n"
|
60 |
+
return output.strip()
|
61 |
+
except Exception as e:
|
62 |
+
return f"β NewsAPI error: {e}"
|
63 |
+
|
64 |
+
# β
Chatbot logic
|
65 |
+
def fake_news_chatbot(message, history):
|
66 |
+
try:
|
67 |
+
prediction = classifier(message)[0]
|
68 |
+
label = prediction['label']
|
69 |
+
confidence = round(prediction['score'], 2)
|
70 |
+
|
71 |
+
if confidence < 0.7:
|
72 |
+
verdict = "π‘ UNSURE"
|
73 |
+
elif label == "FAKE":
|
74 |
+
verdict = "π₯ FAKE"
|
75 |
+
else:
|
76 |
+
verdict = "π© REAL"
|
77 |
+
|
78 |
+
ml_result = f"π ML Prediction: {verdict}\nπ’ Confidence: {confidence}"
|
79 |
+
|
80 |
+
keywords = extract_keywords(message)
|
81 |
+
fact_result = check_google_fact_check(keywords)
|
82 |
+
if fact_result:
|
83 |
+
return f"{ml_result}\n\nπ Keywords Used: {keywords}\n\n{fact_result}"
|
84 |
+
|
85 |
+
newsapi_result = search_newsapi(keywords)
|
86 |
+
if "π° Source:" in newsapi_result and verdict == "π₯ FAKE":
|
87 |
+
ml_result += " β οΈ ML says FAKE but similar real news found"
|
88 |
+
elif "No similar" in newsapi_result and verdict == "π© REAL":
|
89 |
+
ml_result += " β οΈ ML says REAL but no matching news found"
|
90 |
+
|
91 |
+
return f"{ml_result}\n\nπ Keywords Used: {keywords}\n\n{newsapi_result}"
|
92 |
+
|
93 |
+
except Exception as e:
|
94 |
+
return f"β Error: {str(e)}"
|
95 |
+
|
96 |
+
# β
Launch Chatbot
|
97 |
+
gr.ChatInterface(
|
98 |
+
fn=fake_news_chatbot,
|
99 |
+
title="π§ Fake News Detection Chatbot",
|
100 |
+
description="Ask me if a news item is real or fake. Iβll use an ML model + Google Fact Check + NewsAPI!",
|
101 |
+
examples=[
|
102 |
+
"The Prime Minister announced a new moon mission",
|
103 |
+
"Aliens landed in New York yesterday",
|
104 |
+
"COVID vaccine turns you into a lizard"
|
105 |
+
],
|
106 |
+
).launch()
|
requirements.txt
ADDED
@@ -0,0 +1,4 @@
|
|
|
|
|
|
|
|
|
|
|
1 |
+
transformers
|
2 |
+
gradio
|
3 |
+
torch
|
4 |
+
requests
|