lemonslayer commited on
Commit
da254ca
·
verified ·
1 Parent(s): 9f400e1

Upload 2 files

Browse files
Files changed (2) hide show
  1. app.py +122 -0
  2. requirements.txt +4 -0
app.py ADDED
@@ -0,0 +1,122 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import pandas as pd
2
+ from geopy.geocoders import Nominatim
3
+ from geopy.distance import geodesic
4
+ import requests
5
+ import gradio as gr
6
+ import os
7
+
8
+ # 🔐 Your OpenRouter API Key (keep this secret)
9
+ OPENROUTER_API_KEY = os.getenv('OPENROUTER_API_KEY')
10
+
11
+ # 📂 Load your accident dataset
12
+ df = pd.read_csv("final_merged.csv") # Replace with your file
13
+
14
+ # 🌐 Get coordinates for user location
15
+ def geocode_location(location_name):
16
+ geolocator = Nominatim(user_agent="accident-warning-system")
17
+ location = geolocator.geocode(location_name)
18
+ return (location.latitude, location.longitude) if location else None
19
+
20
+ # 📍 Find nearest accident locations
21
+ def find_nearest_accidents(user_latlon, df, top_n=10):
22
+ df['DISTANCE'] = df.apply(
23
+ lambda row: geodesic(user_latlon, (row['LATITUDE'], row['LONGITUDE'])).meters, axis=1)
24
+ return df.sort_values('DISTANCE').head(top_n)
25
+
26
+ # 🧪 Filter by atmospheric and road condition
27
+ def filter_by_conditions(df, atmosphere, road_condition):
28
+ return df[
29
+ df['ATMOSPH_COND_DESC'].str.contains(atmosphere, case=False, na=False) &
30
+ df['SURFACE_COND_DESC'].str.contains(road_condition, case=False, na=False)
31
+ ]
32
+
33
+ # 📊 Summarize accident data
34
+ def summarize_data(df):
35
+ return {
36
+ "total_accidents": len(df),
37
+ "severe_accidents": (df["SEVERITY"] == "Serious").sum(),
38
+ "fatalities": int(df["NO_PERSONS_KILLED"].sum()),
39
+ "common_types": df["ACCIDENT_TYPE_DESC"].value_counts().head(3).to_dict(),
40
+ "age_groups": df["AGE_GROUP"].value_counts().head(2).to_dict(),
41
+ "user_types": df["ROAD_USER_TYPE"].value_counts().head(2).to_dict()
42
+ }
43
+
44
+ # 🧾 Format readable summary
45
+ def format_summary(summary, location, atmosphere, road_condition):
46
+ return (
47
+ f"📍 Location: {location}\n"
48
+ f"🌦️ Atmosphere: {atmosphere}\n"
49
+ f"🛣️ Road Condition: {road_condition}\n\n"
50
+ f"🚧 Accidents Nearby: {summary['total_accidents']}\n"
51
+ f"❗ Severe Accidents: {summary['severe_accidents']}\n"
52
+ f"☠️ Fatalities: {summary['fatalities']}\n"
53
+ f"🔁 Common Accident Types: {', '.join(summary['common_types'].keys())}\n"
54
+ f"👥 Age Groups Involved: {', '.join(summary['age_groups'].keys())}\n"
55
+ f"🚶‍♂️ User Types Affected: {', '.join(summary['user_types'].keys())}\n"
56
+ )
57
+
58
+ # 💬 Generate LLM warning
59
+ def get_llm_warning(summary, location, atmosphere, road_condition):
60
+ prompt = f"""
61
+ A driver is traveling to "{location}" during "{atmosphere}" weather and "{road_condition}" road conditions.
62
+
63
+ Nearby accident statistics:
64
+ - Total accidents: {summary['total_accidents']}
65
+ - Severe: {summary['severe_accidents']}
66
+ - Fatalities: {summary['fatalities']}
67
+ - Common types: {summary['common_types']}
68
+ - Age groups involved: {summary['age_groups']}
69
+ - Road users involved: {summary['user_types']}
70
+
71
+ Give a short safety warning with practical advice based on this data.
72
+ """
73
+ headers = {
74
+ "Authorization": f"Bearer {OPENROUTER_API_KEY}",
75
+ "Content-Type": "application/json"
76
+ }
77
+ payload = {
78
+ "model": "openai/gpt-3.5-turbo",
79
+ "messages": [{"role": "user", "content": prompt}]
80
+ }
81
+ try:
82
+ response = requests.post("https://openrouter.ai/api/v1/chat/completions", headers=headers, json=payload)
83
+ if response.status_code == 200:
84
+ return response.json()['choices'][0]['message']['content']
85
+ else:
86
+ return f"⚠️ LLM Error: {response.status_code} - {response.text}"
87
+ except Exception as e:
88
+ return f"⚠️ Request failed: {e}"
89
+
90
+ # 🤖 Gradio function
91
+ def advisory_bot(location, atmosphere, road_condition):
92
+ coords = geocode_location(location)
93
+ if not coords:
94
+ return "❌ Could not find the specified location.", ""
95
+
96
+ nearest_df = find_nearest_accidents(coords, df)
97
+ filtered_df = filter_by_conditions(nearest_df, atmosphere, road_condition)
98
+
99
+ if filtered_df.empty:
100
+ return f"⚠️ No recent accident data found near '{location}' for these conditions.", ""
101
+
102
+ summary = summarize_data(filtered_df)
103
+ summary_text = format_summary(summary, location, atmosphere, road_condition)
104
+ llm_warning = get_llm_warning(summary, location, atmosphere, road_condition)
105
+
106
+ return summary_text, llm_warning
107
+
108
+ # 🎛️ Gradio UI
109
+ gr.Interface(
110
+ fn=advisory_bot,
111
+ inputs=[
112
+ gr.Textbox(label="📍 Location (e.g., Plenty Road, Melbourne)"),
113
+ gr.Textbox(label="🌦️ Atmosphere (e.g., Rain, Fog, Clear)"),
114
+ gr.Textbox(label="🛣️ Road Condition (e.g., Wet, Dry)")
115
+ ],
116
+ outputs=[
117
+ gr.Textbox(label="📊 Accident Summary"),
118
+ gr.Textbox(label="🛑 Safety Warning")
119
+ ],
120
+ title="🚧 Accident Risk Advisory",
121
+ description="Input a location, weather, and road condition to get a data-based accident summary and safety warning."
122
+ ).launch()
requirements.txt ADDED
@@ -0,0 +1,4 @@
 
 
 
 
 
1
+ pandas
2
+ geopy
3
+ gradio
4
+ requests