vishnu-coder commited on
Commit
9788e26
ยท
1 Parent(s): e2047f6

Integrated Hugging Face model for cloud deployment

Browse files
Files changed (1) hide show
  1. app.py +35 -77
app.py CHANGED
@@ -5,6 +5,8 @@ from pathlib import Path
5
  from typing import Dict
6
  import pandas as pd
7
  import streamlit as st
 
 
8
 
9
  # -------------------------------------------------------------------------
10
  # Page Configuration
@@ -20,34 +22,33 @@ st.caption("Streamlit front-end for the Deloitte-ready Twitter Sentiment Intelli
20
 
21
  try:
22
  # -------------------------------------------------------------------------
23
- # Path setup (โœ… Fixed for root-level app.py)
24
  # -------------------------------------------------------------------------
25
- ROOT = Path(__file__).resolve().parents[0]
26
- SRC_PATH = ROOT / "src"
27
- if str(SRC_PATH) not in sys.path:
28
- sys.path.insert(0, str(SRC_PATH))
29
 
30
- # โœ… Updated imports to use lightweight remote model loader
31
- from twitter_sentiment.config import load_config
32
- from twitter_sentiment.model_loader import get_model
33
- from twitter_sentiment.predictor import predict_with_threshold
34
-
35
- # -------------------------------------------------------------------------
36
- # Cached dependencies (โœ… lightweight version)
37
- # -------------------------------------------------------------------------
38
  @st.cache_resource(show_spinner=False)
39
- def _load_dependencies():
40
- """Load configuration and lightweight remote model."""
41
- config = load_config()
42
- pipeline = get_model()
43
- metrics = {} # Placeholder (not bundled to reduce size)
44
- return config, pipeline, metrics
 
45
 
46
  # -------------------------------------------------------------------------
47
- # Format probabilities helper
48
  # -------------------------------------------------------------------------
 
 
 
 
 
 
 
 
49
  def format_probabilities(probabilities: Dict[str, float]) -> pd.DataFrame:
50
- """Convert prediction probabilities to a styled DataFrame for display."""
51
  return (
52
  pd.DataFrame.from_dict(probabilities, orient="index", columns=["confidence"])
53
  .sort_values("confidence", ascending=False)
@@ -55,70 +56,27 @@ try:
55
  )
56
 
57
  # -------------------------------------------------------------------------
58
- # Main Streamlit Application
59
  # -------------------------------------------------------------------------
60
- def main() -> None:
61
- """Render the Deloitte-ready Twitter Sentiment Intelligence Dashboard."""
62
- config, pipeline, metrics = _load_dependencies()
 
63
 
64
- # ---------------------- Sidebar ----------------------
65
- with st.sidebar:
66
- st.header("๐Ÿ“Š Model Snapshot")
67
- if hasattr(pipeline, "classes_"):
68
- st.write("**Classes:**", ", ".join(pipeline.classes_))
69
- else:
70
- st.write("**Model:** Loaded remotely")
71
 
72
- if metrics:
73
- st.metric("Macro F1", f"{metrics.get('f1_macro', 0.0):.2f}")
74
- st.metric("Accuracy", f"{metrics.get('accuracy', 0.0):.2f}")
75
  else:
76
- st.info("Run training locally to generate metrics (`scripts/train.py`).")
77
-
78
- st.download_button(
79
- label="โฌ‡๏ธ Download Metrics JSON",
80
- data=json.dumps(metrics or {}, indent=2).encode("utf-8"),
81
- file_name="metrics.json",
82
- mime="application/json",
83
- )
84
- st.info(
85
- "๐Ÿš€ Tip: Integrate Oracle Autonomous Database by updating `config/settings.yaml`."
86
- )
87
 
88
- # ---------------------- Tabs ----------------------
89
- tab_predict, tab_metrics = st.tabs(["๐Ÿ”ฎ Predict", "โš™๏ธ Model Governance"])
90
-
91
- # ---------------------- Prediction Tab ----------------------
92
- with tab_predict:
93
- st.subheader("Real-Time Sentiment Assessment")
94
- user_input = st.text_area("Enter a tweet or customer comment:", height=150)
95
- if st.button("Run Analysis", type="primary"):
96
- if not user_input.strip():
97
- st.warning("โš ๏ธ Please enter text to analyse.")
98
- else:
99
- label, probabilities = predict_with_threshold(user_input, config)
100
- st.success(f"Predicted Sentiment: **{label.title()}**")
101
- st.dataframe(format_probabilities(probabilities), use_container_width=True)
102
-
103
- # ---------------------- Metrics Tab ----------------------
104
- with tab_metrics:
105
- st.subheader("Operational Metrics")
106
- if metrics:
107
- metrics_df = (
108
- pd.DataFrame(metrics, index=["score"])
109
- .T.rename(columns={"score": "value"})
110
- )
111
- st.dataframe(metrics_df, use_container_width=True)
112
- else:
113
- st.info("Metrics will appear after local training run (see `scripts/train.py`).")
114
-
115
- # ---------------------- Footer ----------------------
116
  st.markdown("---")
117
  st.caption("ยฉ 2025 Deloitte-aligned Sentiment Analytics Accelerator")
118
 
119
- # -------------------------------------------------------------------------
120
- # Entry Point
121
- # -------------------------------------------------------------------------
122
  if __name__ == "__main__":
123
  main()
124
 
 
5
  from typing import Dict
6
  import pandas as pd
7
  import streamlit as st
8
+ from huggingface_hub import hf_hub_download
9
+ import joblib
10
 
11
  # -------------------------------------------------------------------------
12
  # Page Configuration
 
22
 
23
  try:
24
  # -------------------------------------------------------------------------
25
+ # Download model from Hugging Face Hub (no local artifacts needed)
26
  # -------------------------------------------------------------------------
27
+ MODEL_REPO = "vishnu-coder/twitter-sentiment-model"
28
+ MODEL_FILENAME = "sentiment_pipeline.joblib"
 
 
29
 
 
 
 
 
 
 
 
 
30
  @st.cache_resource(show_spinner=False)
31
+ def load_model():
32
+ """Download and load the trained model from Hugging Face Hub."""
33
+ model_path = hf_hub_download(repo_id=MODEL_REPO, filename=MODEL_FILENAME)
34
+ pipeline = joblib.load(model_path)
35
+ return pipeline
36
+
37
+ pipeline = load_model()
38
 
39
  # -------------------------------------------------------------------------
40
+ # Helper function for predictions
41
  # -------------------------------------------------------------------------
42
+ def predict_sentiment(text: str) -> tuple[str, Dict[str, float]]:
43
+ """Predict sentiment and confidence scores."""
44
+ probs = pipeline.predict_proba([text])[0]
45
+ classes = pipeline.classes_
46
+ label = classes[probs.argmax()]
47
+ probabilities = dict(zip(classes, probs))
48
+ return label, probabilities
49
+
50
  def format_probabilities(probabilities: Dict[str, float]) -> pd.DataFrame:
51
+ """Convert probabilities to styled DataFrame."""
52
  return (
53
  pd.DataFrame.from_dict(probabilities, orient="index", columns=["confidence"])
54
  .sort_values("confidence", ascending=False)
 
56
  )
57
 
58
  # -------------------------------------------------------------------------
59
+ # Streamlit UI
60
  # -------------------------------------------------------------------------
61
+ def main():
62
+ st.sidebar.header("๐Ÿ“Š Model Snapshot")
63
+ st.sidebar.write("**Source:**", MODEL_REPO)
64
+ st.sidebar.success("โœ… Loaded model from Hugging Face Hub")
65
 
66
+ st.subheader("๐Ÿ”ฎ Real-Time Sentiment Analysis")
67
+ user_input = st.text_area("Enter a tweet or comment:", height=150)
 
 
 
 
 
68
 
69
+ if st.button("Analyze", type="primary"):
70
+ if not user_input.strip():
71
+ st.warning("โš ๏ธ Please enter text to analyze.")
72
  else:
73
+ label, probabilities = predict_sentiment(user_input)
74
+ st.success(f"Predicted Sentiment: **{label.title()}**")
75
+ st.dataframe(format_probabilities(probabilities), use_container_width=True)
 
 
 
 
 
 
 
 
76
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
77
  st.markdown("---")
78
  st.caption("ยฉ 2025 Deloitte-aligned Sentiment Analytics Accelerator")
79
 
 
 
 
80
  if __name__ == "__main__":
81
  main()
82