Spaces:
Sleeping
Sleeping
File size: 3,904 Bytes
c342d58 3f276cc c342d58 3f276cc | 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 | import streamlit as st
import pandas as pd
import numpy as np
import joblib
import holidays
import xgboost as xgb
from datetime import date
# Load the model
@st.cache_resource
def load_artifacts():
model = joblib.load('src/xgb_model.joblib')
encoders = joblib.load('src/encoders.joblib')
return model, encoders
try:
model, encoders = load_artifacts()
except FileNotFoundError:
st.error("Model files not found. Please upload 'xgb_model.joblib' and 'encoders.joblib'.")
st.stop()
# Feature Engineering
def create_features(df):
df = df.copy()
df['date'] = pd.to_datetime(df['date'])
df['year'] = df['date'].dt.year
df['month'] = df['date'].dt.month
df['day'] = df['date'].dt.day
df['day_of_week'] = df['date'].dt.dayofweek
df['day_of_year'] = df['date'].dt.dayofyear
df['week_of_year'] = df['date'].dt.isocalendar().week.astype(int)
df['is_weekend'] = (df['day_of_week'] >= 5).astype(int)
# Cyclical Encoding
df['day_sin'] = np.sin(2 * np.pi * df['day_of_year'] / 365.0)
df['day_cos'] = np.cos(2 * np.pi * df['day_of_year'] / 365.0)
df['month_sin'] = np.sin(2 * np.pi * df['month'] / 12.0)
df['month_cos'] = np.cos(2 * np.pi * df['month'] / 12.0)
return df
def add_holiday_features(df, encoders):
df = df.copy()
# Inverse transform to get country names for holiday library
df['country_name'] = encoders['country'].inverse_transform(df['country'])
years = df['date'].dt.year.unique()
country_codes = {'Canada': 'CA','Finland': 'FI','Italy': 'IT','Kenya': 'KE','Norway': 'NO','Singapore': 'SG'}
df['is_holiday'] = 0
for country_name, code in country_codes.items():
try:
country_holidays = holidays.Country(code, years=years)
mask = (df['country_name'] == country_name) & (df['date'].isin(country_holidays))
df.loc[mask, 'is_holiday'] = 1
except:
continue
df = df.drop(columns=['country_name'])
return df
# UI
st.title("🛒 Sticker Sales Prediction")
st.write("Enter the details below to predict the number of items sold.")
# Input
col1, col2 = st.columns(2)
with col1:
country_options = list(encoders['country'].classes_)
store_options = list(encoders['store'].classes_)
product_options = list(encoders['product'].classes_)
selected_date = st.date_input("Select Date", value=date(2025, 1, 1))
selected_country = st.selectbox("Select Country", country_options)
with col2:
selected_store = st.selectbox("Select Store", store_options)
selected_product = st.selectbox("Select Product", product_options)
# 4. Prediction Button
if st.button("Predict Sales"):
input_data = pd.DataFrame({
'date': [pd.to_datetime(selected_date)],
'country': [selected_country],
'store': [selected_store],
'product': [selected_product]})
processed_data = create_features(input_data)
categorical_cols = ['country', 'store', 'product']
for col in categorical_cols:
processed_data[col] = encoders[col].transform(processed_data[col])
processed_data = add_holiday_features(processed_data, encoders)
features = ['country', 'store', 'product', 'year', 'month', 'day', 'day_of_week', 'day_of_year', 'is_weekend',
'day_sin', 'day_cos', 'month_sin', 'month_cos', 'is_holiday']
X_input = processed_data[features]
# Prediction
try:
pred_log = model.predict(X_input)
final_prediction = np.expm1(pred_log)[0]
final_prediction = max(0, final_prediction) # Ensure no negative sales
st.success(f"Predicted Num Sold: **{final_prediction:.2f}**")
with st.expander("See processed features"):
st.dataframe(X_input)
except Exception as e:
st.error(f"An error occurred during prediction: {e}") |