Spaces:
Sleeping
Sleeping
| import gradio as gr | |
| import pandas as pd | |
| import numpy as np | |
| from statsmodels.tsa.arima.model import ARIMA | |
| from sklearn.metrics import mean_squared_error, mean_absolute_error | |
| import matplotlib.pyplot as plt | |
| import io | |
| import base64 | |
| # ✅ Mapping of best ARIMA orders per part number | |
| # (replace with your actual best parameters from the notebook) | |
| BEST_ARIMA_PARAMS = { | |
| "TE50011": (2, 0, 1), | |
| "TE50012": (2, 1, 1), | |
| "TE50013": (1, 1, 1), | |
| "TE50014": (0, 0, 0), | |
| "TE50015": (0, 1, 0), | |
| "TE50016": (0, 1, 1), | |
| "TE50017": (2, 1, 0), | |
| "TE50018": (1, 1, 2), | |
| "TE50019": (2, 1, 0), | |
| "TE50020": (2, 1, 1), | |
| "TE50021": (0, 0, 0), | |
| "TE50022": (2, 1, 2), | |
| "TE50023": (1, 0, 0), | |
| "TE50024": (1, 1, 2), | |
| "TE50025": (1, 1, 0), | |
| "TE50026": (2, 0, 0), | |
| "TE50027": (0, 0, 2), | |
| "TE50028": (1, 0, 1), | |
| "TE50029": (0, 1, 0), | |
| "TE50030": (0, 1, 0), | |
| "TE50031": (1, 1, 0), | |
| "TE50032": (1, 1, 0), | |
| "TE50033": (2, 1, 1), | |
| "TE50034": (0, 0, 0), | |
| "TE50035": (2, 1, 0), | |
| "TE50036": (0, 1, 0), | |
| "TE50037": (0, 0, 2), | |
| "TE50038": (2, 1, 1), | |
| "TE50039": (2, 0, 1), | |
| "TE50040": (1, 1, 1), | |
| "TE50041": (1, 1, 0), | |
| "TE50042": (0, 1, 0), | |
| "TE50043": (2, 1, 0), | |
| "TE50044": (0, 1, 0), | |
| "TE50045": (1, 0, 0), | |
| "TE50046": (0, 1, 0), | |
| "TE50047": (1, 1, 2), | |
| "TE50048": (0, 1, 0), | |
| "TE50049": (2, 1, 2), | |
| "TE50050": (2, 0, 2), | |
| "TE50051": (0, 1, 0), | |
| "TE50052": (2, 0, 1), | |
| "TE50053": (1, 0, 2), | |
| "TE50054": (1, 1, 0), | |
| "TE50055": (0, 0, 0), | |
| "TE50056": (2, 0, 2), | |
| "TE50057": (0, 1, 0), | |
| "TE50058": (1, 1, 0), | |
| "TE50059": (0, 1, 0), | |
| "TE50060": (1, 1, 2), | |
| "TE50061": (2, 1, 0), | |
| "TE50062": (1, 1, 2), | |
| "TE50063": (0, 0, 2), | |
| "TE50064": (0, 1, 0), | |
| "TE50065": (0, 1, 0), | |
| "TE50066": (2, 1, 0), | |
| "TE50067": (2, 1, 0), | |
| "TE50068": (1, 1, 0), | |
| "TE50069": (0, 1, 2), | |
| "TE50070": (1, 1, 1), | |
| "TE50071": (2, 1, 2), | |
| "TE50072": (2, 0, 2), | |
| "TE50073": (2, 0, 1), | |
| "TE50074": (0, 1, 1), | |
| "TE50075": (2, 1, 0), | |
| "TE50076": (0, 1, 0), | |
| "TE50077": (0, 1, 2), | |
| "TE50078": (2, 1, 0), | |
| "TE50079": (0, 1, 0), | |
| "TE50080": (2, 1, 2), | |
| "TE50081": (2, 1, 0), | |
| "TE50082": (0, 1, 0), | |
| "TE50083": (2, 1, 0), | |
| "TE50084": (0, 1, 0), | |
| "TE50085": (2, 1, 0), | |
| "TE50086": (0, 1, 1), | |
| "TE50087": (2, 0, 1), | |
| "TE50088": (2, 1, 0), | |
| "TE50089": (2, 0, 2), | |
| "TE50090": (0, 1, 1), | |
| "TE50091": (0, 1, 0), | |
| "TE50092": (0, 1, 0), | |
| "TE50093": (2, 0, 2), | |
| "TE50094": (2, 0, 1), | |
| "TE50095": (1, 0, 0), | |
| "TE50096": (0, 1, 0), | |
| "TE50097": (0, 1, 0), | |
| "TE50098": (1, 1, 0), | |
| "TE50099": (0, 1, 0), | |
| "TE50100": (2, 0, 2), | |
| "TE50101": (2, 0, 2), | |
| "TE50102": (1, 1, 1), | |
| "TE50103": (0, 0, 1), | |
| "TE50104": (0, 1, 0), | |
| "TE50105": (2, 0, 0), | |
| "TE50106": (2, 0, 0), | |
| "TE50107": (2, 0, 0), | |
| "TE50108": (2, 1, 0), | |
| "TE50109": (2, 1, 0), | |
| "TE50110": (0, 1, 0), | |
| "TE50111": (0, 1, 2), | |
| "TE50112": (2, 1, 2), | |
| "TE50113": (0, 1, 0), | |
| "TE50114": (0, 1, 0), | |
| "TE50115": (1, 1, 0), | |
| "TE50116": (1, 0, 0), | |
| "TE50117": (2, 1, 0), | |
| "TE50118": (2, 1, 1), | |
| "TE50119": (2, 1, 0), | |
| "TE50120": (2, 1, 1), | |
| "TE50121": (0, 1, 0), | |
| "TE50122": (1, 1, 2), | |
| "TE50123": (2, 1, 1), | |
| "TE50124": (1, 0, 2), | |
| "TE50125": (1, 0, 2), | |
| "TE50126": (0, 0, 0), | |
| "TE50127": (0, 1, 0), | |
| "TE50128": (2, 1, 0), | |
| "TE50129": (0, 1, 0), | |
| "TE50130": (1, 1, 0), | |
| "TE50131": (0, 1, 1), | |
| "TE50132": (0, 1, 0), | |
| "TE50133": (2, 0, 2), | |
| "TE50134": (1, 1, 0), | |
| "TE50135": (0, 1, 0), | |
| "TE50136": (0, 1, 2), | |
| "TE50137": (2, 0, 0), | |
| "TE50138": (2, 1, 0), | |
| "TE50139": (0, 1, 0), | |
| "TE50140": (0, 1, 0), | |
| "TE50141": (0, 1, 0), | |
| "TE50142": (2, 1, 2), | |
| "TE50143": (0, 1, 0), | |
| "TE50144": (0, 1, 0), | |
| "TE50145": (1, 0, 2), | |
| "TE50146": (0, 0, 0), | |
| "TE50147": (0, 0, 2), | |
| "TE50148": (2, 0, 2), | |
| "TE50149": (1, 0, 2), | |
| "TE50150": (2, 1, 1), | |
| "TE50151": (2, 0, 2), | |
| "TE50152": (2, 0, 1), | |
| "TE50153": (2, 0, 2), | |
| "TE50154": (2, 0, 2), | |
| "TE50155": (0, 0, 0), | |
| "TE50156": (0, 0, 0), | |
| "TE50157": (0, 1, 2), | |
| "TE50158": (1, 0, 2), | |
| "TE50159": (2, 1, 0), | |
| "TE50160": (2, 1, 0), | |
| "TE50161": (2, 0, 2), | |
| "TE50162": (0, 1, 0), | |
| "TE50163": (0, 1, 0), | |
| "TE50164": (1, 0, 0), | |
| "TE50165": (0, 1, 0), | |
| "TE50166": (2, 0, 2), | |
| "TE50167": (0, 1, 2), | |
| "TE50168": (0, 1, 0), | |
| "TE50169": (0, 1, 0), | |
| "TE50170": (1, 1, 0), | |
| "TE50171": (2, 1, 2), | |
| "TE50172": (2, 1, 2), | |
| "TE50173": (0, 1, 0), | |
| "TE50174": (2, 1, 0), | |
| "TE50175": (0, 1, 0), | |
| "TE50176": (2, 0, 2), | |
| "TE50177": (2, 0, 2), | |
| "TE50178": (1, 1, 0), | |
| "TE50179": (1, 0, 1), | |
| "TE50180": (0, 1, 0), | |
| "TE50181": (0, 1, 0), | |
| "TE50182": (1, 1, 0), | |
| "TE50183": (2, 1, 1), | |
| "TE50184": (0, 1, 0), | |
| "TE50185": (1, 1, 0), | |
| "TE50186": (2, 0, 2), | |
| "TE50187": (0, 1, 0), | |
| "TE50188": (0, 1, 1), | |
| "TE50189": (2, 0, 2), | |
| "TE50190": (1, 1, 0), | |
| "TE50191": (0, 1, 0), | |
| "TE50192": (0, 0, 1), | |
| "TE50193": (1, 1, 0), | |
| "TE50194": (2, 1, 0), | |
| "TE50195": (2, 0, 2), | |
| "TE50196": (0, 1, 0), | |
| "TE50197": (0, 0, 1), | |
| "TE50198": (0, 1, 0), | |
| "TE50199": (0, 1, 0), | |
| "TE50200": (0, 1, 0), | |
| "TE50201": (0, 1, 0), | |
| "TE50202": (0, 1, 0), | |
| "TE50203": (0, 1, 0), | |
| "TE50204": (2, 1, 2), | |
| "TE50205": (2, 0, 1), | |
| "TE50206": (1, 1, 1), | |
| "TE50207": (2, 0, 0), | |
| "TE50208": (0, 1, 0), | |
| "TE50209": (2, 0, 2), | |
| "TE50210": (0, 1, 0), | |
| "TE50211": (0, 1, 0), | |
| "TE50212": (0, 1, 0), | |
| "TE50213": (0, 1, 0), | |
| "TE50214": (0, 1, 0), | |
| "TE50215": (0, 1, 0), | |
| "TE50216": (0, 1, 0), | |
| "TE50217": (0, 1, 0), | |
| "TE50218": (2, 0, 1), | |
| "TE50219": (2, 1, 0), | |
| "TE50220": (2, 1, 0), | |
| "TE50221": (1, 1, 2), | |
| "TE50222": (0, 1, 0), | |
| "TE50223": (0, 1, 1), | |
| "TE50224": (0, 1, 0), | |
| "TE50225": (0, 1, 0), | |
| "TE50226": (0, 1, 0), | |
| "TE50227": (0, 1, 0), | |
| "TE50228": (0, 1, 0), | |
| "TE50229": (0, 1, 0), | |
| "TE50230": (0, 1, 0), | |
| "TE50231": (0, 1, 0), | |
| "TE50232": (0, 1, 1), | |
| "TE50233": (1, 1, 2), | |
| "TE50234": (0, 1, 0), | |
| "TE50235": (0, 1, 0), | |
| "TE50236": (0, 1, 0), | |
| "TE50237": (0, 1, 0), | |
| "TE50238": (0, 0, 2), | |
| "TE50239": (0, 1, 0), | |
| "TE50240": (0, 1, 0), | |
| "TE50241": (0, 1, 0), | |
| "TE50242": (0, 1, 0), | |
| "TE50243": (0, 1, 0), | |
| "TE50244": (0, 1, 0), | |
| "TE50245": (0, 1, 0), | |
| "TE50246": (0, 1, 0), | |
| "TE50247": (0, 1, 0), | |
| "TE50248": (0, 1, 0), | |
| "TE50249": (0, 1, 0), | |
| "TE50250": (2, 0, 1), | |
| "TE50251": (2, 0, 1), | |
| "TE50252": (0, 1, 0), | |
| "TE50253": (0, 1, 0), | |
| "TE50254": (0, 1, 0), | |
| "TE50255": (0, 1, 0), | |
| "TE50256": (0, 1, 0), | |
| "TE50257": (0, 1, 0), | |
| "TE50258": (0, 1, 0), | |
| "TE50259": (0, 1, 0), | |
| "TE50260": (0, 1, 0), | |
| "TE50261": (0, 1, 0), | |
| "TE50262": (0, 1, 0), | |
| "TE50263": (0, 1, 0), | |
| "TE50264": (0, 1, 0), | |
| "TE50265": (0, 1, 0), | |
| "TE50266": (0, 1, 0), | |
| "TE50267": (0, 1, 0), | |
| "TE50268": (0, 1, 0), | |
| "TE50269": (0, 1, 0), | |
| "TE50270": (0, 1, 0), | |
| "TE50271": (0, 1, 0), | |
| "TE50272": (0, 1, 0), | |
| "TE50273": (0, 1, 0), | |
| "TE50274": (0, 1, 0), | |
| "TE50275": (0, 1, 0), | |
| "TE50276": (0, 1, 0), | |
| "TE50277": (0, 1, 0), | |
| "TE50278": (0, 1, 0), | |
| "TE50279": (0, 1, 0), | |
| "TE50280": (0, 1, 0), | |
| "TE50281": (0, 1, 0), | |
| "TE50282": (0, 1, 0), | |
| "TE50283": (0, 1, 0), | |
| "TE50284": (0, 1, 0), | |
| "TE50285": (0, 1, 0), | |
| "TE50286": (0, 1, 0), | |
| "TE50287": (0, 1, 0), | |
| "TE50288": (0, 1, 0), | |
| "TE50289": (0, 1, 0), | |
| "TE50290": (0, 1, 0), | |
| "TE50291": (0, 1, 0), | |
| "TE50292": (0, 1, 0), | |
| "TE50293": (0, 1, 0), | |
| "TE50294": (0, 1, 0), | |
| "TE50295": (0, 1, 0), | |
| "TE50296": (0, 1, 0), | |
| "TE50297": (0, 1, 0), | |
| "TE50298": (0, 1, 0), | |
| "TE50299": (0, 1, 0), | |
| "TE50300": (0, 1, 0), | |
| "TE50301": (0, 1, 0), | |
| "TE50302": (0, 1, 0), | |
| "TE50303": (0, 1, 0), | |
| "TE50304": (0, 1, 0), | |
| "TE50305": (0, 1, 0), | |
| "TE50306": (0, 1, 0), | |
| "TE50307": (0, 1, 0), | |
| "TE50308": (0, 1, 0), | |
| "TE50309": (0, 1, 0), | |
| "TE50310": (0, 1, 0), | |
| "TE50311": (0, 1, 0), | |
| "TE50312": (0, 1, 0), | |
| "TE50313": (0, 1, 0), | |
| "TE50314": (0, 1, 0), | |
| "TE50315": (0, 1, 0), | |
| "TE50316": (0, 1, 0), | |
| "TE50317": (0, 1, 0), | |
| "TE50318": (0, 1, 0), | |
| "TE50319": (0, 1, 0), | |
| "TE50320": (0, 1, 0), | |
| "TE50321": (0, 1, 0), | |
| "TE50322": (0, 1, 0), | |
| "TE50323": (0, 1, 0), | |
| "TE50324": (0, 1, 0), | |
| "TE50325": (0, 1, 0), | |
| "TE50326": (0, 1, 0), | |
| "TE50327": (0, 1, 0), | |
| "TE50328": (2, 0, 2), | |
| "TE50329": (0, 1, 0), | |
| "TE50330": (0, 1, 0), | |
| "TE50331": (0, 1, 0), | |
| "TE50332": (0, 1, 0), | |
| "TE50333": (0, 1, 0), | |
| "TE50334": (0, 1, 0), | |
| "TE50335": (0, 1, 1), | |
| "TE50336": (0, 1, 1), | |
| "TE50337": (0, 1, 0), | |
| "TE50338": (0, 1, 0), | |
| "TE50339": (0, 1, 0), | |
| "TE50340": (0, 1, 0), | |
| "TE50341": (0, 1, 0), | |
| "TE50342": (0, 1, 0), | |
| "TE50343": (0, 1, 0), | |
| "TE50344": (0, 1, 0), | |
| "TE50345": (0, 1, 0), | |
| "TE50346": (0, 1, 0), | |
| "TE50346": (0, 1, 0), | |
| "TE50347": (0, 1, 0), | |
| "TE50348": (0, 1, 0), | |
| "TE50349": (0, 1, 0), | |
| "TE50350": (0, 1, 0), | |
| "TE50351": (0, 1, 0), | |
| "TE50352": (0, 1, 0), | |
| "TE50353": (0, 1, 0) | |
| } | |
| # Load and preprocess data | |
| def load_data(): | |
| df = pd.read_csv("data (3).csv", skiprows=2, header=None) | |
| header_df = pd.read_csv("data (3).csv", nrows=2, header=None) | |
| column_names = ['PN', 'Dummy_Project'] + [ | |
| f"{header_df.iloc[0, i]}_{header_df.iloc[1, i]}" for i in range(2, len(header_df.columns)) | |
| ] | |
| df.columns = column_names | |
| id_vars = ['PN', 'Dummy_Project'] | |
| value_vars = column_names[2:] | |
| df_long = df.melt( | |
| id_vars=id_vars, | |
| value_vars=value_vars, | |
| var_name='Time_Period', | |
| value_name='y' | |
| ) | |
| df_long[['Year', 'Month']] = df_long['Time_Period'].str.split('_', expand=True) | |
| df_long.drop(columns=['Time_Period'], inplace=True) | |
| df_long['Year'] = df_long['Year'].astype(int) | |
| df_long['Month'] = df_long['Month'].astype(str) | |
| df_long['Date'] = pd.to_datetime( | |
| df_long['Year'].astype(str) + '-' + df_long['Month'] + '-01', | |
| format='%Y-%b-%d', | |
| errors='coerce' | |
| ) | |
| df_long.dropna(subset=['y'], inplace=True) | |
| df_long.reset_index(drop=True, inplace=True) | |
| return df_long | |
| # Get available part numbers | |
| def get_part_numbers(df): | |
| return df['PN'].unique().tolist() | |
| # Train ARIMA model and make predictions | |
| def train_arima(series, order=(5,1,0)): | |
| model = ARIMA(series, order=order) | |
| model_fit = model.fit() | |
| forecast = model_fit.forecast(steps=10) | |
| return model_fit, forecast | |
| # Create plot | |
| def create_plot(historical, forecast, freq='M'): | |
| plt.figure(figsize=(14, 7)) | |
| plt.plot(historical.index, historical, label='Historical', linewidth=2) | |
| forecast_index = pd.date_range( | |
| start=historical.index[-1] + pd.tseries.frequencies.to_offset(freq), | |
| periods=len(forecast), | |
| freq=freq | |
| ) | |
| plt.plot(forecast_index, forecast, label='Forecast', color='orange', linewidth=2) | |
| plt.legend(fontsize=12) | |
| plt.title('Time Series Forecast', fontsize=16) | |
| plt.xlabel('Time Period', fontsize=14) | |
| plt.ylabel('Value', fontsize=14) | |
| plt.grid(True, alpha=0.3) | |
| buf = io.BytesIO() | |
| plt.savefig(buf, format='png', bbox_inches="tight") | |
| buf.seek(0) | |
| img_str = base64.b64encode(buf.read()).decode('utf-8') | |
| buf.close() | |
| plt.close() | |
| return f'<img src="data:image/png;base64,{img_str}" style="width:100%; height:auto;" />' | |
| # Main prediction function | |
| def predict(part_number, model_name): | |
| df = load_data() | |
| df_part = df[df['PN'] == part_number].copy() | |
| # Prepare time series | |
| start_date = '2021-10-09' | |
| date_range = pd.date_range(start=start_date, periods=len(df_part), freq='W') | |
| df_part['Date'] = date_range | |
| df_part.set_index('Date', inplace=True) | |
| series = df_part['y'].astype(float) | |
| freq = pd.infer_freq(series.index) or 'M' | |
| # ✅ Choose ARIMA order from mapping (fallback = (5,1,0)) | |
| order = BEST_ARIMA_PARAMS.get(part_number, (5,1,0)) | |
| if model_name == 'ARIMA': | |
| model, forecast = train_arima(series, order=order) | |
| plot_html = create_plot(series, forecast, freq=freq) | |
| # Evaluate | |
| train_size = int(len(series) * 0.8) | |
| train, test = series[:train_size], series[train_size:] | |
| model_eval = ARIMA(train, order=order) | |
| model_fit_eval = model_eval.fit() | |
| predictions = model_fit_eval.forecast(steps=len(test)) | |
| rmse = np.sqrt(mean_squared_error(test, predictions)) | |
| mae = mean_absolute_error(test, predictions) | |
| metrics = f""" | |
| Best ARIMA Order for {part_number}: {order} | |
| Model Performance Metrics: | |
| - RMSE: {rmse:.2f} | |
| - MAE: {mae:.2f} | |
| Forecast for next 10 periods: | |
| {', '.join([f'{x:.2f}' for x in forecast])} | |
| """ | |
| return metrics, plot_html | |
| # Create Gradio interface | |
| def create_interface(): | |
| df = load_data() | |
| part_numbers = get_part_numbers(df) | |
| with gr.Blocks() as demo: | |
| gr.Markdown("# Time Series Forecasting Dashboard") | |
| with gr.Row(): | |
| part_dropdown = gr.Dropdown(choices=part_numbers, label="Select Part Number") | |
| model_dropdown = gr.Dropdown(choices=['ARIMA'], label="Select Model") | |
| predict_btn = gr.Button("Predict") | |
| with gr.Row(): | |
| metrics_output = gr.Textbox(label="Metrics and Forecast") | |
| plot_output = gr.HTML(label="Forecast Plot") | |
| predict_btn.click( | |
| fn=predict, | |
| inputs=[part_dropdown, model_dropdown], | |
| outputs=[metrics_output, plot_output] | |
| ) | |
| return demo | |
| if __name__ == "__main__": | |
| demo = create_interface() | |
| demo.launch() | |