Spaces:
Sleeping
Sleeping
Create app.py
Browse files
app.py
ADDED
@@ -0,0 +1,145 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import gradio as gr
|
2 |
+
import pandas as pd
|
3 |
+
import numpy as np
|
4 |
+
from statsmodels.tsa.arima.model import ARIMA
|
5 |
+
from sklearn.metrics import mean_squared_error, mean_absolute_error
|
6 |
+
import matplotlib.pyplot as plt
|
7 |
+
import io
|
8 |
+
import base64
|
9 |
+
|
10 |
+
# Load and preprocess data
|
11 |
+
def load_data():
|
12 |
+
df = pd.read_csv("data (3).csv", skiprows=2, header=None)
|
13 |
+
header_df = pd.read_csv("data (3).csv", nrows=2, header=None)
|
14 |
+
|
15 |
+
column_names = ['PN', 'Dummy_Project'] + [
|
16 |
+
f"{header_df.iloc[0, i]}_{header_df.iloc[1, i]}" for i in range(2, len(header_df.columns))
|
17 |
+
]
|
18 |
+
|
19 |
+
df.columns = column_names
|
20 |
+
id_vars = ['PN', 'Dummy_Project']
|
21 |
+
value_vars = column_names[2:]
|
22 |
+
|
23 |
+
df_long = df.melt(
|
24 |
+
id_vars=id_vars,
|
25 |
+
value_vars=value_vars,
|
26 |
+
var_name='Time_Period',
|
27 |
+
value_name='y'
|
28 |
+
)
|
29 |
+
|
30 |
+
df_long[['Year', 'Month']] = df_long['Time_Period'].str.split('_', expand=True)
|
31 |
+
df_long.drop(columns=['Time_Period'], inplace=True)
|
32 |
+
df_long['Year'] = df_long['Year'].astype(int)
|
33 |
+
df_long['Month'] = df_long['Month'].astype(str)
|
34 |
+
|
35 |
+
df_long['Date'] = pd.to_datetime(
|
36 |
+
df_long['Year'].astype(str) + '-' + df_long['Month'] + '-01',
|
37 |
+
format='%Y-%b-%d',
|
38 |
+
errors='coerce'
|
39 |
+
)
|
40 |
+
|
41 |
+
df_long.dropna(subset=['y'], inplace=True)
|
42 |
+
df_long.reset_index(drop=True, inplace=True)
|
43 |
+
|
44 |
+
return df_long
|
45 |
+
|
46 |
+
# Get available part numbers
|
47 |
+
def get_part_numbers(df):
|
48 |
+
return df['PN'].unique().tolist()
|
49 |
+
|
50 |
+
# Train ARIMA model and make predictions
|
51 |
+
def train_arima(series, order=(5,1,0)):
|
52 |
+
model = ARIMA(series, order=order)
|
53 |
+
model_fit = model.fit()
|
54 |
+
forecast = model_fit.forecast(steps=10)
|
55 |
+
return model_fit, forecast
|
56 |
+
|
57 |
+
# Create plot
|
58 |
+
def create_plot(historical, forecast):
|
59 |
+
plt.figure(figsize=(12, 6))
|
60 |
+
plt.plot(historical.index, historical, label='Historical')
|
61 |
+
plt.plot(range(len(historical), len(historical) + len(forecast)), forecast,
|
62 |
+
label='Forecast', color='orange')
|
63 |
+
plt.legend()
|
64 |
+
plt.title('Time Series Forecast')
|
65 |
+
plt.xlabel('Time Period')
|
66 |
+
plt.ylabel('Value')
|
67 |
+
|
68 |
+
# Convert plot to base64 for Gradio
|
69 |
+
buf = io.BytesIO()
|
70 |
+
plt.savefig(buf, format='png')
|
71 |
+
buf.seek(0)
|
72 |
+
img_str = base64.b64encode(buf.read()).decode('utf-8')
|
73 |
+
buf.close()
|
74 |
+
|
75 |
+
return f'<img src="data:image/png;base64,{img_str}" />'
|
76 |
+
|
77 |
+
# Main prediction function
|
78 |
+
def predict(part_number, model_name):
|
79 |
+
df = load_data()
|
80 |
+
df_part = df[df['PN'] == part_number].copy()
|
81 |
+
|
82 |
+
# Prepare time series data
|
83 |
+
start_date = '2021-10-09'
|
84 |
+
date_range = pd.date_range(start=start_date, periods=len(df_part), freq='W')
|
85 |
+
df_part['Date'] = date_range
|
86 |
+
df_part.set_index('Date', inplace=True)
|
87 |
+
|
88 |
+
series = df_part['y'].astype(float)
|
89 |
+
|
90 |
+
if model_name == 'ARIMA':
|
91 |
+
model, forecast = train_arima(series)
|
92 |
+
|
93 |
+
# Calculate metrics
|
94 |
+
train_size = int(len(series) * 0.8)
|
95 |
+
train, test = series[:train_size], series[train_size:]
|
96 |
+
|
97 |
+
model_eval = ARIMA(train, order=(5,1,0))
|
98 |
+
model_fit_eval = model_eval.fit()
|
99 |
+
predictions = model_fit_eval.forecast(steps=len(test))
|
100 |
+
|
101 |
+
rmse = np.sqrt(mean_squared_error(test, predictions))
|
102 |
+
mae = mean_absolute_error(test, predictions)
|
103 |
+
|
104 |
+
plot_html = create_plot(series, forecast)
|
105 |
+
|
106 |
+
metrics = f"""
|
107 |
+
Model Performance Metrics:
|
108 |
+
- RMSE: {rmse:.2f}
|
109 |
+
- MAE: {mae:.2f}
|
110 |
+
|
111 |
+
Forecast for next 10 periods:
|
112 |
+
{', '.join([f'{x:.2f}' for x in forecast])}
|
113 |
+
"""
|
114 |
+
|
115 |
+
return metrics, plot_html
|
116 |
+
|
117 |
+
# Create Gradio interface
|
118 |
+
def create_interface():
|
119 |
+
df = load_data()
|
120 |
+
part_numbers = get_part_numbers(df)
|
121 |
+
|
122 |
+
with gr.Blocks() as demo:
|
123 |
+
gr.Markdown("# Time Series Forecasting Dashboard")
|
124 |
+
|
125 |
+
with gr.Row():
|
126 |
+
part_dropdown = gr.Dropdown(choices=part_numbers, label="Select Part Number")
|
127 |
+
model_dropdown = gr.Dropdown(choices=['ARIMA'], label="Select Model")
|
128 |
+
|
129 |
+
predict_btn = gr.Button("Predict")
|
130 |
+
|
131 |
+
with gr.Row():
|
132 |
+
metrics_output = gr.Textbox(label="Metrics and Forecast")
|
133 |
+
plot_output = gr.HTML(label="Forecast Plot")
|
134 |
+
|
135 |
+
predict_btn.click(
|
136 |
+
fn=predict,
|
137 |
+
inputs=[part_dropdown, model_dropdown],
|
138 |
+
outputs=[metrics_output, plot_output]
|
139 |
+
)
|
140 |
+
|
141 |
+
return demo
|
142 |
+
|
143 |
+
if __name__ == "__main__":
|
144 |
+
demo = create_interface()
|
145 |
+
demo.launch()
|