Predictive / app.py
SowmiyaNagaraj's picture
Update app.py
5d17b66 verified
import gradio as gr
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
import io
from sklearn.preprocessing import MinMaxScaler
from statsmodels.tsa.arima.model import ARIMA
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import LSTM, Dense, Dropout
import warnings
warnings.filterwarnings("ignore")
# Function to check data complexity
def is_complex(data):
variance = np.var(data)
return variance > 1000000
# Function to create dataset for LSTM
def create_dataset(dataset, time_step=1):
X, y = [], []
for i in range(len(dataset) - time_step - 1):
X.append(dataset[i:(i + time_step), 0])
y.append(dataset[i + time_step, 0])
return np.array(X), np.array(y)
def forecast_sales(file):
# Read CSV
data = pd.read_csv(GlobalTech_Inc_SalesData.csv)
# Clean data
data = data.dropna()
data['Order Date'] = pd.to_datetime(data['Order Date'])
data['Total Sales'] = pd.to_numeric(data['Total Sales'], errors='coerce')
data = data.drop_duplicates().sort_values(by='Order Date')
# Forecasting
time_step = 10
forecast_type = ""
if is_complex(data['Total Sales']):
forecast_type = "LSTM"
elif len(data) < 30:
forecast_type = "ARIMA"
else:
forecast_type = "Hybrid"
# Prepare forecasting
if forecast_type == "LSTM":
scaler = MinMaxScaler()
scaled_data = scaler.fit_transform(data[['Total Sales']])
X, y = create_dataset(scaled_data, time_step)
X = X.reshape(X.shape[0], X.shape[1], 1)
lstm_model = Sequential([
LSTM(50, return_sequences=True, input_shape=(X.shape[1], 1)),
Dropout(0.2),
LSTM(50),
Dropout(0.2),
Dense(1)
])
lstm_model.compile(optimizer='adam', loss='mean_squared_error')
lstm_model.fit(X, y, epochs=5, batch_size=32, verbose=0)
lstm_predictions = lstm_model.predict(X)
lstm_predictions = scaler.inverse_transform(lstm_predictions)
forecast = pd.DataFrame({
'Date': pd.date_range(start=data['Order Date'].iloc[-1], periods=len(lstm_predictions), freq='D'),
'Forecasted_Sales': lstm_predictions.flatten()
})
elif forecast_type == "ARIMA":
arima_model = ARIMA(data['Total Sales'], order=(5, 1, 0))
arima_result = arima_model.fit()
arima_forecast = arima_result.forecast(steps=30)
forecast = pd.DataFrame({
'Date': pd.date_range(start=data['Order Date'].iloc[-1], periods=len(arima_forecast), freq='D'),
'Forecasted_Sales': arima_forecast.flatten()
})
else: # Hybrid
arima_model = ARIMA(data['Total Sales'], order=(5, 1, 0))
arima_result = arima_model.fit()
arima_forecast = arima_result.forecast(steps=30)
scaler = MinMaxScaler()
scaled_data = scaler.fit_transform(data[['Total Sales']])
X, y = create_dataset(scaled_data, time_step)
X = X.reshape(X.shape[0], X.shape[1], 1)
lstm_model = Sequential([
LSTM(50, return_sequences=True, input_shape=(X.shape[1], 1)),
Dropout(0.2),
LSTM(50),
Dropout(0.2),
Dense(1)
])
lstm_model.compile(optimizer='adam', loss='mean_squared_error')
lstm_model.fit(X, y, epochs=5, batch_size=32, verbose=0)
lstm_predictions = lstm_model.predict(X)
lstm_predictions = scaler.inverse_transform(lstm_predictions)
hybrid_forecast = arima_forecast.flatten() + lstm_predictions.flatten()[:len(arima_forecast)]
forecast = pd.DataFrame({
'Date': pd.date_range(start=data['Order Date'].iloc[-1], periods=len(hybrid_forecast), freq='D'),
'Forecasted_Sales': hybrid_forecast
})
# Merge for forecast by product
data_with_forecast = pd.merge(data, forecast, left_on='Order Date', right_on='Date', how='left')
product_sales_forecast = data_with_forecast.groupby('Product Name')['Forecasted_Sales'].sum().reset_index()
product_sales_forecast = product_sales_forecast.sort_values(by='Forecasted_Sales', ascending=False)
top_product = product_sales_forecast.iloc[0]
# Plot
fig, ax = plt.subplots(figsize=(10, 6))
sns.barplot(x='Product Name', y='Forecasted_Sales', data=product_sales_forecast, ax=ax, palette='coolwarm')
plt.xticks(rotation=45)
plt.title("Forecasted Sales by Product")
plt.tight_layout()
# Save image
img = io.BytesIO()
plt.savefig(img, format='png')
plt.close()
img.seek(0)
return f"Forecast Model Used: {forecast_type}\nTop-Selling Product: {top_product['Product Name']} with Forecasted Sales: {top_product['Forecasted_Sales']:.2f}", img
# Gradio Interface
interface = gr.Interface(
fn=forecast_sales,
inputs=gr.File(label="Upload Sales CSV File"),
outputs=["text", gr.Image(type="pil")],
title="Sales Forecasting App",
description="Upload a CSV file with columns: Order Date, Product Name, Total Sales to forecast sales and identify top-selling products."
)
if __name__ == "__main__":
interface.launch()