Spaces:
Sleeping
Sleeping
| 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() | |