File size: 3,594 Bytes
3e780fd
 
 
 
649bcdc
3e780fd
649bcdc
 
 
 
 
 
 
 
 
 
 
3e780fd
 
 
 
 
649bcdc
 
 
3e780fd
 
 
 
 
649bcdc
3e780fd
 
 
 
 
 
 
 
 
 
 
 
 
649bcdc
3e780fd
 
 
 
649bcdc
 
 
3e780fd
 
 
 
 
 
 
 
 
 
 
649bcdc
3e780fd
 
 
 
 
 
 
649bcdc
3e780fd
 
 
 
 
649bcdc
 
 
3e780fd
649bcdc
 
 
 
 
 
3e780fd
649bcdc
 
 
 
3e780fd
 
 
649bcdc
 
 
3e780fd
 
 
 
 
 
 
649bcdc
 
 
3e780fd
649bcdc
 
3e780fd
 
649bcdc
 
3e780fd
 
 
 
 
 
 
 
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
import pandas as pd
import gradio as gr
import matplotlib.pyplot as plt
from statsmodels.tsa.arima.model import ARIMA
import os

# =========================
# Load dataset safely
# =========================
DATA_PATH = "train.csv"

if not os.path.exists(DATA_PATH):
    raise FileNotFoundError(
        "train.csv not found. Please upload train.csv to the Hugging Face Space root directory."
    )

df = pd.read_csv(DATA_PATH)
df["date"] = pd.to_datetime(df["date"])

stores = sorted(df["store"].unique())
items = sorted(df["item"].unique())

# =========================
# Forecast single store-item
# =========================
def forecast_single(store_id, item_id, days):
    data = df[(df["store"] == store_id) & (df["item"] == item_id)]
    data = data[["date", "sales"]].sort_values("date")

    if len(data) < 50:
        return None, None, "❌ Not enough data for forecasting"

    ts = data.set_index("date")["sales"]

    model = ARIMA(ts, order=(1, 1, 1))
    model_fit = model.fit()
    forecast = model_fit.forecast(steps=days)

    forecast_df = forecast.reset_index()
    forecast_df.columns = ["Date", "Forecasted_Sales"]

    fig, ax = plt.subplots()
    ax.plot(ts, label="Historical Sales")
    ax.plot(forecast, label="Forecast")
    ax.set_title(f"Store {store_id} – Item {item_id}")
    ax.legend()

    return forecast_df, fig, forecast_df

# =========================
# Forecast ALL stores for one item
# =========================
def forecast_all_stores(item_id, days):
    results = []

    for store_id in stores:
        data = df[(df["store"] == store_id) & (df["item"] == item_id)]
        data = data[["date", "sales"]].sort_values("date")

        if len(data) < 50:
            continue

        ts = data.set_index("date")["sales"]

        model = ARIMA(ts, order=(1, 1, 1))
        model_fit = model.fit()
        forecast = model_fit.forecast(steps=days)

        forecast_df = forecast.reset_index()
        forecast_df.columns = ["Date", "Forecasted_Sales"]
        forecast_df["Store"] = store_id

        results.append(forecast_df)

    final_df = pd.concat(results)
    return final_df, final_df

# =========================
# Gradio UI
# =========================
with gr.Blocks() as demo:
    gr.Markdown("# 📊 Demand Forecasting Tool")
    gr.Markdown(
        "Forecast demand for any **Store–Item combination** using historical sales data."
    )

    gr.Markdown("## 🔹 Forecast for Single Store & Item")

    with gr.Row():
        store = gr.Dropdown(stores, label="Select Store", value=stores[0])
        item = gr.Dropdown(items, label="Select Item", value=items[0])
        days = gr.Slider(7, 90, value=30, label="Forecast Horizon (Days)")

    run_single = gr.Button("Generate Forecast")

    table_single = gr.Dataframe(label="Forecast Table")
    plot_single = gr.Plot(label="Forecast Chart")
    download_single = gr.File(label="Download CSV")

    run_single.click(
        forecast_single,
        inputs=[store, item, days],
        outputs=[table_single, plot_single, download_single]
    )

    gr.Markdown("---")
    gr.Markdown("## 🔁 Forecast One Item Across ALL Stores")

    item_all = gr.Dropdown(items, label="Select Item")
    days_all = gr.Slider(7, 90, value=30, label="Forecast Horizon (Days)")

    run_all = gr.Button("Forecast All Stores")

    table_all = gr.Dataframe(label="All Stores Forecast")
    download_all = gr.File(label="Download Combined CSV")

    run_all.click(
        forecast_all_stores,
        inputs=[item_all, days_all],
        outputs=[table_all, download_all]
    )

demo.launch()