Maloth123/stack_over_flow
0
1import streamlit as st2import joblib3import pandas as pd4import re5from unidecode import unidecode6import emoji7import string8import contractions9from nltk.stem import PorterStemmer10import numpy as np11from sklearn.feature_extraction.text import ENGLISH_STOP_WORDS12 13st.set_page_config(page_title="StackOverflow Tag Predictor", layout="centered")14 15# ---------------- Modern Glassmorphism CSS ---------------- #16st.markdown("""17<style>18@import url('https://fonts.googleapis.com/css2?family=Poppins:wght@400;600&display=swap');19 20html, body, .stApp {21 font-family: 'Poppins', sans-serif;22 background: linear-gradient(135deg, #f0f9ff 0%, #e0f7fa 100%);23 padding: 0;24 margin: 0;25}26 27.block-container {28 padding-top: 0rem;29}30 31header, footer {32 visibility: hidden;33}34 35.main-container {36 background: rgba(255, 255, 255, 0.9);37 backdrop-filter: blur(12px);38 -webkit-backdrop-filter: blur(12px);39 border-radius: 20px;40 padding: 2.5rem 2rem;41 margin: 2rem auto;42 max-width: 850px;43 box-shadow: 0 8px 20px rgba(0, 0, 0, 0.08);44 border: 1px solid rgba(200, 200, 255, 0.3);45}46 47h1 {48 font-size: 2.5rem;49 font-weight: 700;50 color: #111827;51 margin-bottom: 0.3rem;52}53 54p {55 font-size: 1.05rem;56 color: #4b5563;57 margin-bottom: 1.5rem;58}59 60textarea {61 border-radius: 10px !important;62 border: 1px solid #d1d5db !important;63 padding: 1rem !important;64 font-size: 1rem !important;65}66 67.stButton > button {68 background-color: #3b82f6;69 color: white;70 border: none;71 border-radius: 10px;72 padding: 0.6rem 1.5rem;73 font-size: 1rem;74 font-weight: 600;75 margin-top: 1rem;76}77 78.stButton > button:hover {79 background-color: #2563eb;80}81 82.result-box {83 margin-top: 2rem;84 padding: 1.5rem;85 background-color: #f9fafb;86 border-radius: 16px;87 border: 1px solid #e5e7eb;88}89 90.tag {91 display: inline-block;92 background-color: #dbeafe;93 color: #1e40af;94 padding: 0.4rem 0.9rem;95 border-radius: 16px;96 margin: 0.25rem;97 font-weight: 500;98 font-size: 0.9rem;99}100 101.footer {102 text-align: center;103 color: #6b7280;104 margin-top: 3rem;105 font-size: 0.9rem;106}107</style>108""", unsafe_allow_html=True)109 110# ---------------- NLP Setup ---------------- #111stemmer = PorterStemmer()112stop_words = set(ENGLISH_STOP_WORDS)113chat_words = {114 "brb": "be right back", "btw": "by the way", "lol": "laugh out loud",115 "afaik": "as far as i know", "imo": "in my opinion", "tbh": "to be honest",116 "idk": "i don't know", "asap": "as soon as possible", "np": "no problem",117 "thx": "thanks", "pls": "please", "fyi": "for your information"118}119 120def preprocess_text(text):121 if not isinstance(text, str) or not text.strip():122 return ""123 try:124 text = re.sub(r'<[^>]+>', '', text)125 text = re.sub(r'https?://\S+|www\.\S+', '', text)126 text = emoji.demojize(text, delimiters=(" ", " "))127 text = unidecode(text)128 text = contractions.fix(text)129 text = text.lower()130 words = text.split()131 text = " ".join([chat_words.get(word, word) for word in words])132 text = text.translate(str.maketrans('', '', string.punctuation))133 tokens = re.findall(r'\b\w+\b', text)134 tokens = [word for word in tokens if word not in stop_words]135 tokens = [stemmer.stem(word) for word in tokens]136 return " ".join(tokens)137 except Exception as e:138 st.error(f"Text preprocessing error: {e}")139 return ""140 141# ---------------- Load ML Model ---------------- #142@st.cache_resource143def load_models():144 try:145 model = joblib.load("tag_model.joblib")146 mlb = joblib.load("tag_binarizer.joblib")147 return model, mlb148 except Exception as e:149 st.error(f"Model loading error: {e}")150 return None, None151 152model, mlb = load_models()153 154# ---------------- App Layout ---------------- #155st.markdown('<div class="main-container">', unsafe_allow_html=True)156 157st.markdown("### 🔍 StackOverflow Tag Predictor")158st.markdown("Predict relevant programming tags from your question using ML.")159 160# ---------------- User Input ---------------- #161user_input = st.text_area(162 label="Your Programming Question",163 placeholder="e.g., How to fix a 'NoneType' object is not subscriptable error in Python?",164 height=180165)166 167# ---------------- Predict Button ---------------- #168if st.button("Predict Tags"):169 if not user_input.strip():170 st.warning("Please enter a question to analyze.")171 elif model is None or mlb is None:172 st.error("Model failed to load.")173 else:174 with st.spinner("Processing your question..."):175 processed = preprocess_text(user_input)176 if processed:177 try:178 input_df = pd.DataFrame({'processed_excerpt': [processed]})179 if hasattr(model, "predict_proba"):180 probabilities = model.predict_proba(input_df)[0]181 top5_idx = np.argsort(probabilities)[-5:][::-1]182 top5_tags = [mlb.classes_[i] for i in top5_idx]183 top5_probs = [probabilities[i] for i in top5_idx]184 st.markdown('<div class="result-box"><h3>🏷️ Predicted Tags</h3>', unsafe_allow_html=True)185 for tag, prob in zip(top5_tags, top5_probs):186 st.markdown(f'<div class="tag">{tag}</div>', unsafe_allow_html=True)187 st.markdown('</div>', unsafe_allow_html=True)188 else:189 pred = model.predict(input_df)190 tags = mlb.inverse_transform(pred)191 tags = list(dict.fromkeys([tag for group in tags for tag in group]))[:5]192 if tags:193 st.markdown('<div class="result-box"><h3>🏷️ Predicted Tags</h3>', unsafe_allow_html=True)194 for tag in tags:195 st.markdown(f'<div class="tag">{tag}</div>', unsafe_allow_html=True)196 st.markdown('</div>', unsafe_allow_html=True)197 else:198 st.info("No relevant tags found.")199 except Exception as e:200 st.error(f"Prediction error: {e}")201 202# ---------------- Footer ---------------- #203st.markdown("""204<div class="footer">205 <p>Built with ❤️ using Streamlit and Machine Learning</p>206 <p>By Devaki</p>207</div>208</div>209""", unsafe_allow_html=True)210 