Spaces:
Sleeping
Sleeping
File size: 3,270 Bytes
c4e8774 311ac82 c4e8774 b1de695 c4e8774 98aeab4 c4e8774 e572246 b1de695 e572246 b1de695 e572246 b1de695 e572246 e004797 b1de695 e004797 c4e8774 e572246 c4e8774 98aeab4 e004797 e572246 e004797 98aeab4 b1de695 98aeab4 b1de695 98aeab4 e572246 98aeab4 e572246 98aeab4 e572246 98aeab4 e004797 98aeab4 b1de695 e004797 98aeab4 b1de695 e004797 e572246 98aeab4 b1de695 98aeab4 b1de695 | 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 | import streamlit as st
import pandas as pd
import numpy as np
import pickle
import tensorflow as tf
import neattext.functions as nfx
from tensorflow.keras.models import load_model
from tensorflow.keras.layers import InputLayer, Dense
from PIL import Image
# 1. Set Page Config
st.set_page_config(page_title="Disaster Tweet Detector", page_icon="🚨", layout="centered")
# 2. The Absolute Final Recovery Fix
# We manually define the input shape (5000) to bypass the broken file metadata
@st.cache_resource
def load_assets():
# This function creates a dummy layer that Keras expects
def fix_input_layer(**kwargs):
# We force the shape to be 5000 because that's what your vectorizer produces
return InputLayer(shape=(5000,))
# This dummy function ignores the Keras 3 'DTypePolicy'
def fix_dtype(*args, **kwargs):
return None
custom_objects = {
'InputLayer': fix_input_layer,
'SafeInputLayer': fix_input_layer,
'DTypePolicy': fix_dtype,
# If it complains about Dense again, we use the standard Dense
'Dense': Dense
}
# Load the model ignoring the 'compile' step and using our manual fixes
model = load_model(
'disaster_model.h5',
custom_objects=custom_objects,
compile=False
)
# Load the vectorizer
with open('vectorizer.pkl', 'rb') as f:
vect = pickle.load(f)
return model, vect
# 3. Preprocessing Function
def clean_text(text):
text = text.lower()
text = nfx.remove_hashtags(text)
text = nfx.remove_urls(text)
text = nfx.remove_userhandles(text)
text = nfx.remove_multiple_spaces(text)
text = nfx.remove_special_characters(text)
return text
# --- App Interface ---
try:
model, vect = load_assets()
except Exception as e:
st.error(f"Critical Deployment Error: {e}")
st.warning("Manual Override triggered. Please refresh the page.")
st.stop()
st.title("🚨 Disaster Tweet Detector")
st.markdown("Analyzing social media sentiment for emergency response.")
try:
img = Image.open('disaster_wordcloud.png')
st.image(img, caption="Common Disaster Keywords", use_container_width=True)
except:
pass
st.subheader("Analyze a Tweet")
user_input = st.text_area("Enter tweet text:", placeholder="e.g., Massive earthquake reported!")
if st.button("Predict"):
if user_input.strip() != "":
cleaned_msg = clean_text(user_input)
# Convert text to the 5000-feature vector
vect_text = vect.transform([cleaned_msg]).toarray()
# Prediction logic
prediction = model.predict(vect_text)
probability = float(prediction[0][0])
st.divider()
if probability > 0.5:
st.error(f"### ⚠️ Real Disaster Detected! ({probability:.2%})")
st.progress(probability)
else:
st.success(f"### ✅ Normal Tweet ({(1-probability):.2%})")
st.progress(1 - probability)
with st.expander("Technical Details"):
st.write(f"Processed Text: {cleaned_msg}")
st.write(f"Vector Shape: {vect_text.shape}")
else:
st.warning("Please enter text.")
st.divider()
st.caption("Data Science Portfolio") |