import streamlit as st
import requests
import pandas as pd
import numpy as np
import plotly.express as px
import plotly.graph_objects as go
from datetime import datetime
# Page configuration
st.set_page_config(
page_title="SuperKart Sales Forecasting",
page_icon="🛒",
layout="wide",
initial_sidebar_state="expanded"
)
# Custom CSS
st.markdown("""
""", unsafe_allow_html=True)
# API Configuration
API_BASE_URL = "https://ananttripathiak-superkart-akt.hf.space/" # Replace with your actual URL
# Helper functions
def make_prediction(data):
"""Make prediction using the API"""
try:
response = requests.post(f"{API_BASE_URL}/predict", json=data, timeout=30)
if response.status_code == 200:
return response.json()
else:
return {"error": f"API Error: {response.status_code}"}
except requests.exceptions.RequestException as e:
return {"error": f"Connection Error: {str(e)}"}
def make_batch_prediction(data_list):
"""Make batch prediction using the API"""
try:
response = requests.post(f"{API_BASE_URL}/batch_predict",
json={"data": data_list}, timeout=60)
if response.status_code == 200:
return response.json()
else:
return {"error": f"API Error: {response.status_code}"}
except requests.exceptions.RequestException as e:
return {"error": f"Connection Error: {str(e)}"}
# Main app
def main():
# Header
st.markdown('
🛒 SuperKart Sales Forecasting
',
unsafe_allow_html=True)
# Sidebar
st.sidebar.title("Navigation")
page = st.sidebar.selectbox("Choose a page",
["Single Prediction", "Batch Prediction", "Data Analysis", "About"])
if page == "Single Prediction":
single_prediction_page()
elif page == "Batch Prediction":
batch_prediction_page()
elif page == "Data Analysis":
data_analysis_page()
elif page == "About":
about_page()
def single_prediction_page():
st.header("Single Product Sales Prediction")
st.markdown("Predict sales revenue for a single product-store combination.")
col1, col2 = st.columns([1, 1])
with col1:
st.subheader("Product Information")
product_weight = st.number_input("Product Weight", min_value=0.1, max_value=100.0, value=12.5, step=0.1)
product_sugar_content = st.selectbox("Sugar Content",
["Low Sugar", "Regular", "No Sugar"])
product_allocated_area = st.slider("Allocated Area Ratio", 0.001, 0.5, 0.05, 0.001)
product_type = st.selectbox("Product Type",
["Frozen Foods", "Dairy", "Canned", "Baking Goods", "Health and Hygiene",
"Snack Foods", "Meat", "Household", "Soft Drinks", "Hard Drinks",
"Bread", "Breakfast", "Fruits and Vegetables", "Seafood",
"Starchy Foods", "Others"])
product_mrp = st.number_input("Product MRP", min_value=10.0, max_value=1000.0, value=100.0, step=1.0)
with col2:
st.subheader("Store Information")
store_establishment_year = st.number_input("Store Establishment Year",
min_value=1980, max_value=2024, value=2010)
store_size = st.selectbox("Store Size", ["High", "Medium", "Small"])
store_location_city_type = st.selectbox("City Type", ["Tier 1", "Tier 2", "Tier 3"])
store_type = st.selectbox("Store Type",
["Departmental Store", "Supermarket Type1",
"Supermarket Type2", "Food Mart"])
# Prediction button
if st.button("Predict Sales", type="primary"):
# Prepare data
input_data = {
"Product_Weight": product_weight,
"Product_Sugar_Content": product_sugar_content,
"Product_Allocated_Area": product_allocated_area,
"Product_Type": product_type,
"Product_MRP": product_mrp,
"Store_Establishment_Year": store_establishment_year,
"Store_Size": store_size,
"Store_Location_City_Type": store_location_city_type,
"Store_Type": store_type
}
# Make prediction
with st.spinner("Making prediction..."):
result = make_prediction(input_data)
if "error" in result:
st.error(f"Error: {result['error']}")
else:
prediction = result["prediction"]
st.markdown(f"""
Predicted Sales Revenue
₹{prediction:,.2f}
""", unsafe_allow_html=True)
# Additional insights
st.subheader("Insights")
col1, col2, col3 = st.columns(3)
with col1:
st.metric("Revenue per Unit Weight", f"₹{prediction/product_weight:.2f}")
with col2:
st.metric("Revenue per MRP", f"₹{prediction/product_mrp:.2f}")
with col3:
st.metric("Revenue per Area", f"₹{prediction/product_allocated_area:.2f}")
def batch_prediction_page():
st.header("Batch Sales Prediction")
st.markdown("Upload a CSV file or enter data manually for batch predictions.")
# File upload option
uploaded_file = st.file_uploader("Upload CSV file", type=['csv'])
if uploaded_file is not None:
try:
df = pd.read_csv(uploaded_file)
st.subheader("Uploaded Data Preview")
st.dataframe(df.head())
# Validate columns
required_columns = [
'Product_Weight', 'Product_Sugar_Content', 'Product_Allocated_Area',
'Product_Type', 'Product_MRP', 'Store_Establishment_Year',
'Store_Size', 'Store_Location_City_Type', 'Store_Type'
]
missing_columns = [col for col in required_columns if col not in df.columns]
if missing_columns:
st.error(f"Missing required columns: {missing_columns}")
else:
if st.button("Predict All", type="primary"):
with st.spinner("Making batch predictions..."):
data_list = df[required_columns].to_dict('records')
result = make_batch_predictions(data_list)
if "error" in result:
st.error(f"Error: {result['error']}")
else:
predictions = result["predictions"]
df['Predicted_Sales'] = predictions
st.subheader("Predictions Results")
st.dataframe(df)
# Download results
csv = df.to_csv(index=False)
st.download_button(
label="Download Results as CSV",
data=csv,
file_name=f"predictions_{datetime.now().strftime('%Y%m%d_%H%M%S')}.csv",
mime="text/csv"
)
except Exception as e:
st.error(f"Error reading file: {str(e)}")
# Manual data entry
st.subheader("Manual Data Entry")
st.markdown("Add rows manually for batch prediction")
# Initialize session state for manual data
if 'manual_data' not in st.session_state:
st.session_state.manual_data = []
# Add new row form
with st.form("add_row_form"):
col1, col2 = st.columns(2)
with col1:
weight = st.number_input("Product Weight", min_value=0.1, max_value=100.0, value=12.5, step=0.1, key="weight")
sugar_content = st.selectbox("Sugar Content", ["Low Sugar", "Regular", "No Sugar"], key="sugar")
allocated_area = st.slider("Allocated Area", 0.001, 0.5, 0.05, 0.001, key="area")
product_type = st.selectbox("Product Type",
["Frozen Foods", "Dairy", "Canned", "Baking Goods", "Health and Hygiene",
"Snack Foods", "Meat", "Household", "Soft Drinks", "Hard Drinks",
"Bread", "Breakfast", "Fruits and Vegetables", "Seafood",
"Starchy Foods", "Others"], key="type")
mrp = st.number_input("Product MRP", min_value=10.0, max_value=1000.0, value=100.0, step=1.0, key="mrp")
with col2:
establishment_year = st.number_input("Store Establishment Year",
min_value=1980, max_value=2024, value=2010, key="year")
size = st.selectbox("Store Size", ["High", "Medium", "Small"], key="size")
city_type = st.selectbox("City Type", ["Tier 1", "Tier 2", "Tier 3"], key="city")
store_type = st.selectbox("Store Type",
["Departmental Store", "Supermarket Type1",
"Supermarket Type2", "Food Mart"], key="store")
if st.form_submit_button("Add Row"):
new_row = {
'Product_Weight': weight,
'Product_Sugar_Content': sugar_content,
'Product_Allocated_Area': allocated_area,
'Product_Type': product_type,
'Product_MRP': mrp,
'Store_Establishment_Year': establishment_year,
'Store_Size': size,
'Store_Location_City_Type': city_type,
'Store_Type': store_type
}
st.session_state.manual_data.append(new_row)
st.success("Row added successfully!")
# Display manual data
if st.session_state.manual_data:
st.subheader("Manual Data")
manual_df = pd.DataFrame(st.session_state.manual_data)
st.dataframe(manual_df)
col1, col2 = st.columns(2)
with col1:
if st.button("Predict Manual Data", type="primary"):
with st.spinner("Making predictions..."):
result = make_batch_predictions(st.session_state.manual_data)
if "error" in result:
st.error(f"Error: {result['error']}")
else:
predictions = result["predictions"]
manual_df['Predicted_Sales'] = predictions
st.subheader("Predictions Results")
st.dataframe(manual_df)
with col2:
if st.button("Clear Data"):
st.session_state.manual_data = []
st.rerun()
def data_analysis_page():
st.header("Data Analysis Dashboard")
st.markdown("Explore the SuperKart dataset and model insights.")
# Sample data for analysis (you can load actual data here)
st.subheader("Dataset Overview")
# Create sample data for demonstration
np.random.seed(42)
sample_data = {
'Product_Type': np.random.choice(['Frozen Foods', 'Dairy', 'Canned', 'Baking Goods'], 100),
'Store_Size': np.random.choice(['High', 'Medium', 'Small'], 100),
'Store_Location_City_Type': np.random.choice(['Tier 1', 'Tier 2', 'Tier 3'], 100),
'Product_MRP': np.random.normal(150, 50, 100),
'Product_Weight': np.random.normal(15, 5, 100),
'Predicted_Sales': np.random.normal(3000, 1000, 100)
}
df_sample = pd.DataFrame(sample_data)
# Metrics
col1, col2, col3, col4 = st.columns(4)
with col1:
st.metric("Total Products", len(df_sample))
with col2:
st.metric("Average Sales", f"₹{df_sample['Predicted_Sales'].mean():,.0f}")
with col3:
st.metric("Max Sales", f"₹{df_sample['Predicted_Sales'].max():,.0f}")
with col4:
st.metric("Min Sales", f"₹{df_sample['Predicted_Sales'].min():,.0f}")
# Charts
col1, col2 = st.columns(2)
with col1:
# Sales by Product Type
fig1 = px.bar(df_sample.groupby('Product_Type')['Predicted_Sales'].mean().reset_index(),
x='Product_Type', y='Predicted_Sales',
title='Average Sales by Product Type')
st.plotly_chart(fig1, use_container_width=True)
with col2:
# Sales by Store Size
fig2 = px.pie(df_sample.groupby('Store_Size')['Predicted_Sales'].sum().reset_index(),
values='Predicted_Sales', names='Store_Size',
title='Sales Distribution by Store Size')
st.plotly_chart(fig2, use_container_width=True)
# Scatter plot
fig3 = px.scatter(df_sample, x='Product_MRP', y='Predicted_Sales',
color='Store_Location_City_Type',
title='Sales vs Product MRP by City Type')
st.plotly_chart(fig3, use_container_width=True)
def about_page():
st.header("About SuperKart Sales Forecasting")
st.markdown("""
## Overview
This application provides sales forecasting for SuperKart retail stores using machine learning models.
## Features
- **Single Prediction**: Predict sales for individual product-store combinations
- **Batch Prediction**: Process multiple predictions at once
- **Data Analysis**: Explore sales patterns and insights
- **Real-time API**: Fast predictions using deployed ML models
## Model Information
The forecasting model uses ensemble learning techniques including:
- Random Forest
- XGBoost
- Gradient Boosting
- Decision Trees
## Data Features
- Product characteristics (weight, sugar content, type, MRP)
- Store information (size, location, type, establishment year)
- Allocated display area
## API Endpoints
- `POST /predict` - Single prediction
- `POST /batch_predict` - Batch predictions
- `GET /health` - Health check
## Contact
For questions or support, please contact the development team.
""")
st.subheader("Model Performance")
col1, col2 = st.columns(2)
with col1:
st.metric("R² Score", "0.85+")
st.metric("RMSE", "< 500")
with col2:
st.metric("MAE", "< 300")
st.metric("MAPE", "< 15%")
if __name__ == "__main__":
main()