-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathapp.py
More file actions
147 lines (122 loc) · 4.88 KB
/
app.py
File metadata and controls
147 lines (122 loc) · 4.88 KB
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
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
"""
Streamlit Web Application for Agricultural Production Forecasting.
"""
import streamlit as st
import pandas as pd
import numpy as np
import os
import sys
import plotly.graph_objects as go
from PIL import Image
# Add src to path
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
from src.data_loader import DataLoader
from src.feature_engineering import FeatureEngineer
from src.predictor import Predictor
from src.policy_advisor import PolicyAdvisor
from src.visualization import Visualizer
# Page Config
st.set_page_config(
page_title="Kaduna Agricultural Forecasting",
page_icon="🌾",
layout="wide"
)
# Title and Header
st.title("🌾 Kaduna State Agricultural Forecasting System")
st.markdown("""
This system predicts future crop production levels to support food security planning and policy decisions.
""")
# Sidebar
st.sidebar.header("Configuration")
# Load Data
@st.cache_data
def load_dataset():
loader = DataLoader("Kaduna_State_Agricultural_Production_Data.csv")
loader.clean_data()
return loader
try:
loader = load_dataset()
available_crops = loader.get_available_crops()
except Exception as e:
st.error(f"Error loading data: {e}")
st.stop()
# Crop Selection
selected_crop = st.sidebar.selectbox("Select Crop", available_crops, index=available_crops.index("Maize") if "Maize" in available_crops else 0)
# Model Selection
model_options = ['ARIMA', 'SARIMAX', 'XGBoost', 'LSTM', 'GRU']
selected_model = st.sidebar.selectbox("Select Model", model_options, index=0)
# Forecast Horizon
forecast_years = st.sidebar.slider("Forecast Horizon (Years)", 1, 5, 3)
# Run Button
if st.sidebar.button("Generate Forecast"):
with st.spinner(f"Generating forecast for {selected_crop} using {selected_model}..."):
try:
# Get Data
crop_df = loader.get_crop_data(selected_crop)
# Initialize Components
predictor = Predictor()
advisor = PolicyAdvisor()
viz = Visualizer()
# Generate Forecast
# Note: This assumes models are already trained and saved in outputs/models/
# If not, we might need to trigger training or handle the error
try:
forecast_df = predictor.generate_forecast(
selected_crop,
selected_model.lower(),
years_ahead=forecast_years,
historical_data=crop_df
)
except FileNotFoundError:
st.warning(f"Model {selected_model} for {selected_crop} not found. Please train the model first using the CLI or check available models.")
st.info(f"Try running: `python main.py --crop \"{selected_crop}\" --model {selected_model.lower()} --train` in your terminal.")
st.stop()
# Layout
col1, col2 = st.columns([2, 1])
with col1:
st.subheader("Production Forecast")
# Plot
fig = viz.plot_forecast_interactive(
crop_df, forecast_df, selected_crop, selected_model
)
st.plotly_chart(fig, use_container_width=True)
# Data Table
st.subheader("Forecast Data")
st.dataframe(forecast_df)
with col2:
st.subheader("Policy Analysis")
# Policy Analysis
analysis = advisor.analyze_forecast(crop_df, forecast_df, selected_crop)
recs = advisor.generate_recommendations(analysis)
# Display Recommendations
for rec in recs:
if "ALERT" in rec or "Shortage" in rec:
st.error(rec)
elif "NOTICE" in rec or "Oversupply" in rec:
st.warning(rec)
elif "Action" in rec:
st.info(rec)
else:
st.write(rec)
# Download Policy Brief
brief_text = "\n".join(recs)
st.download_button(
label="Download Policy Brief",
data=brief_text,
file_name=f"{selected_crop}_policy_brief.txt",
mime="text/plain"
)
except Exception as e:
st.error(f"An error occurred: {e}")
import traceback
st.code(traceback.format_exc())
# Historical Data Tab
with st.expander("View Historical Data"):
crop_df = loader.get_crop_data(selected_crop)
st.dataframe(crop_df)
# Simple stats
st.write("Summary Statistics:")
st.write(crop_df.describe())
# Footer
st.markdown("---")
st.markdown("Built with ❤️ for Kaduna State Ministry of Agriculture")