Spaces:
Runtime error
Runtime error
Update app.py
Browse files
app.py
CHANGED
|
@@ -265,7 +265,7 @@ from sklearn.metrics.pairwise import cosine_similarity
|
|
| 265 |
from sklearn.feature_extraction.text import TfidfVectorizer
|
| 266 |
from datetime import datetime
|
| 267 |
|
| 268 |
-
# Load
|
| 269 |
@st.cache_data
|
| 270 |
def load_data():
|
| 271 |
df = pd.read_csv("Illinois_Entire_Data_Insights_Final_v2.csv")
|
|
@@ -276,25 +276,25 @@ def load_data():
|
|
| 276 |
df["summary_insight"] = df["llama_trend_summary"] + "\n" + df["llama_insight"]
|
| 277 |
return df
|
| 278 |
|
| 279 |
-
# Load
|
| 280 |
@st.cache_resource
|
| 281 |
def load_models():
|
| 282 |
embed_model = SentenceTransformer('all-MiniLM-L6-v2')
|
| 283 |
summarizer = pipeline("summarization", model="t5-small", tokenizer="t5-small")
|
| 284 |
return embed_model, summarizer
|
| 285 |
|
| 286 |
-
# Compute
|
| 287 |
@st.cache_data
|
| 288 |
def compute_embeddings(texts, _model):
|
| 289 |
return _model.encode(texts, show_progress_bar=True)
|
| 290 |
|
| 291 |
-
# Perform semantic
|
| 292 |
def semantic_search(query, embeddings, model, threshold=0.5):
|
| 293 |
query_embedding = model.encode([query])
|
| 294 |
sims = cosine_similarity(query_embedding, embeddings)[0]
|
| 295 |
return [(i, s) for i, s in enumerate(sims) if s > threshold]
|
| 296 |
|
| 297 |
-
# Generate
|
| 298 |
def rag_summarize(texts, summarizer, top_k=5):
|
| 299 |
if not texts:
|
| 300 |
return "No relevant content to summarize."
|
|
@@ -308,7 +308,7 @@ def rag_summarize(texts, summarizer, top_k=5):
|
|
| 308 |
out = summarizer(prompt, max_length=60, min_length=30, do_sample=False)
|
| 309 |
return out[0]['summary_text']
|
| 310 |
|
| 311 |
-
# Extract month and year from query
|
| 312 |
def extract_month_year(q):
|
| 313 |
month_map = {m: i for i, m in enumerate(
|
| 314 |
["january", "february", "march", "april", "may", "june",
|
|
@@ -319,7 +319,7 @@ def extract_month_year(q):
|
|
| 319 |
yr = int(ym.group()) if ym else None
|
| 320 |
return mon, yr
|
| 321 |
|
| 322 |
-
# Match query
|
| 323 |
def extract_topic_match(query, df):
|
| 324 |
query_lower = query.lower()
|
| 325 |
return df[
|
|
@@ -329,32 +329,38 @@ def extract_topic_match(query, df):
|
|
| 329 |
df['policy_impact_areas_standardized'].fillna('').str.lower().str.contains(query_lower)
|
| 330 |
]
|
| 331 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 332 |
# Streamlit UI setup
|
| 333 |
st.set_page_config(page_title="IL Trends Q&A", layout="wide")
|
| 334 |
-
st.title("Illinois Legislative Trends Q&A")
|
| 335 |
-
st.markdown("Ask about trends in topics like education, higher education,
|
| 336 |
|
| 337 |
-
# Load
|
| 338 |
df = load_data()
|
| 339 |
embed_model, summarizer = load_models()
|
| 340 |
|
| 341 |
-
# User
|
| 342 |
-
query = st.text_input(" Ask a question (e.g., โtrends in Higher education in 2024โ):")
|
| 343 |
|
| 344 |
if query:
|
| 345 |
mon, yr = extract_month_year(query)
|
| 346 |
df2 = extract_topic_match(query, df)
|
| 347 |
|
| 348 |
if df2.empty:
|
| 349 |
-
df2 = df
|
| 350 |
-
|
| 351 |
if yr:
|
| 352 |
df2 = df2[df2['status_date'].dt.year == yr]
|
| 353 |
if mon:
|
| 354 |
df2 = df2[df2['status_date'].dt.month == mon]
|
| 355 |
-
st.info(f"Filtering by
|
| 356 |
else:
|
| 357 |
-
st.info(f"Filtering by year: **{yr}**")
|
| 358 |
|
| 359 |
if df2.empty:
|
| 360 |
st.warning("No matching records found.")
|
|
@@ -366,32 +372,35 @@ if query:
|
|
| 366 |
if not res:
|
| 367 |
st.warning("No relevant insights found.")
|
| 368 |
else:
|
| 369 |
-
st.subheader("Top Matching Insights")
|
| 370 |
collected = []
|
| 371 |
|
| 372 |
for idx, score in sorted(res, key=lambda x: x[1], reverse=True)[:5]:
|
| 373 |
row = df2.iloc[idx]
|
| 374 |
date = row['status_date'].date()
|
|
|
|
| 375 |
cat_std = row['category_&_subcategory_standardized']
|
| 376 |
goal = row['legislative_goal_standardized']
|
| 377 |
intent = row['intent_standardized']
|
| 378 |
stance = row['stance_standardized']
|
| 379 |
-
trend_summary = row['llama_trend_summary']
|
| 380 |
-
|
| 381 |
-
url = row['
|
| 382 |
-
|
| 383 |
-
st.markdown(f"
|
| 384 |
-
st.markdown(f"
|
| 385 |
-
st.markdown(f"
|
| 386 |
-
st.markdown(f"
|
| 387 |
-
st.markdown(f"
|
| 388 |
-
|
| 389 |
-
|
| 390 |
-
|
|
|
|
| 391 |
|
| 392 |
collected.append(row['summary_insight'])
|
| 393 |
|
| 394 |
-
st.subheader(" RAG-Generated Summary")
|
| 395 |
summary = rag_summarize(collected, summarizer)
|
| 396 |
st.success(summary)
|
| 397 |
|
|
|
|
|
|
| 265 |
from sklearn.feature_extraction.text import TfidfVectorizer
|
| 266 |
from datetime import datetime
|
| 267 |
|
| 268 |
+
# Load dataset
|
| 269 |
@st.cache_data
|
| 270 |
def load_data():
|
| 271 |
df = pd.read_csv("Illinois_Entire_Data_Insights_Final_v2.csv")
|
|
|
|
| 276 |
df["summary_insight"] = df["llama_trend_summary"] + "\n" + df["llama_insight"]
|
| 277 |
return df
|
| 278 |
|
| 279 |
+
# Load models
|
| 280 |
@st.cache_resource
|
| 281 |
def load_models():
|
| 282 |
embed_model = SentenceTransformer('all-MiniLM-L6-v2')
|
| 283 |
summarizer = pipeline("summarization", model="t5-small", tokenizer="t5-small")
|
| 284 |
return embed_model, summarizer
|
| 285 |
|
| 286 |
+
# Compute text embeddings
|
| 287 |
@st.cache_data
|
| 288 |
def compute_embeddings(texts, _model):
|
| 289 |
return _model.encode(texts, show_progress_bar=True)
|
| 290 |
|
| 291 |
+
# Perform semantic similarity search
|
| 292 |
def semantic_search(query, embeddings, model, threshold=0.5):
|
| 293 |
query_embedding = model.encode([query])
|
| 294 |
sims = cosine_similarity(query_embedding, embeddings)[0]
|
| 295 |
return [(i, s) for i, s in enumerate(sims) if s > threshold]
|
| 296 |
|
| 297 |
+
# Generate RAG-style summary
|
| 298 |
def rag_summarize(texts, summarizer, top_k=5):
|
| 299 |
if not texts:
|
| 300 |
return "No relevant content to summarize."
|
|
|
|
| 308 |
out = summarizer(prompt, max_length=60, min_length=30, do_sample=False)
|
| 309 |
return out[0]['summary_text']
|
| 310 |
|
| 311 |
+
# Extract month and year from user query
|
| 312 |
def extract_month_year(q):
|
| 313 |
month_map = {m: i for i, m in enumerate(
|
| 314 |
["january", "february", "march", "april", "may", "june",
|
|
|
|
| 319 |
yr = int(ym.group()) if ym else None
|
| 320 |
return mon, yr
|
| 321 |
|
| 322 |
+
# Match user query to bill-related fields
|
| 323 |
def extract_topic_match(query, df):
|
| 324 |
query_lower = query.lower()
|
| 325 |
return df[
|
|
|
|
| 329 |
df['policy_impact_areas_standardized'].fillna('').str.lower().str.contains(query_lower)
|
| 330 |
]
|
| 331 |
|
| 332 |
+
# Clean generated summary/insight text
|
| 333 |
+
def clean_summary_text(text):
|
| 334 |
+
text = re.sub(r"(?i)here are the requested outputs[:\s]*", "", text)
|
| 335 |
+
text = re.sub(r"(?i)trend summary[:\s]*", "", text)
|
| 336 |
+
text = re.sub(r"(?i)actionable insight[:\s]*", "", text)
|
| 337 |
+
return text.strip()
|
| 338 |
+
|
| 339 |
# Streamlit UI setup
|
| 340 |
st.set_page_config(page_title="IL Trends Q&A", layout="wide")
|
| 341 |
+
st.title("๐ Illinois Legislative Trends Q&A")
|
| 342 |
+
st.markdown("Ask about trends in **topics** like education, higher education, equity, etc.")
|
| 343 |
|
| 344 |
+
# Load everything
|
| 345 |
df = load_data()
|
| 346 |
embed_model, summarizer = load_models()
|
| 347 |
|
| 348 |
+
# User question
|
| 349 |
+
query = st.text_input("๐ Ask a question (e.g., โtrends in Higher education in 2024โ):")
|
| 350 |
|
| 351 |
if query:
|
| 352 |
mon, yr = extract_month_year(query)
|
| 353 |
df2 = extract_topic_match(query, df)
|
| 354 |
|
| 355 |
if df2.empty:
|
| 356 |
+
df2 = df
|
|
|
|
| 357 |
if yr:
|
| 358 |
df2 = df2[df2['status_date'].dt.year == yr]
|
| 359 |
if mon:
|
| 360 |
df2 = df2[df2['status_date'].dt.month == mon]
|
| 361 |
+
st.info(f"๐
Filtering by: **{datetime(yr, mon, 1):%B %Y}**")
|
| 362 |
else:
|
| 363 |
+
st.info(f"๐
Filtering by year: **{yr}**")
|
| 364 |
|
| 365 |
if df2.empty:
|
| 366 |
st.warning("No matching records found.")
|
|
|
|
| 372 |
if not res:
|
| 373 |
st.warning("No relevant insights found.")
|
| 374 |
else:
|
| 375 |
+
st.subheader("๐ Top Matching Insights")
|
| 376 |
collected = []
|
| 377 |
|
| 378 |
for idx, score in sorted(res, key=lambda x: x[1], reverse=True)[:5]:
|
| 379 |
row = df2.iloc[idx]
|
| 380 |
date = row['status_date'].date()
|
| 381 |
+
bill_number = row['bill_number']
|
| 382 |
cat_std = row['category_&_subcategory_standardized']
|
| 383 |
goal = row['legislative_goal_standardized']
|
| 384 |
intent = row['intent_standardized']
|
| 385 |
stance = row['stance_standardized']
|
| 386 |
+
trend_summary = clean_summary_text(row['llama_trend_summary'])
|
| 387 |
+
insight = clean_summary_text(row['llama_insight'])
|
| 388 |
+
url = row['full_text_url']
|
| 389 |
+
|
| 390 |
+
st.markdown(f"**๐๏ธ Date:** {date} | **Bill Number:** `{bill_number}` | **Score:** {score:.2f}")
|
| 391 |
+
st.markdown(f"- **Category:** {cat_std}")
|
| 392 |
+
st.markdown(f"- **Goal:** {goal}")
|
| 393 |
+
st.markdown(f"- **Intent:** {intent} | **Stance:** {stance}")
|
| 394 |
+
st.markdown(f"**๐น Trend Summary:** {trend_summary}")
|
| 395 |
+
if insight:
|
| 396 |
+
st.markdown(f"**๐ง Actionable Insight:** {insight}")
|
| 397 |
+
st.markdown(f"[๐ View Full Bill Text]({url})")
|
| 398 |
+
st.markdown("---")
|
| 399 |
|
| 400 |
collected.append(row['summary_insight'])
|
| 401 |
|
| 402 |
+
st.subheader("๐งพ RAG-Generated Summary")
|
| 403 |
summary = rag_summarize(collected, summarizer)
|
| 404 |
st.success(summary)
|
| 405 |
|
| 406 |
+
|