File size: 4,774 Bytes
c06c8ec
58e2771
 
 
 
 
 
 
f0803ec
58e2771
58f2731
58e2771
 
58f2731
 
58e2771
06e3525
 
 
58e2771
06e3525
58f2731
 
 
58e2771
 
 
 
 
 
58f2731
58e2771
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
f0803ec
 
58e2771
 
 
 
58f2731
58e2771
c06c8ec
58e2771
 
 
58f2731
58e2771
 
 
 
 
 
06e3525
58e2771
06e3525
e805f28
58e2771
e805f28
58e2771
 
 
58f2731
58e2771
 
 
 
 
 
 
 
 
 
 
58f2731
 
58e2771
 
 
 
 
 
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
import streamlit as st
from transformers import pipeline
import torch
import plotly.express as px
import pandas as pd
import time

# --- UI CONFIGURATION ---
st.set_page_config(page_title="NEURAL-X | AI Classifier", layout="wide", initial_sidebar_state="expanded")

# --- CUSTOM CSS ---
st.markdown("""
    <style>
    .stApp { background: radial-gradient(circle at top right, #1e293b, #0f172a); color: #f8fafc; }
    h1 { font-family: 'Inter', sans-serif; font-weight: 800; background: -webkit-linear-gradient(#38bdf8, #818cf8); -webkit-background-clip: text; -webkit-text-fill-color: transparent; letter-spacing: -1px; }
    
    div.stTextArea { width: 100% !important; box-sizing: border-box !important; }
    div[data-baseweb="base-input"], div[data-baseweb="textarea"] { background-color: #1e293b !important; border: 1px solid rgba(255, 255, 255, 0.2) !important; border-radius: 15px !important; }
    textarea { color: #ffffff !important; -webkit-text-fill-color: #ffffff !important; caret-color: #ffffff !important; }

    [data-testid="stMetricValue"] { color: #38bdf8; font-size: 2rem !important; white-space: normal !important; word-wrap: break-word !important; line-height: 1.2; }
    
    .stButton > button { width: 100%; background: linear-gradient(90deg, #6366f1 0%, #a855f7 100%); color: white; border: none; padding: 0.75rem; border-radius: 12px; font-weight: 600; transition: all 0.3s ease; text-transform: uppercase; letter-spacing: 1px; }
    .stButton > button:hover { transform: translateY(-2px); box-shadow: 0 10px 20px rgba(99, 102, 241, 0.4); }
    </style>
    """, unsafe_allow_html=True)

# --- AI BACKEND ---
@st.cache_resource(show_spinner=False)
def load_ai():
    return pipeline("zero-shot-classification", model="cross-encoder/nli-distilroberta-base", device=-1)

classifier = load_ai()

HIDDEN_LABELS = [
    "Business", "Macroeconomics", "Startups", "Stock Market", "Politics", "Geopolitics", 
    "War & Conflict", "Human Rights", "Technology", "Artificial Intelligence", 
    "Cybersecurity", "Science", "Healthcare", "Climate Change", "Entertainment", 
    "Music", "Video Games", "Sports", "Crime", "Religion", "Psychology", 
    "Social Issues", "Mental Health", "Youth & Development", "Education"
]

# --- SIDEBAR (History) ---
with st.sidebar:
    st.title("🗂️ Analysis History")
    if 'history' not in st.session_state:
        st.session_state.history = []
    
    for item in reversed(st.session_state.history):
        st.info(f"**{item['label']}**\n\n{item['text'][:50]}...")

# --- MAIN UI ---
st.title("NEURAL-X CLASSIFIER")
st.write("#### Enterprise-grade semantic analysis powered by Deep Learning.")

col1, col2 = st.columns([1.2, 0.8], gap="large")

with col1:
    text_input = st.text_area("INPUT STREAM", height=250, placeholder="Paste raw text here...")
    analyze_btn = st.button("Execute Neural Scan")

with col2:
    if analyze_btn:
        if not text_input.strip():
            st.warning("⚠️ Neural input buffer empty.")
        else:
            with st.spinner("Processing Tensors..."):
                start_time = time.time()
                result = classifier(text_input, HIDDEN_LABELS, multi_label=True)
                end_time = time.time()
                
                # Dynamic Logic with 60% Threshold
                valid_pairs = [(l, s) for l, s in zip(result['labels'], result['scores']) if s >= 0.60]
                
                # THE REVERT: Blindly guessing the highest score if nothing hits 60%
                if not valid_pairs:
                    valid_pairs = [(result['labels'][0], result['scores'][0])]
                
                st.subheader("Analysis Results")
                m1, m2 = st.columns(2)
                
                m1.metric("Top Category", valid_pairs[0][0])
                m2.metric("Inference Time", f"{round(end_time - start_time, 2)}s")
                
                df = pd.DataFrame({
                    "Concept": [p[0] for p in valid_pairs],
                    "Confidence": [p[1] for p in valid_pairs]
                }).sort_values("Confidence")
                
                fig = px.bar(df, x="Confidence", y="Concept", orientation='h',
                             color="Confidence", color_continuous_scale="Tealgrn",
                             template="plotly_dark")
                             
                fig.update_yaxes(automargin=True)
                fig.update_layout(paper_bgcolor='rgba(0,0,0,0)', plot_bgcolor='rgba(0,0,0,0)')
                st.plotly_chart(fig, use_container_width=True)
                
                st.session_state.history.append({"label": valid_pairs[0][0], "text": text_input})
    else:
        st.info("💡 Enter text and initiate scan to view semantic mapping.")