File size: 4,514 Bytes
7c92f4d 4ea946f | 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 | import gradio as gr
import pandas as pd
from prophet import Prophet
import matplotlib.pyplot as plt
def forecast_sales(file):
# Load the sales data
sales_data = pd.read_csv(file.name)
# Convert date column to datetime
sales_data['date'] = pd.to_datetime(sales_data['date'])
# Prepare the data for Prophet with additional regressors
prophet_data = sales_data[['date', 'sales', 'orders', 'goog_upper_spend', 'fb_upper', 'search_spend', 'brand_spend', 'shopping_spend', 'fb_spend', 'pinterest_spend', 'tiktok', 'RTB_Spend', 'venta_buen_fin', 'venta_hot_sale']].rename(columns={'date': 'ds', 'sales': 'y'})
# Fill missing values with the mean of the respective columns
prophet_data.fillna(prophet_data.mean(), inplace=True)
# Initialize the Prophet model with additional regressors
model = Prophet()
# Add additional regressors
regressors = ['orders', 'goog_upper_spend', 'fb_upper', 'search_spend', 'brand_spend', 'shopping_spend', 'fb_spend', 'pinterest_spend', 'tiktok', 'RTB_Spend', 'venta_buen_fin', 'venta_hot_sale']
for regressor in regressors:
model.add_regressor(regressor)
# Fit the model
model.fit(prophet_data)
# Create a dataframe for future dates with additional regressors
future = model.make_future_dataframe(periods=30)
future = future.merge(sales_data[['date'] + regressors].set_index('date'), left_on='ds', right_index=True, how='left')
future.fillna(future.mean(), inplace=True)
# Predict the future sales
forecast = model.predict(future)
# Plot the forecast
fig1, ax1 = plt.subplots()
model.plot(forecast, ax=ax1)
ax1.set_title('Sales Forecast with Additional Regressors')
ax1.set_xlabel('Date')
ax1.set_ylabel('Sales')
# Merge the forecasted sales with the actual sales data for comparison
comparison_df = pd.merge(forecast[['ds', 'yhat']], prophet_data, left_on='ds', right_on='ds', how='left')
comparison_df.rename(columns={'yhat': 'forecasted_sales', 'y': 'actual_sales'}, inplace=True)
# Resample the comparison dataframe to monthly frequency and calculate the mean sales for each month
monthly_comparison_df = comparison_df.resample('M', on='ds').mean()
# Filter the monthly comparison dataframe to show only the last 12 months
last_12_months_df = monthly_comparison_df.tail(12)
# Calculate the percentage difference between actual and forecasted sales for the last 12 months
last_12_months_df['percentage_difference'] = ((last_12_months_df['actual_sales'] - last_12_months_df['forecasted_sales']) / last_12_months_df['actual_sales']) * 100
# Drop rows with NaN values in 'actual_sales'
last_12_months_df = last_12_months_df.dropna(subset=['actual_sales'])
# Plot the monthly comparison with bar charts and the percentage difference on top
fig2, ax2 = plt.subplots(figsize=(14, 7))
bar_width = 15 # Set the bar width
# Plot actual sales bars
bars_actual = ax2.bar(last_12_months_df.index, last_12_months_df['actual_sales'],
width=bar_width, label='Actual Sales', color='black', alpha=0.7)
# Plot forecasted sales bars
bars_forecasted = ax2.bar(last_12_months_df.index + pd.DateOffset(days=15),
last_12_months_df['forecasted_sales'], width=bar_width,
label='Forecasted Sales', color='blue', alpha=0.7)
# Add the percentage difference on top of the bars
for bar, diff in zip(bars_actual, last_12_months_df['percentage_difference']):
height = bar.get_height()
ax2.text(bar.get_x() + bar.get_width() / 2.0, height, f'{diff:.2f}%', ha='center', va='bottom', color='red')
ax2.set_title('Monthly Actual vs Forecasted Sales with Percentage Difference (Last 12 Months)')
ax2.set_xlabel('Date')
ax2.set_ylabel('Sales')
ax2.legend()
# Save the comparison dataframe to a CSV
last_12_months_df.to_csv('forecast_comparison.csv')
return fig1, fig2, 'forecast_comparison.csv'
# Define the Gradio interface
interface = gr.Interface(
fn=forecast_sales,
inputs=gr.File(label="Upload CSV File"),
outputs=[
gr.Plot(label="Sales Forecast"),
gr.Plot(label="Monthly Comparison"),
gr.File(label="Comparison CSV")
],
title="Sales Forecasting with Prophet",
description="Upload a CSV file with sales data to forecast future sales and compare with actual sales."
)
# Launch the interface
interface.launch(share=True)
|