Spaces:
Running
Running
File size: 4,979 Bytes
da254ca |
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 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 |
import pandas as pd
from geopy.geocoders import Nominatim
from geopy.distance import geodesic
import requests
import gradio as gr
import os
# 🔐 Your OpenRouter API Key (keep this secret)
OPENROUTER_API_KEY = os.getenv('OPENROUTER_API_KEY')
# 📂 Load your accident dataset
df = pd.read_csv("final_merged.csv") # Replace with your file
# 🌐 Get coordinates for user location
def geocode_location(location_name):
geolocator = Nominatim(user_agent="accident-warning-system")
location = geolocator.geocode(location_name)
return (location.latitude, location.longitude) if location else None
# 📍 Find nearest accident locations
def find_nearest_accidents(user_latlon, df, top_n=10):
df['DISTANCE'] = df.apply(
lambda row: geodesic(user_latlon, (row['LATITUDE'], row['LONGITUDE'])).meters, axis=1)
return df.sort_values('DISTANCE').head(top_n)
# 🧪 Filter by atmospheric and road condition
def filter_by_conditions(df, atmosphere, road_condition):
return df[
df['ATMOSPH_COND_DESC'].str.contains(atmosphere, case=False, na=False) &
df['SURFACE_COND_DESC'].str.contains(road_condition, case=False, na=False)
]
# 📊 Summarize accident data
def summarize_data(df):
return {
"total_accidents": len(df),
"severe_accidents": (df["SEVERITY"] == "Serious").sum(),
"fatalities": int(df["NO_PERSONS_KILLED"].sum()),
"common_types": df["ACCIDENT_TYPE_DESC"].value_counts().head(3).to_dict(),
"age_groups": df["AGE_GROUP"].value_counts().head(2).to_dict(),
"user_types": df["ROAD_USER_TYPE"].value_counts().head(2).to_dict()
}
# 🧾 Format readable summary
def format_summary(summary, location, atmosphere, road_condition):
return (
f"📍 Location: {location}\n"
f"🌦️ Atmosphere: {atmosphere}\n"
f"🛣️ Road Condition: {road_condition}\n\n"
f"🚧 Accidents Nearby: {summary['total_accidents']}\n"
f"❗ Severe Accidents: {summary['severe_accidents']}\n"
f"☠️ Fatalities: {summary['fatalities']}\n"
f"🔁 Common Accident Types: {', '.join(summary['common_types'].keys())}\n"
f"👥 Age Groups Involved: {', '.join(summary['age_groups'].keys())}\n"
f"🚶♂️ User Types Affected: {', '.join(summary['user_types'].keys())}\n"
)
# 💬 Generate LLM warning
def get_llm_warning(summary, location, atmosphere, road_condition):
prompt = f"""
A driver is traveling to "{location}" during "{atmosphere}" weather and "{road_condition}" road conditions.
Nearby accident statistics:
- Total accidents: {summary['total_accidents']}
- Severe: {summary['severe_accidents']}
- Fatalities: {summary['fatalities']}
- Common types: {summary['common_types']}
- Age groups involved: {summary['age_groups']}
- Road users involved: {summary['user_types']}
Give a short safety warning with practical advice based on this data.
"""
headers = {
"Authorization": f"Bearer {OPENROUTER_API_KEY}",
"Content-Type": "application/json"
}
payload = {
"model": "openai/gpt-3.5-turbo",
"messages": [{"role": "user", "content": prompt}]
}
try:
response = requests.post("https://openrouter.ai/api/v1/chat/completions", headers=headers, json=payload)
if response.status_code == 200:
return response.json()['choices'][0]['message']['content']
else:
return f"⚠️ LLM Error: {response.status_code} - {response.text}"
except Exception as e:
return f"⚠️ Request failed: {e}"
# 🤖 Gradio function
def advisory_bot(location, atmosphere, road_condition):
coords = geocode_location(location)
if not coords:
return "❌ Could not find the specified location.", ""
nearest_df = find_nearest_accidents(coords, df)
filtered_df = filter_by_conditions(nearest_df, atmosphere, road_condition)
if filtered_df.empty:
return f"⚠️ No recent accident data found near '{location}' for these conditions.", ""
summary = summarize_data(filtered_df)
summary_text = format_summary(summary, location, atmosphere, road_condition)
llm_warning = get_llm_warning(summary, location, atmosphere, road_condition)
return summary_text, llm_warning
# 🎛️ Gradio UI
gr.Interface(
fn=advisory_bot,
inputs=[
gr.Textbox(label="📍 Location (e.g., Plenty Road, Melbourne)"),
gr.Textbox(label="🌦️ Atmosphere (e.g., Rain, Fog, Clear)"),
gr.Textbox(label="🛣️ Road Condition (e.g., Wet, Dry)")
],
outputs=[
gr.Textbox(label="📊 Accident Summary"),
gr.Textbox(label="🛑 Safety Warning")
],
title="🚧 Accident Risk Advisory",
description="Input a location, weather, and road condition to get a data-based accident summary and safety warning."
).launch()
|