Spaces:
Sleeping
Sleeping
π Initial upload of my app
Browse files- .gitattributes +2 -0
- LICENSE +21 -0
- README.md +89 -12
- __pycache__/ui.cpython-311.pyc +0 -0
- __pycache__/utils.cpython-311.pyc +0 -0
- app.py +7 -0
- demo/demo.mp4 +3 -0
- demo/demo.png +0 -0
- models/feature_cols.pkl +3 -0
- models/lgb_sales_model.txt +3 -0
- predicting-retail-sales-with-lightgbm-rmse-7.ipynb +0 -0
- requirements.txt +4 -0
- ui.py +28 -0
- utils.py +53 -0
.gitattributes
CHANGED
|
@@ -33,3 +33,5 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
|
|
| 33 |
*.zip filter=lfs diff=lfs merge=lfs -text
|
| 34 |
*.zst filter=lfs diff=lfs merge=lfs -text
|
| 35 |
*tfevents* filter=lfs diff=lfs merge=lfs -text
|
|
|
|
|
|
|
|
|
| 33 |
*.zip filter=lfs diff=lfs merge=lfs -text
|
| 34 |
*.zst filter=lfs diff=lfs merge=lfs -text
|
| 35 |
*tfevents* filter=lfs diff=lfs merge=lfs -text
|
| 36 |
+
demo/demo.mp4 filter=lfs diff=lfs merge=lfs -text
|
| 37 |
+
models/lgb_sales_model.txt filter=lfs diff=lfs merge=lfs -text
|
LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
MIT License
|
| 2 |
+
|
| 3 |
+
Copyright (c) 2025 Eslam Tarek
|
| 4 |
+
|
| 5 |
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
| 6 |
+
of this software and associated documentation files (the "Software"), to deal
|
| 7 |
+
in the Software without restriction, including without limitation the rights
|
| 8 |
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
| 9 |
+
copies of the Software, and to permit persons to whom the Software is
|
| 10 |
+
furnished to do so, subject to the following conditions:
|
| 11 |
+
|
| 12 |
+
The above copyright notice and this permission notice shall be included in all
|
| 13 |
+
copies or substantial portions of the Software.
|
| 14 |
+
|
| 15 |
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
| 16 |
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
| 17 |
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
| 18 |
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
| 19 |
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
| 20 |
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
| 21 |
+
SOFTWARE.
|
README.md
CHANGED
|
@@ -1,12 +1,89 @@
|
|
| 1 |
-
|
| 2 |
-
|
| 3 |
-
|
| 4 |
-
|
| 5 |
-
|
| 6 |
-
|
| 7 |
-
|
| 8 |
-
|
| 9 |
-
|
| 10 |
-
|
| 11 |
-
|
| 12 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Sales Forecasting with LightGBM
|
| 2 |
+
|
| 3 |
+
A retail sales prediction application built with LightGBM and Gradio for interactive forecasting.
|
| 4 |
+
|
| 5 |
+
## π Demo
|
| 6 |
+
|
| 7 |
+

