Spaces:
Sleeping
Sleeping
| import streamlit as st | |
| import plotly.graph_objects as go | |
| import pandas as pd | |
| import torch | |
| from transformers import AutoTokenizer, AutoModelForSequenceClassification | |
| # --------------------------------------------------- | |
| # Page Config (must be first Streamlit command) | |
| # --------------------------------------------------- | |
| st.set_page_config( | |
| page_title="Aspect-Based Intelligence", | |
| page_icon="β¨", | |
| layout="wide", | |
| initial_sidebar_state="expanded" | |
| ) | |
| # --------------------------------------------------- | |
| # Load Model | |
| # --------------------------------------------------- | |
| MODEL_NAME = "justhariharan/Review-RAG" | |
| def load_model(): | |
| tokenizer = AutoTokenizer.from_pretrained(MODEL_NAME) | |
| model = AutoModelForSequenceClassification.from_pretrained(MODEL_NAME) | |
| model.eval() | |
| return tokenizer, model | |
| tokenizer, model = load_model() | |
| labels = ["positive","negative","neutral","conflict"] | |
| # --------------------------------------------------- | |
| # Prediction Function | |
| # --------------------------------------------------- | |
| def predict_sentiment(text): | |
| inputs = tokenizer( | |
| text, | |
| return_tensors="pt", | |
| truncation=True, | |
| padding=True | |
| ) | |
| with torch.no_grad(): | |
| outputs = model(**inputs) | |
| probs = torch.softmax(outputs.logits, dim=1)[0] | |
| pred_id = torch.argmax(probs).item() | |
| return { | |
| "sentiment": labels[pred_id], | |
| "confidence": float(probs[pred_id]) | |
| } | |
| # --------------------------------------------------- | |
| # UI Styling | |
| # --------------------------------------------------- | |
| st.markdown(""" | |
| <style> | |
| .block-container { | |
| padding-top:2rem; | |
| padding-bottom:2rem; | |
| } | |
| .sentiment-card{ | |
| padding:1.2rem; | |
| border-radius:12px; | |
| margin-bottom:1rem; | |
| box-shadow:0 4px 6px rgba(0,0,0,0.1); | |
| color:white; | |
| display:flex; | |
| justify-content:space-between; | |
| align-items:center; | |
| } | |
| .aspect-title{font-size:1.4rem;font-weight:700;} | |
| .sentiment-label{text-transform:uppercase;} | |
| .pos-theme{background:linear-gradient(135deg,#11998e,#38ef7d);} | |
| .neg-theme{background:linear-gradient(135deg,#FF416C,#FF4B2B);} | |
| .neu-theme{background:linear-gradient(135deg,#7F7FD5,#86A8E7);} | |
| .con-theme{background:linear-gradient(135deg,#F2994A,#F2C94C);} | |
| .gradient-text{ | |
| font-weight:800; | |
| background:-webkit-linear-gradient(45deg,#4facfe,#00f2fe); | |
| -webkit-background-clip:text; | |
| -webkit-text-fill-color:transparent; | |
| font-size:3rem; | |
| } | |
| </style> | |
| """, unsafe_allow_html=True) | |
| # --------------------------------------------------- | |
| # Header | |
| # --------------------------------------------------- | |
| st.markdown('<h1 class="gradient-text">β¨ Aspect-Based Review Intelligence</h1>', unsafe_allow_html=True) | |
| st.markdown( | |
| "Transforming unstructured customer feedback into real-time actionable telemetry." | |
| ) | |
| st.divider() | |
| # --------------------------------------------------- | |
| # Sidebar Status | |
| # --------------------------------------------------- | |
| with st.sidebar: | |
| st.title("System Status") | |
| st.success("π’ Model Loaded") | |
| st.info("π§ RoBERTa Inference Ready") | |
| st.divider() | |
| st.markdown("**Tech Stack:**") | |
| st.markdown("`RoBERTa` `Transformers` `Streamlit`") | |
| # --------------------------------------------------- | |
| # Tabs | |
| # --------------------------------------------------- | |
| tab1, tab2, tab3 = st.tabs( | |
| ["π Analytics Dashboard","π¬ RAG Copilot","π Live Extraction"] | |
| ) | |
| # --------------------------------------------------- | |
| # Analytics Dashboard | |
| # --------------------------------------------------- | |
| with tab1: | |
| st.subheader("Sentiment Distribution (Demo Analytics)") | |
| demo_data = { | |
| "positive":120, | |
| "negative":45, | |
| "neutral":30, | |
| "conflict":15 | |
| } | |
| fig = go.Figure( | |
| data=[go.Bar( | |
| x=list(demo_data.keys()), | |
| y=list(demo_data.values()) | |
| )] | |
| ) | |
| st.plotly_chart(fig,use_container_width=True) | |
| # --------------------------------------------------- | |
| # RAG Copilot (UI only demo) | |
| # --------------------------------------------------- | |
| with tab2: | |
| st.subheader("Talk to Your Product Data") | |
| st.info("RAG Copilot demo mode. Backend disabled in Spaces.") | |
| prompt = st.chat_input("Ask about product feedback") | |
| if prompt: | |
| with st.chat_message("user"): | |
| st.write(prompt) | |
| with st.chat_message("assistant"): | |
| st.write("RAG backend is not deployed in this demo.") | |
| # --------------------------------------------------- | |
| # Live Review Analysis | |
| # --------------------------------------------------- | |
| with tab3: | |
| st.subheader("NLP Extraction Sandbox") | |
| review_text = st.text_area( | |
| "Input Review:", | |
| height=120, | |
| placeholder="The laptop screen is gorgeous but the battery drains incredibly fast." | |
| ) | |
| analyze_btn = st.button("π Run Extraction") | |
| if analyze_btn and review_text: | |
| with st.spinner("Running RoBERTa inference..."): | |
| result = predict_sentiment(review_text) | |
| sentiment = result["sentiment"] | |
| conf = result["confidence"] | |
| theme_class="neu-theme" | |
| icon="βͺ" | |
| if sentiment=="positive": | |
| theme_class="pos-theme" | |
| icon="π’" | |
| elif sentiment=="negative": | |
| theme_class="neg-theme" | |
| icon="π΄" | |
| elif sentiment=="conflict": | |
| theme_class="con-theme" | |
| icon="π‘" | |
| card_html=f""" | |
| <div class="sentiment-card {theme_class}"> | |
| <div> | |
| <p class="aspect-title">{icon} Overall Sentiment</p> | |
| <p class="sentiment-label">{sentiment}</p> | |
| </div> | |
| <div style="text-align:right;"> | |
| <h2>{conf*100:.0f}%</h2> | |
| <p>Confidence</p> | |
| </div> | |
| </div> | |
| """ | |
| st.markdown(card_html,unsafe_allow_html=True) |