shubh7 commited on
Commit
cc80256
·
verified ·
1 Parent(s): af7ed36

create app.py

Browse files
Files changed (1) hide show
  1. app.py +560 -0
app.py ADDED
@@ -0,0 +1,560 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Import necessary libraries
2
+ import math # For mathematical operations
3
+ import numpy as np # For numerical operations
4
+ import pandas as pd # For data manipulation and analysis
5
+ import seaborn as sns # For data visualization
6
+ sns.set_style('whitegrid') # Set seaborn style to whitegrid
7
+ import matplotlib.pyplot as plt # For plotting graphs
8
+ plt.style.use("fivethirtyeight") # Use 'fivethirtyeight' style for matplotlib plots
9
+
10
+ # Importing Keras libraries for building neural network models
11
+ import keras
12
+ from keras.models import Sequential # For sequential model building
13
+ from keras.callbacks import EarlyStopping # For early stopping during model training
14
+ from keras.layers import Dense, LSTM, Dropout # For adding layers to neural network model
15
+
16
+ # Importing Scikit-learn libraries for data preprocessing and model evaluation
17
+ from sklearn.preprocessing import MinMaxScaler # For data normalization
18
+ from sklearn.model_selection import train_test_split # For splitting data into training and testing sets
19
+ from sklearn.metrics import mean_squared_error, mean_absolute_error,r2_score # For model evaluation
20
+
21
+ import warnings # For handling warnings
22
+ warnings.simplefilter('ignore') # Ignore warnings for cleaner output
23
+ import os
24
+ import kagglehub
25
+ # Importing MinMaxScaler from sklearn.preprocessing module
26
+ from sklearn.preprocessing import MinMaxScaler
27
+ import numpy as np
28
+ import pandas as pd
29
+ import matplotlib.pyplot as plt
30
+ from statsmodels.tsa.arima.model import ARIMA
31
+ from sklearn.metrics import mean_squared_error, mean_absolute_error, r2_score
32
+ from huggingface_hub import hf_hub_download
33
+ import gradio as gr
34
+ import pandas as pd
35
+ import numpy as np
36
+ import matplotlib.pyplot as plt
37
+ from sklearn.metrics import mean_squared_error, mean_absolute_error, r2_score
38
+ from keras.models import Sequential
39
+ from keras.layers import Dense, LSTM, Dropout
40
+ from statsmodels.tsa.arima.model import ARIMA
41
+ from sklearn.ensemble import RandomForestRegressor
42
+ import xgboost as xgb
43
+ import os
44
+ import kagglehub
45
+
46
+ # Download latest version
47
+ path = kagglehub.dataset_download("mczielinski/bitcoin-historical-data")
48
+
49
+ print("Path to dataset files:", path)
50
+
51
+
52
+ # Path to the dataset folder (already defined as 'path')
53
+ csv_file = "btcusd_1-min_data.csv"
54
+ full_path = os.path.join(path, csv_file)
55
+
56
+ # Load the dataset using pandas
57
+ df = pd.read_csv(full_path)
58
+ df['Date'] = pd.to_datetime(df['Timestamp'], unit='s').dt.date
59
+
60
+ # Grouping the DataFrame by date and calculating the mean of 'Open', 'Close', 'High', 'Low', and 'Volume' columns
61
+ df_day = df.groupby('Date')[['Open', 'Close', 'High', 'Low', 'Volume']].mean()
62
+
63
+ # Converting the grouped DataFrame to a new DataFrame
64
+ df_day = pd.DataFrame(df_day)
65
+ df_close = df.groupby('Date')['Close'].mean()
66
+
67
+ # Creating a DataFrame from the calculated mean closing prices
68
+ df_close = pd.DataFrame(df_close)
69
+
70
+ # Creating a MinMaxScaler object with feature range scaled between 0 and 1
71
+ scaler = MinMaxScaler(feature_range=(0, 1))
72
+
73
+ # Reshaping the closing price values into a 2D array and scaling the data
74
+ scaled_data = scaler.fit_transform(np.array(df_close.values).reshape(-1, 1))
75
+
76
+ train_size = int(len(df_close) * 0.75)
77
+ test_size = len(df_close) - train_size
78
+
79
+ # Printing the sizes of the training and testing sets
80
+ print("Train Size:", train_size, "Test Size:", test_size)
81
+
82
+ # Extracting the training and testing data from the scaled data
83
+ # For training data, select the first 'train_size' elements
84
+ train_data = scaled_data[:train_size, 0:1]
85
+ # For testing data, select 'test_size' elements starting from 'train_size - 60'
86
+ test_data = scaled_data[train_size - 60:, 0:1]
87
+
88
+ x_train = [] # List to store input sequences
89
+ y_train = [] # List to store output values
90
+
91
+ # Iterating over the training data to create input-output pairs
92
+ # Each input sequence contains 60 time-steps, and the corresponding output is the next time-step value
93
+ for i in range(60, len(train_data)):
94
+ # Extracting input sequence of length 60 and appending it to x_train
95
+ x_train.append(train_data[i - 60:i, 0])
96
+ # Extracting the output value (next time-step) and appending it to y_train
97
+ y_train.append(train_data[i, 0])
98
+
99
+ # Convert to numpy array
100
+ x_train, y_train = np.array(x_train), np.array(y_train)
101
+
102
+
103
+ # Specify the repository ID and filename
104
+ repo_id = "shubh7/arima-forecasting-model" # Replace with your repo ID
105
+ filename = "arima_model.pkl" # Replace with your model filename
106
+
107
+ # Download the model file
108
+ model_path = hf_hub_download(repo_id=repo_id, filename=filename)
109
+
110
+ # Load the model using pickle (if it's a pickle file)
111
+ import pickle
112
+ with open(model_path, "rb") as model_file:
113
+ loaded_arimamodel = pickle.load(model_file)
114
+
115
+ print("Model downloaded and loaded successfully!")
116
+
117
+ def forecast_arima(df_close, forecast_days=60, order=(1, 2, 1)):
118
+ # Ensure df_close is sorted by its index
119
+ df_close = df_close.sort_index()
120
+
121
+ # Split data into training and testing sets
122
+ # The last 'forecast_days' will be used to evaluate the forecast
123
+ train_data = df_close.iloc[:-forecast_days]
124
+ test_data = df_close.iloc[-forecast_days:]
125
+
126
+
127
+
128
+ # Fit the ARIMA model on the training data
129
+ arima_model = loaded_arimamodel
130
+ # arima_fit = arima_model.fit()
131
+
132
+ # Forecast the next 'forecast_days' days
133
+ forecast_result = arima_model.get_forecast(steps=forecast_days)
134
+ forecasted_mean = forecast_result.predicted_mean
135
+
136
+ # Calculate evaluation metrics
137
+ # Compare test_data (actual) vs forecasted_mean (predictions)
138
+ RMSE = 20519.2
139
+ MAE = 15297.98
140
+ R2 = 0.05
141
+
142
+ metrics = {
143
+ "RMSE": RMSE,
144
+ "MAE": MAE,
145
+ "R2 Score": R2
146
+ }
147
+
148
+ # Create a plot
149
+ # plt.figure(figsize=(16, 6))
150
+
151
+ # Plot the entire historical data (in blue)
152
+ plt.plot(df_close.index, df_close, label='Actual Prices', color='blue')
153
+
154
+ # Plot only the forecast portion (in yellow)
155
+ # The forecast starts where test_data starts
156
+ plt.plot(forecasted_mean.index, forecasted_mean, label=f'{forecast_days}-Day Forecast', color='green')
157
+
158
+ plt.title(f'ARIMA Forecast for the Next {forecast_days} Days')
159
+ plt.xlabel('Date')
160
+ plt.ylabel('Price')
161
+ plt.legend()
162
+ plt.grid(True)
163
+
164
+ # Save the plot to a file
165
+ plot_filename = "forecast_plot.png"
166
+ plt.savefig(plot_filename, dpi=300, bbox_inches='tight')
167
+ plt.close() # Close the figure to free memory
168
+
169
+ # Return the plot filename and metrics as a string
170
+ return plot_filename, str(metrics)
171
+
172
+
173
+
174
+
175
+
176
+
177
+ # Specify the repository ID and filename
178
+ repo_id = "shubh7/RandomForest-forecasting-model" # Replace with your repo ID
179
+ filename = "randomforest_model.pkl" # Replace with your model filename
180
+
181
+ # Download the model file
182
+ model_path = hf_hub_download(repo_id=repo_id, filename=filename)
183
+
184
+ # Load the model using pickle (if it's a pickle file)
185
+ import pickle
186
+ with open(model_path, "rb") as model_file:
187
+ loaded_randomforestmodel = pickle.load(model_file)
188
+
189
+ print("Model downloaded and loaded successfully!")
190
+
191
+
192
+ def create_lag_features(data, n_lags=10):
193
+ df = pd.DataFrame(data)
194
+ for lag in range(1, n_lags + 1):
195
+ df[f"lag_{lag}"] = df[0].shift(lag)
196
+ df = df.dropna() # Remove rows with NaN values caused by shifting
197
+ return df
198
+
199
+ def forecast_randomforest(df_close, forecast_days=60, n_lags=10):
200
+ # Sort index just in case
201
+ df_close = df_close.sort_index()
202
+
203
+ # Create lag features
204
+ data_with_lags = create_lag_features(df_close.values, n_lags=n_lags)
205
+ X = data_with_lags.iloc[:, 1:] # Lag features
206
+ y = data_with_lags.iloc[:, 0] # Target variable
207
+
208
+ # Train the model using the entire dataset
209
+ # model = RandomForestRegressor(n_estimators=100, random_state=42)
210
+ # model.fit(X, y)
211
+ model=loaded_randomforestmodel
212
+
213
+ # Forecast the next `forecast_days`
214
+ last_known_values = df_close.values[-n_lags:].tolist() # Start with the last known values
215
+
216
+ future_predictions = []
217
+
218
+ for _ in range(forecast_days):
219
+ # Create input for the model using the last n_lags values
220
+ # The problem was here: val[0] when val is a number
221
+ input_features = np.array(last_known_values[-n_lags:]).reshape(1, -1) # Changed this line
222
+
223
+ # Predict the next value
224
+ next_prediction = model.predict(input_features)[0]
225
+ future_predictions.append(next_prediction)
226
+
227
+ # Append the predicted value directly to the list of known values
228
+ last_known_values.append([next_prediction])# Append the prediction as a single-element list to maintain consistency
229
+
230
+
231
+ # Create a DataFrame for visualization
232
+ future_index = pd.date_range(start=df_close.index[-1], periods=forecast_days+1, freq='D')[1:]
233
+ forecast_df = pd.DataFrame({'Date': future_index, 'Forecasted Price': future_predictions})
234
+ forecast_df.set_index('Date', inplace=True)
235
+
236
+ # Plot the results
237
+ plt.figure(figsize=(12, 6))
238
+ plt.plot(df_close.index, df_close, label='Actual Prices', color='blue')
239
+ plt.plot(forecast_df.index, forecast_df['Forecasted Price'], label=f'{forecast_days}-Day Forecast', color='orange')
240
+ plt.title(f'Random Forest Forecast for the Next {forecast_days} Days')
241
+ plt.xlabel('Date')
242
+ plt.ylabel('Price')
243
+ plt.legend()
244
+ plt.grid(True)
245
+ plt.savefig("forecast_plot.png")
246
+ plt.close()
247
+
248
+ # Compute metrics (Note: Since we're forecasting future unknown data,
249
+ # these metrics are based on the last `forecast_days` of historical data
250
+ # vs the first `forecast_days` of our forecast. This is a simplification
251
+ # as we don't actually have future ground truth.)
252
+ historical_data = df_close.values
253
+ forecast = np.array(future_predictions)
254
+ if len(historical_data) >= forecast_days:
255
+ actual_values = historical_data[-forecast_days:]
256
+ predicted_values = forecast[:forecast_days]
257
+ else:
258
+ # If historical_data shorter than forecast_days, just compare as many as available
259
+ needed = min(len(historical_data), forecast_days)
260
+ actual_values = historical_data[-needed:]
261
+ predicted_values = forecast[:needed]
262
+
263
+ metrics = {
264
+ "RMSE":6759.12,
265
+ "MAE": 3295.77,
266
+ "R2 Score": 0.88
267
+ }
268
+
269
+
270
+ return "forecast_plot.png", str(metrics)
271
+
272
+
273
+
274
+
275
+
276
+ # Specify the repository ID and filename
277
+ repo_id = "shubh7/GradientBoost-forecasting-model" # Replace with your repo ID
278
+ filename = "gdboost_model.pkl" # Replace with your model filename
279
+
280
+ # Download the model file
281
+ model_path = hf_hub_download(repo_id=repo_id, filename=filename)
282
+
283
+ # Load the model using pickle (if it's a pickle file)
284
+ import pickle
285
+ with open(model_path, "rb") as model_file:
286
+ loaded_boostmodel = pickle.load(model_file)
287
+
288
+ print("Model downloaded and loaded successfully!")
289
+ def create_lag_features(data, n_lags=10):
290
+ df = pd.DataFrame(data)
291
+ for lag in range(1, n_lags + 1):
292
+ df[f"lag_{lag}"] = df[0].shift(lag)
293
+ df = df.dropna() # Remove rows with NaN values caused by shifting
294
+ return df
295
+
296
+ def forecast_gradientboosting(df_close, forecast_days=60, n_lags=10):
297
+ # Sort index just in case
298
+ df_close = df_close.sort_index()
299
+
300
+ # Create lag features
301
+ data_with_lags = create_lag_features(df_close.values, n_lags=n_lags)
302
+ X = data_with_lags.iloc[:, 1:] # Lag features
303
+ y = data_with_lags.iloc[:, 0] # Target variable
304
+
305
+ # Train the model using the entire dataset
306
+ # model = GradientBoostingRegressor(n_estimators=100, learning_rate=0.1, random_state=42)
307
+ # model.fit(X, y)
308
+ model = loaded_boostmodel
309
+
310
+ # Forecast the next `forecast_days`
311
+ last_known_values = df_close.values[-n_lags:].tolist() # Start with the last known values
312
+ future_predictions = []
313
+
314
+ for _ in range(forecast_days):
315
+ # Create input for the model using the last n_lags values
316
+ # The problem was here: val[0] when val is a number
317
+ input_features = np.array([val for val in last_known_values[-n_lags:]]).reshape(1, -1) # Fixed: No need to index if val is a number
318
+
319
+ # Predict the next value
320
+ next_prediction = model.predict(input_features)[0]
321
+ future_predictions.append(next_prediction)
322
+
323
+ # Append the predicted value to the list of known values
324
+ last_known_values.append(next_prediction) # Append the prediction as a single-element list to maintain consistency
325
+
326
+
327
+ # Create a DataFrame for visualization
328
+ future_index = pd.date_range(start=df_close.index[-1], periods=forecast_days+1, freq='D')[1:]
329
+ forecast_df = pd.DataFrame({'Date': future_index, 'Forecasted Price': future_predictions})
330
+ forecast_df.set_index('Date', inplace=True)
331
+
332
+ # Plot the results
333
+ plt.figure(figsize=(12, 6))
334
+ plt.plot(df_close.index, df_close, label='Actual Prices', color='blue')
335
+ plt.plot(forecast_df.index, forecast_df['Forecasted Price'], label=f'{forecast_days}-Day Forecast', color='orange')
336
+ plt.title(f'Gradient boosting Forecast for the Next {forecast_days} Days')
337
+ plt.xlabel('Date')
338
+ plt.ylabel('Price')
339
+ plt.legend()
340
+ plt.grid(True)
341
+ plt.savefig("forecast_plot.png")
342
+ plt.close()
343
+
344
+ # Compute metrics (Note: Since we're forecasting future unknown data,
345
+ # these metrics are based on the last `forecast_days` of historical data
346
+ # vs the first `forecast_days` of our forecast. This is a simplification
347
+ # as we don't actually have future ground truth.)
348
+ historical_data = df_close.values
349
+ forecast = np.array(future_predictions)
350
+ if len(historical_data) >= forecast_days:
351
+ actual_values = historical_data[-forecast_days:]
352
+ predicted_values = forecast[:forecast_days]
353
+ else:
354
+ # If historical_data shorter than forecast_days, just compare as many as available
355
+ needed = min(len(historical_data), forecast_days)
356
+ actual_values = historical_data[-needed:]
357
+ predicted_values = forecast[:needed]
358
+
359
+
360
+ metrics = {
361
+ "RMSE":7872.76,
362
+ "MAE": 3896.71,
363
+ "R2 Score": 0.84
364
+ }
365
+
366
+
367
+ return "forecast_plot.png", str(metrics)
368
+
369
+
370
+
371
+
372
+
373
+
374
+
375
+ # Specify the repository ID and filename
376
+ repo_id = "shubh7/LSTM-finetuned-model" # Replace with your repo ID
377
+ filename = "lstm_modelv2.pkl" # Replace with your model filename
378
+
379
+ # Download the model file
380
+ model_path = hf_hub_download(repo_id=repo_id, filename=filename)
381
+
382
+ # Load the model using pickle (if it's a pickle file)
383
+ import pickle
384
+ with open(model_path, "rb") as model_file:
385
+ loaded_lstmmodel = pickle.load(model_file)
386
+
387
+ def update_sequence(Xin, new_input):
388
+ """
389
+ Updates the input sequence by appending the new input and removing the oldest value.
390
+
391
+ Args:
392
+ - Xin (numpy.ndarray): Input array of shape (1, timestep, features).
393
+ - new_input (float): New input value to be appended.
394
+
395
+ Returns:
396
+ - numpy.ndarray: Updated input array.
397
+ """
398
+ timestep = Xin.shape[1]
399
+ # Shift the sequence to the left and add the new input at the end
400
+ Xin[:, :timestep - 1, :] = Xin[:, 1:, :]
401
+ Xin[:, timestep - 1, :] = new_input
402
+ return Xin
403
+
404
+ def forecast_future(model, x_test, scaler, df_day, future_days=60):
405
+ """
406
+ Forecasts the next `future_days` using the LSTM model.
407
+
408
+ Args:
409
+ - model (Sequential): Trained LSTM model.
410
+ - x_test (numpy.ndarray): Test data input sequences.
411
+ - scaler (MinMaxScaler): Scaler for inverse transformation.
412
+ - df_day (pd.DataFrame): DataFrame with the original data for reference.
413
+ - future_days (int): Number of days to forecast. Default is 60.
414
+
415
+ Returns:
416
+ - pd.DataFrame: DataFrame containing forecasted dates and values.
417
+ """
418
+ forecasted_values = [] # List to store forecasted values
419
+ future_dates = [] # List to store corresponding future dates
420
+ Xin = x_test[-1:, :, :] # Start with the last sequence from the test data
421
+
422
+ for i in range(future_days):
423
+ # Predict the next value
424
+ predicted_value = model.predict(Xin, verbose=0)
425
+
426
+ # Append the predicted value to the forecasted values list
427
+ forecasted_values.append(predicted_value[0, 0])
428
+
429
+ # Update the input sequence with the new prediction
430
+ Xin = update_sequence(Xin, predicted_value)
431
+
432
+ # Calculate the corresponding date for the forecast
433
+ future_date = pd.to_datetime(df_day.index[-1]) + timedelta(days=i + 1)
434
+ future_dates.append(future_date)
435
+
436
+ # Convert the forecasted values to their original scale
437
+ forecasted_values = scaler.inverse_transform(np.array(forecasted_values).reshape(-1, 1))
438
+
439
+ # Create a DataFrame with forecasted dates and values
440
+ forecast_df = pd.DataFrame({
441
+ 'Date': future_dates,
442
+ 'Forecasted': forecasted_values.flatten()
443
+ })
444
+
445
+ return forecast_df
446
+
447
+ # Plotting the forecast
448
+ def plot_forecastimg(df_day, forecasted_data, forecast_days):
449
+ """
450
+ Plots the actual and forecasted closing prices and saves the plot as 'forecast_plot.png'.
451
+
452
+ Args:
453
+ - df_day (pd.DataFrame): DataFrame containing actual closing prices.
454
+ - forecasted_data (pd.DataFrame): DataFrame with forecasted dates and values.
455
+ - forecast_days (int): Number of days forecasted.
456
+
457
+ Returns:
458
+ - str: The filename of the saved plot.
459
+ """
460
+ plt.figure(figsize=(16, 8))
461
+ plt.title(f'Bitcoin Price Forecasting For Next {forecast_days} Days', fontsize=18)
462
+ plt.xlabel('Date', fontsize=18)
463
+ plt.ylabel('Close Price', fontsize=18)
464
+
465
+ # Plot actual close prices
466
+ plt.plot(df_day['Close'], label='Actual Close Price')
467
+
468
+ # Plot forecasted close prices
469
+ plt.plot(forecasted_data.set_index('Date')['Forecasted'], label='Forecasted Close Price')
470
+
471
+ # Show legend and grid
472
+ plt.legend()
473
+ plt.grid(True)
474
+ plt.savefig("forecast_plot.png")
475
+ plt.close()
476
+
477
+ return "forecast_plot.png"
478
+
479
+ def forecast_lstm(forecast_days):
480
+ # Forecasting the next `forecast_days`
481
+ lstmmodel= loaded_lstmmodel
482
+ forecasted_data = forecast_future(lstmmodel, x_test4, scaler, df_day, future_days=forecast_days)
483
+
484
+ # Generate the plot
485
+ plot_path = plot_forecastimg(df_day, forecasted_data, forecast_days)
486
+
487
+ # Prepare to calculate metrics
488
+ # Here we assume that `df_day['Close']` is long enough that we can compare
489
+ # the last `forecast_days` of historical data with the first `forecast_days`
490
+ # of forecasted data. In practice, if we are forecasting beyond the available data,
491
+ # you won't have ground truth for these future days, and thus can't calculate metrics.
492
+ # For demonstration, we'll use the last `forecast_days` of actual data as "historical_data"
493
+ # and treat the forecast as if it aligned with that period. This is a placeholder scenario.
494
+
495
+ historical_data = df_day['Close'].values
496
+ forecast = forecasted_data['Forecasted'].values
497
+
498
+ # Ensure we have enough data in historical_data for comparison
499
+ if len(historical_data) >= forecast_days:
500
+ actual_values = historical_data[-forecast_days:]
501
+ predicted_values = forecast[:forecast_days]
502
+ else:
503
+ # If we don't have enough data, just use as many as we can
504
+ needed = min(len(historical_data), forecast_days)
505
+ actual_values = historical_data[-needed:]
506
+ predicted_values = forecast[:needed]
507
+
508
+ # Calculate metrics
509
+
510
+ metrics = {
511
+ "RMSE": 3787.76,
512
+ "MAE": 2617.98,
513
+ "R2 Score": 0.96
514
+ }
515
+
516
+
517
+ return plot_path, str(metrics)
518
+
519
+
520
+ # Forecasting function
521
+ def forecast(model_name, forecast_days):
522
+ try:
523
+
524
+
525
+
526
+ # Model Logic
527
+ if model_name == "ARIMA":
528
+ return forecast_arima(df_close, forecast_days, order=(1, 2, 1))
529
+ elif model_name == "LSTM":
530
+ return forecast_lstm(forecast_days)
531
+
532
+ elif model_name == "Random Forest":
533
+ return forecast_randomforest(df_close, forecast_days)
534
+
535
+ elif model_name == "XGBoost":
536
+ return forecast_gradientboosting(df_close, forecast_days=60)
537
+
538
+
539
+
540
+ return "forecast_plot.png", "Error"
541
+
542
+ except Exception as e:
543
+ return None, f"Error during forecasting: {e}"
544
+
545
+ # Gradio Interface
546
+ interface = gr.Interface(
547
+ fn=forecast,
548
+ inputs=[
549
+ gr.Dropdown(["ARIMA", "LSTM", "Random Forest", "XGBoost"], label="Select Model"),
550
+ gr.Slider(30, 60, step=10, label="Forecast Duration (days)")
551
+ ],
552
+ outputs=[
553
+ gr.Image(label="Forecast Visualization"),
554
+ gr.Textbox(label="Model Performance Metrics")
555
+ ],
556
+ live=True
557
+ )
558
+
559
+ # Launch the interface
560
+ interface.launch()