|
| 8 |
+
|
| 9 |
+
[Watch Demo Video](./demo/demo.mp4)
|
| 10 |
+
|
| 11 |
+
## β¨ Features
|
| 12 |
+
|
| 13 |
+
- Interactive web interface for sales prediction
|
| 14 |
+
- Takes into account various features including:
|
| 15 |
+
- Promotional events
|
| 16 |
+
- Holiday status
|
| 17 |
+
- Historical sales data (various lags and rolling means)
|
| 18 |
+
- Temporal features (day, month, year, day of week)
|
| 19 |
+
- Built with LightGBM for fast and accurate predictions
|
| 20 |
+
- Simple and intuitive user interface
|
| 21 |
+
|
| 22 |
+
## π Installation
|
| 23 |
+
|
| 24 |
+
1. Clone the repository:
|
| 25 |
+
```bash
|
| 26 |
+
git clone https://github.com/yourusername/sales-forecasting.git
|
| 27 |
+
cd sales-forecasting
|
| 28 |
+
```
|
| 29 |
+
|
| 30 |
+
2. Create and activate a virtual environment:
|
| 31 |
+
```bash
|
| 32 |
+
# Create a virtual environment
|
| 33 |
+
python -m venv .venv
|
| 34 |
+
|
| 35 |
+
# Activate it
|
| 36 |
+
# On Linux/Mac:
|
| 37 |
+
source .venv/bin/activate
|
| 38 |
+
# On Windows:
|
| 39 |
+
.venv\Scripts\activate
|
| 40 |
+
```
|
| 41 |
+
|
| 42 |
+
3. Install the required dependencies:
|
| 43 |
+
```bash
|
| 44 |
+
pip install -r requirements.txt
|
| 45 |
+
```
|
| 46 |
+
|
| 47 |
+
## π οΈ Usage
|
| 48 |
+
|
| 49 |
+
1. Run the application:
|
| 50 |
+
```bash
|
| 51 |
+
python app.py
|
| 52 |
+
```
|
| 53 |
+
|
| 54 |
+
2. Open your web browser and navigate to the URL shown in the terminal (typically http://localhost:7860)
|
| 55 |
+
|
| 56 |
+
3. Input the required information:
|
| 57 |
+
- Promo status (0 or 1)
|
| 58 |
+
- Holiday status (0 or 1)
|
| 59 |
+
- Date in YYYY-MM-DD format
|
| 60 |
+
- Sales lags and rolling means
|
| 61 |
+
|
| 62 |
+
4. Click "Predict Sales" to see the prediction
|
| 63 |
+
|
| 64 |
+
## π¦ Dependencies
|
| 65 |
+
|
| 66 |
+
- gradio >= 3.50.0
|
| 67 |
+
- joblib >= 1.3.0
|
| 68 |
+
- lightgbm >= 4.0.0
|
| 69 |
+
- pandas >= 2.0.0
|
| 70 |
+
|
| 71 |
+
## π€ Contributing
|
| 72 |
+
|
| 73 |
+
Contributions are welcome! Please feel free to submit a Pull Request.
|
| 74 |
+
|
| 75 |
+
1. Fork the repository
|
| 76 |
+
2. Create your feature branch (`git checkout -b feature/AmazingFeature`)
|
| 77 |
+
3. Commit your changes (`git commit -m 'Add some AmazingFeature'`)
|
| 78 |
+
4. Push to the branch (`git push origin feature/AmazingFeature`)
|
| 79 |
+
5. Open a Pull Request
|
| 80 |
+
|
| 81 |
+
## π License
|
| 82 |
+
|
| 83 |
+
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
|
| 84 |
+
|
| 85 |
+
## π Acknowledgements
|
| 86 |
+
|
| 87 |
+
- [LightGBM](https://github.com/microsoft/LightGBM) - The gradient boosting framework used for predictions
|
| 88 |
+
- [Gradio](https://gradio.app/) - For the simple web interface
|
| 89 |
+
- [Pandas](https://pandas.pydata.org/) - For data manipulation and analysis
|
__pycache__/ui.cpython-311.pyc
ADDED
|
Binary file (2.49 kB). View file
|
|
|
__pycache__/utils.cpython-311.pyc
ADDED
|
Binary file (2.28 kB). View file
|
|
|
app.py
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from utils import load_artifacts, predict_sales
|
| 2 |
+
from ui import build_ui
|
| 3 |
+
|
| 4 |
+
if __name__ == "__main__":
|
| 5 |
+
model, feature_cols = load_artifacts()
|
| 6 |
+
iface = build_ui(model, feature_cols, predict_sales)
|
| 7 |
+
iface.launch()
|
demo/demo.mp4
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:709f027723ef11b7699671bfb67b904580a63b70330dbef4069ffed351f4af8f
|
| 3 |
+
size 896228
|
demo/demo.png
ADDED
|
models/feature_cols.pkl
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:0864e6b46775ccc0e558809c789734531d61e640572fbb6583340ce0b02edd75
|
| 3 |
+
size 144
|
models/lgb_sales_model.txt
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:2eac4686b692c0ebfa95e257afc6051d69a727193caa9726c160b0082e06a7fe
|
| 3 |
+
size 14242166
|
predicting-retail-sales-with-lightgbm-rmse-7.ipynb
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
requirements.txt
ADDED
|
@@ -0,0 +1,4 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
gradio>=3.50.0
|
| 2 |
+
joblib>=1.3.0
|
| 3 |
+
lightgbm>=4.0.0
|
| 4 |
+
pandas>=2.0.0
|
ui.py
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import gradio as gr
|
| 2 |
+
|
| 3 |
+
def build_ui(model, feature_cols, predict_fn):
|
| 4 |
+
with gr.Blocks() as demo:
|
| 5 |
+
gr.Markdown("## π Retail Sales Prediction App")
|
| 6 |
+
|
| 7 |
+
with gr.Row():
|
| 8 |
+
promo = gr.Radio([0, 1], label="Promo", value=0)
|
| 9 |
+
holiday = gr.Radio([0, 1], label="Holiday", value=0)
|
| 10 |
+
|
| 11 |
+
date = gr.Textbox(label="Date (YYYY-MM-DD)", value="2023-11-01")
|
| 12 |
+
|
| 13 |
+
with gr.Row():
|
| 14 |
+
lag_1 = gr.Number(label="Sales Lag 1 Day", value=100)
|
| 15 |
+
lag_7 = gr.Number(label="Sales Lag 7 Days", value=120)
|
| 16 |
+
mean_3 = gr.Number(label="Rolling Mean (3 Days)", value=110)
|
| 17 |
+
mean_7 = gr.Number(label="Rolling Mean (7 Days)", value=115)
|
| 18 |
+
|
| 19 |
+
predict_btn = gr.Button("Predict Sales")
|
| 20 |
+
output = gr.Number(label="Predicted Sales", precision=2)
|
| 21 |
+
|
| 22 |
+
predict_btn.click(
|
| 23 |
+
fn=lambda p, h, d, l1, l7, m3, m7: predict_fn(model, feature_cols, p, h, d, l1, l7, m3, m7),
|
| 24 |
+
inputs=[promo, holiday, date, lag_1, lag_7, mean_3, mean_7],
|
| 25 |
+
outputs=output
|
| 26 |
+
)
|
| 27 |
+
|
| 28 |
+
return demo
|
utils.py
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import joblib
|
| 2 |
+
import lightgbm as lgb
|
| 3 |
+
import pandas as pd
|
| 4 |
+
|
| 5 |
+
# Load artifacts
|
| 6 |
+
def load_artifacts():
|
| 7 |
+
model = lgb.Booster(model_file="models/lgb_sales_model.txt")
|
| 8 |
+
feature_cols = joblib.load("models/feature_cols.pkl")
|
| 9 |
+
return model, feature_cols
|
| 10 |
+
|
| 11 |
+
# Preprocess new input row into model-ready features
|
| 12 |
+
def preprocess_input(promo, holiday, date, past_sales):
|
| 13 |
+
"""
|
| 14 |
+
Args:
|
| 15 |
+
|
| 16 |
+
promo: int (0/1)
|
| 17 |
+
holiday: int (0/1)
|
| 18 |
+
date: datetime-like
|
| 19 |
+
past_sales: dict with keys ['lag_1','lag_7','mean_3','mean_7']
|
| 20 |
+
|
| 21 |
+
Returns:
|
| 22 |
+
pd.DataFrame with a single row ready for prediction
|
| 23 |
+
"""
|
| 24 |
+
date = pd.to_datetime(date)
|
| 25 |
+
|
| 26 |
+
features = {
|
| 27 |
+
"promo": promo,
|
| 28 |
+
"holiday": holiday,
|
| 29 |
+
"day": date.day,
|
| 30 |
+
"month": date.month,
|
| 31 |
+
"year": date.year,
|
| 32 |
+
"day_of_week": date.weekday(),
|
| 33 |
+
"is_weekend": 1 if date.weekday() >= 5 else 0,
|
| 34 |
+
"sales_lag_1": past_sales.get("lag_1", 0),
|
| 35 |
+
"sales_lag_7": past_sales.get("lag_7", 0),
|
| 36 |
+
"rolling_mean_3": past_sales.get("mean_3", 0),
|
| 37 |
+
"rolling_mean_7": past_sales.get("mean_7", 0),
|
| 38 |
+
}
|
| 39 |
+
|
| 40 |
+
return pd.DataFrame([features])
|
| 41 |
+
|
| 42 |
+
# Prediction
|
| 43 |
+
def predict_sales(model, feature_cols, promo, holiday, date, lag_1, lag_7, mean_3, mean_7):
|
| 44 |
+
past_sales = {
|
| 45 |
+
"lag_1": lag_1,
|
| 46 |
+
"lag_7": lag_7,
|
| 47 |
+
"mean_3": mean_3,
|
| 48 |
+
"mean_7": mean_7,
|
| 49 |
+
}
|
| 50 |
+
X = preprocess_input(promo, holiday, date, past_sales)
|
| 51 |
+
X = X[feature_cols] # ensure correct column order
|
| 52 |
+
prediction = model.predict(X)[0]
|
| 53 |
+
return round(prediction, 2)
|