News_Classifier / app.py
Mpavan45's picture
Update app.py
83d3123 verified
import streamlit as st
import numpy as np
import re
import emoji
import nltk
from nltk.tokenize import word_tokenize
from nltk.corpus import stopwords
from nltk.stem import WordNetLemmatizer
import tensorflow as tf
import keras
from keras.utils import pad_sequences
import pickle
import os
# Streamlit UI
st.set_page_config(page_title="PressGuard", page_icon="🛡️")
# Radium color effect for the title
st.markdown("""
<style>
.radium {
font-size: 60px;
font-weight: bold;
color: #f4ff81; /* Radium-like light greenish-yellow color */
text-shadow: 0 0 5px #f4ff81, 0 0 10px #f4ff81, 0 0 20px #f4ff81, 0 0 30px #e8ff94;
text-align: center;
}
.tagline {
font-size: 20px;
color: #ffffff;
text-align: center;
margin-bottom: 30px;
}
</style>
<div class='radium'>🛡️ PressGuard</div>
""", unsafe_allow_html=True)
# st.markdown(
# """
# <img src="https://cdn-uploads.huggingface.co/production/uploads/675fab3a2d0851e23d23cad3/ut9wBSlRR2CCpw95V5ej8.jpeg" width="100%" />
# """,
# unsafe_allow_html=True
# )
# Apply custom CSS for the background image and overlay
background_image_url="https://cdn-uploads.huggingface.co/production/uploads/675fab3a2d0851e23d23cad3/yiXBcm5bq8gcMoaMRSYEv.webp"
st.markdown(
f"""
<style>
.stApp {{
background-image: url("{background_image_url}");
background-size: auto; /* Ensure the image width is 100% of the screen, and the height scales proportionally */
background-repeat: repeat; /* Repeat only vertically */
background-position: top center; /* Start repeating from the top center */
background-attachment: fixed; /* Keeps the background fixed as you scroll */
height: 100%;
}}
/* Semi-transparent overlay */
.stApp::before {{
content: "";
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.4); /* Adjust transparency here (0.4 for 40% transparency) */
z-index: -1;
}}
/* Container to center elements and limit width */
.content-container {{
max-width: 70%; /* Limit content width to 70% */
margin: 0 auto; /* Center the container */
padding: 50px; /* Add some padding for spacing */
}}
/* Styling the markdown content */
.stMarkdown {{
color: white; /* White text to ensure visibility */
font-size: 100px; /* Adjust font size for readability */
}}
</style>
""",
unsafe_allow_html=True
)
# Background Image and Enhanced Styling
st.markdown(
"""
<style>
.centered-container {
text-align: center;
}
.title {
font-size: 60px;
font-weight: bold;
color: white;
background: linear-gradient(60deg, #880E4F, #4A235A, #311B92, #000000);
padding: 20px;
border-radius: 20px;
box-shadow: 0 8px 25px rgba(136, 14, 79, 0.5),
0 4px 15px rgba(74, 35, 90, 0.6),
inset 0 2px 10px rgba(49, 27, 146, 0.4);
display: inline-block;
margin-bottom: 20px;
animation: elegantFadeSlide 1.5s ease-out forwards;
}
.prompt-box {
font-size: 22px;
font-weight: bold;
color: white;
text-align: center;
background: linear-gradient(135deg, #33ccff, #ff99cc, #33ff99, #ffcc00);
background-size: 400% 400%;
animation: gradientAnimation 8s ease infinite;
padding: 15px;
border-radius: 15px;
box-shadow: 0 0 15px rgba(255, 255, 255, 0.7),
0 0 25px rgba(136, 14, 79, 0.7),
0 0 35px rgba(49, 27, 146, 0.7);
transition: all 0.4s ease-in-out;
}
.prompt-box:hover {
transform: scale(1.05) rotate(1deg);
box-shadow: 0 0 25px rgba(255, 255, 255, 0.9),
0 0 35px rgba(136, 14, 79, 0.9),
0 0 45px rgba(49, 27, 146, 0.9);
}
@keyframes gradientAnimation {
0% { background-position: 0% 50%; }
50% { background-position: 100% 50%; }
100% { background-position: 0% 50%; }
}
.analyze-button {
width: 180px;
height: 60px;
border-radius: 50px;
background: linear-gradient(45deg, #880E4F, #4A235A, #311B92, #000000);
font-size: 20px;
font-weight: bold;
color: white;
border: none;
box-shadow: 0 8px 25px rgba(136, 14, 79, 0.5),
0 4px 15px rgba(74, 35, 90, 0.6),
0 2px 10px rgba(49, 27, 146, 0.7),
inset 0 1px 5px rgba(0, 0, 0, 0.4);
cursor: pointer;
transition: all 0.4s ease-in-out;
}
.analyze-button:hover {
transform: scale(1.1);
background: linear-gradient(225deg, #880E4F, #4A235A, #311B92, #000000);
box-shadow: 0 12px 35px rgba(49, 27, 146, 0.8),
0 8px 25px rgba(74, 35, 90, 0.7),
0 4px 15px rgba(136, 14, 79, 0.6);
}
.result-box {
font-size: 22px;
font-weight: bold;
color: white;
text-align: center;
background: linear-gradient(135deg, #6a11cb, #2575fc, #ff6a00, #ffcc00);
background-size: 400% 400%;
animation: gradientAnimation 6s ease infinite;
padding: 20px;
border-radius: 12px;
box-shadow: 0 0 15px rgba(0, 0, 0, 0.5),
0 0 25px rgba(255, 105, 180, 0.7),
0 0 35px rgba(0, 191, 255, 0.7);
transition: all 0.4s ease-in-out;
}
.result-box:hover {
transform: scale(1.08) rotate(1deg);
box-shadow: 0 0 25px rgba(0, 0, 0, 0.7),
0 0 35px rgba(255, 105, 180, 0.9),
0 0 45px rgba(0, 191, 255, 0.9);
}
@keyframes gradientAnimation {
0% {
background-position: 0% 50%;
}
50% {
background-position: 100% 50%;
}
100% {
background-position: 0% 50%;
}
}
</style>
""",
unsafe_allow_html=True
)
# Title and Prompt
st.markdown("<div class='prompt-box'>Paste the article content below to analyze its category with PressGuard🛡️</div>", unsafe_allow_html=True)
# Download necessary resources
nltk.download('punkt_tab')
nltk.download('stopwords')
nltk.download('wordnet')
# Initialize stopwords and lemmatizer
stop_words = set(stopwords.words('english')).union({"pm"})
lemmatizer = WordNetLemmatizer()
# ✅ Preprocessing Function
def pre_process(x):
x = x.lower()
x = re.sub("<.*?>", "", x)
x = re.sub("http[s]?://.+?\\S+", "", x)
x = re.sub("[@#].+?\\S", "", x)
x = re.sub(r"\\_+", " ", x)
x = re.sub("^[A-Za-z.].*\\s-\\s", "", x)
x = emoji.demojize(x)
x = re.sub(":.*?:", "", x)
x = re.sub("[^a-zA-Z0-9\\s_]", "", x)
words = word_tokenize(x)
words = [word for word in words if word not in stop_words]
x = " ".join([lemmatizer.lemmatize(word) for word in words])
return x
# ✅ Load Model and Vectorizer
@st.cache_resource
def load_model():
# Load the model
model = tf.keras.models.load_model("model_m3_new.keras")
vectorizer = keras.models.load_model("vec_text_m3_new.keras")
# Load label encoder
with open("label_encoder_m5.pkl", 'rb') as file:
label_encoder = pickle.load(file)
return model, vectorizer, label_encoder
# Load models
model, vectorizer, label_encoder = load_model()
# ✅ Prediction Function
def predict_category(text):
processed_text = [pre_process(text)]
text_vectorized = pad_sequences(vectorizer(processed_text).numpy().tolist(), padding='pre', maxlen=128)
prediction = model.predict(text_vectorized)
category_idx = np.argmax(prediction, axis=1)[0]
return label_encoder.inverse_transform([category_idx])[0]
# ✅ Streamlit UI
st.markdown("""
<style>
.title-box {
font-size: 48px;
font-weight: bold;
text-align: center;
background: linear-gradient(135deg, #ff7e5f, #feb47b, #86a8e7, #91eac9);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
animation: gradientAnimation 6s ease infinite;
margin-bottom: 30px;
}
@keyframes gradientAnimation {
0% { background-position: 0% 50%; }
50% { background-position: 100% 50%; }
100% { background-position: 0% 50%; }
}
</style>
<div class="title-box">AI-Powered News Categorization</div>
""", unsafe_allow_html=True)
input_text = st.text_area("Enter News Article:", height=200)
if st.button("Analyze", key="analyze-btn", help="Click to classify the news article"):
if input_text:
category = predict_category(input_text)
st.markdown(f"<div class='result-box'>Predicted Category: {category}</div>", unsafe_allow_html=True)
else:
st.warning("Please enter some text to analyze.")