├── README.md ├── requirements.txt ├── multipage.py ├── prophet_script2.py ├── nbeats2.py ├── image_bot2.py ├── data_bot2.py └── main.py /README.md: -------------------------------------------------------------------------------- 1 | # forecast-demo -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | streamlit==1.15.2 2 | pandas==1.3.3 3 | numpy==1.21.2 4 | matplotlib==3.4.3 5 | prophet==1.0.1 6 | holidays==0.11.3.1 7 | tensorflow==2.6.0 8 | Pillow==8.3.2 9 | google-generativeai==0.2.0 10 | python-dotenv==0.19.1 11 | -------------------------------------------------------------------------------- /multipage.py: -------------------------------------------------------------------------------- 1 | import streamlit as st 2 | import pandas as pd 3 | import numpy as np 4 | import matplotlib.pyplot as plt 5 | from prophet import Prophet 6 | from prophet.plot import add_changepoints_to_plot 7 | import holidays 8 | from datetime import date, datetime, timedelta 9 | import streamlit as st 10 | import tensorflow as tf 11 | from PIL import Image 12 | import os 13 | from dotenv import load_dotenv 14 | import google.generativeai as genai 15 | from streamlit_option_menu import option_menu 16 | # from keras.saving import register_keras_serializable 17 | 18 | load_dotenv() 19 | os.getenv("GOOGLE_API_KEY") 20 | genai.configure(api_key=os.getenv("GOOGLE_API_KEY")) 21 | 22 | 23 | st.set_page_config( 24 | page_title="Demand Forecasting App", 25 | page_icon="📊" 26 | ) 27 | 28 | import main 29 | import image_bot2 30 | import data_bot2 31 | 32 | 33 | class MultiApp: 34 | 35 | def __init__(self): 36 | self.apps = [] 37 | 38 | def add_app(self, title, func): 39 | 40 | self.apps.append({ 41 | "title": title, 42 | "function": func 43 | }) 44 | 45 | def run(): 46 | if 'selected_index' not in st.session_state: 47 | st.session_state.selected_index = 0 48 | 49 | selected = option_menu( 50 | menu_title='', 51 | options=['Generate Forecasts','Chat with Image', 'Chat with Data'], 52 | icons=['cloud-arrow-up','graph-up-arrow', 'database-check'], 53 | menu_icon='chat-text-fill', 54 | default_index=st.session_state.selected_index, 55 | orientation="horizontal", 56 | styles={ 57 | "container": {"padding": "0!important", "background-color": "white"}, 58 | "icon": {"color": "black", "font-size": "default"}, 59 | "nav-link": {"color": "black", "font-size": "default", "text-align": "left", "margin": "0px", "--hover-color": "#e8f5e9"}, 60 | "nav-link-selected": {"background-color": "#02ab21", "color": "white"}, 61 | } 62 | ) 63 | 64 | st.session_state.selected_index = ['Generate Forecasts', 'Chat with Image', 'Chat with Data'].index(selected) 65 | 66 | 67 | if selected == "Generate Forecasts": 68 | main.app() 69 | if selected == "Chat with Image": 70 | image_bot2.app() 71 | if selected == "Chat with Data": 72 | data_bot2.app() 73 | 74 | 75 | run() -------------------------------------------------------------------------------- /prophet_script2.py: -------------------------------------------------------------------------------- 1 | import pandas as pd 2 | import numpy as np 3 | import matplotlib.pyplot as plt 4 | from prophet import Prophet 5 | from prophet.plot import add_changepoints_to_plot 6 | import holidays 7 | from datetime import date, datetime, timedelta 8 | import streamlit as st 9 | import tensorflow as tf 10 | # from keras.saving import register_keras_serializable 11 | 12 | model = Prophet() 13 | 14 | 15 | def plot_time_series(timesteps, values, format='-', start=0, end=None, label=None): 16 | fig, ax = plt.subplots(figsize=(15, 10)) 17 | ax.plot(timesteps[start:end], values[start:end], format, label=label) 18 | ax.set_xlabel("Timeline") 19 | ax.set_ylabel("Forecasted Values of Sales") 20 | if label: 21 | ax.legend(fontsize=10) 22 | ax.grid(True) 23 | st.pyplot(fig) 24 | return fig 25 | 26 | # Define functions specific to the Prophet model 27 | def read_process(file): 28 | df = pd.read_csv(file) 29 | 30 | # Try to parse the 'Date' column with multiple formats 31 | date_formats = ["%d-%m-%Y", "%m/%d/%Y"] 32 | for date_format in date_formats: 33 | try: 34 | df['Date'] = pd.to_datetime(df['Date'], format=date_format) 35 | break 36 | except ValueError: 37 | continue 38 | 39 | # If the date parsing failed, raise an error 40 | if df['Date'].isna().any(): 41 | raise ValueError("Date parsing failed for all formats") 42 | 43 | # Convert the 'Date' column to the desired format 44 | df['Date'] = df['Date'].dt.strftime("%m/%d/%Y") 45 | 46 | # Create the new DataFrame with the required columns 47 | data = pd.DataFrame() 48 | data["ds"] = df["Date"] 49 | data["y"] = df["Sales"] 50 | 51 | return data 52 | 53 | def evaluate(df, end_date): 54 | df['ds'] = pd.to_datetime(df['ds']) 55 | start_date = df["ds"].iloc[-1] 56 | d_1 = df["ds"].iloc[0] 57 | d_2 = df["ds"].iloc[1] 58 | if isinstance(end_date, date): 59 | end_date = pd.Timestamp(end_date) 60 | diff_dates = (d_2 - d_1).days 61 | if diff_dates == 1: 62 | days_selected = (end_date - start_date).days 63 | st.write(f"Number of Days selected: {days_selected}") 64 | return days_selected, diff_dates 65 | 66 | if diff_dates == 7: 67 | weeks_selected = (end_date - start_date).days // 7 68 | st.write(f"Number of Weeks selected: {weeks_selected}") 69 | return weeks_selected, diff_dates 70 | return days_selected, diff_dates 71 | 72 | def forecast(model, df, timesteps, f): 73 | model.fit(df) 74 | if f == 1: 75 | future_df = model.make_future_dataframe(periods=timesteps, freq='D') 76 | if f == 7: 77 | future_df = model.make_future_dataframe(periods=timesteps, freq='W') 78 | future_forecasts = model.predict(future_df) 79 | future_forecasts = model.predict(future_df) 80 | dates = future_forecasts["ds"] 81 | preds = future_forecasts["yhat"] 82 | last_idx = df.index[-1] 83 | fig = plot_time_series(timesteps=dates[last_idx:], values=preds[last_idx:]) 84 | return future_forecasts, last_idx, fig 85 | -------------------------------------------------------------------------------- /nbeats2.py: -------------------------------------------------------------------------------- 1 | # nbeats.py 2 | import pandas as pd 3 | import numpy as np 4 | import matplotlib.pyplot as plt 5 | from prophet import Prophet 6 | from prophet.plot import add_changepoints_to_plot 7 | import holidays 8 | from datetime import date, datetime, timedelta 9 | import streamlit as st 10 | import tensorflow as tf 11 | # from keras.saving import register_keras_serializable 12 | 13 | def plot_time_series(timesteps, values, format='-', start=0, end=None, label=None): 14 | fig, ax = plt.subplots(figsize=(15, 10)) 15 | ax.plot(timesteps[start:end], values[start:end], format, label=label) 16 | ax.set_xlabel("Timeline") 17 | ax.set_ylabel("Forecasted Values of Sales") 18 | if label: 19 | ax.legend(fontsize=10) 20 | ax.grid(True) 21 | st.pyplot(fig) 22 | return fig 23 | 24 | 25 | 26 | 27 | WINDOW_SIZE = 7 28 | HORIZON = 1 29 | 30 | class NBeatsBlock(tf.keras.layers.Layer): 31 | def __init__(self, input_size: int, theta_size: int, horizon: int, n_neurons: int, n_layers: int, **kwargs): 32 | super().__init__(**kwargs) 33 | self.input_size = input_size 34 | self.theta_size = theta_size 35 | self.horizon = horizon 36 | self.n_neurons = n_neurons 37 | self.n_layers = n_layers 38 | self.hidden = [tf.keras.layers.Dense(n_neurons, activation="relu") for _ in range(n_layers)] 39 | self.theta_layer = tf.keras.layers.Dense(theta_size, activation='linear', name='theta') 40 | 41 | def call(self, inputs): 42 | x = inputs 43 | for layer in self.hidden: 44 | x = layer(x) 45 | theta = self.theta_layer(x) 46 | backcast, forecast = theta[:, :self.input_size], theta[:, -self.horizon:] 47 | return backcast, forecast 48 | 49 | def read_and_process_nbeats(df): 50 | data = pd.DataFrame() 51 | data["ds"] = df["Date"] 52 | data["y"] = df["Sales"] 53 | data = data.set_index("ds") 54 | data_nbeats = data.copy() 55 | for i in range(WINDOW_SIZE): 56 | data_nbeats[f"y + {i+1}"] = data_nbeats["y"].shift(periods=i+1) 57 | X_all= data_nbeats.dropna().drop("y", axis=1) 58 | y_all = data_nbeats.dropna()["y"] 59 | return X_all, y_all 60 | 61 | def make_forecast_dates(df, end_date): 62 | start_date = df.iloc[-1]["Date"] 63 | dates_to_be_forecasted = pd.date_range(start=start_date, end=end_date) 64 | dates_to_be_forecasted = dates_to_be_forecasted[1:] 65 | st.write(f"Number of Timesteps selected: {len(dates_to_be_forecasted)}") 66 | return dates_to_be_forecasted, len(dates_to_be_forecasted) 67 | 68 | def make_future_forecast(values, model, into_future, window_size=WINDOW_SIZE) -> list: 69 | future_forecast = [] 70 | last_window = values[-WINDOW_SIZE:] 71 | last_window = np.asarray(last_window) 72 | for _ in range(into_future): 73 | future_pred = model.predict(tf.expand_dims(last_window, axis=0)) 74 | print(f"Predicting on:\n {last_window} -> Prediction: {tf.squeeze(future_pred).numpy()}\n") 75 | future_forecast.append(tf.squeeze(future_pred).numpy()) 76 | last_window = np.append(last_window, future_pred)[-WINDOW_SIZE:] 77 | return future_forecast 78 | -------------------------------------------------------------------------------- /image_bot2.py: -------------------------------------------------------------------------------- 1 | import google.generativeai as genai 2 | import streamlit as st 3 | from PIL import Image 4 | import os 5 | from dotenv import load_dotenv 6 | 7 | load_dotenv() 8 | os.getenv("GOOGLE_API_KEY") 9 | genai.configure(api_key=os.getenv("GOOGLE_API_KEY")) 10 | 11 | 12 | if "conversation_history_image" not in st.session_state: 13 | st.session_state.conversation_history_image = [] 14 | 15 | 16 | def add_custom_css_image_bot(): 17 | st.markdown(""" 18 | 32 | """, unsafe_allow_html=True) 33 | 34 | 35 | 36 | def app(): 37 | add_custom_css_image_bot() 38 | st.title("Image Description and Context Generation") 39 | 40 | # Load and display the image 41 | uploaded_file = st.file_uploader("Choose an image...", type=["png", "jpg", "jpeg"]) 42 | if uploaded_file is not None: 43 | image = Image.open(uploaded_file) 44 | st.image(image, caption="Uploaded Image.", use_column_width=True) 45 | 46 | # Convert the image to bytes 47 | # img_byte_arr = io.BytesIO() 48 | # image.save(img_byte_arr, format=image.format) 49 | # img_byte_arr = img_byte_arr.getvalue() 50 | 51 | # Add chat message for the initial prompt 52 | st.chat_message("📈").write("Analyze the trends in this graph.") 53 | 54 | user_prompt = st.chat_input("Enter your prompt here:") 55 | 56 | if user_prompt: 57 | # Hardcoded default prompt for forecasting graphs and trend analysis 58 | default_prompt = """ 59 | You are an expert in analyzing forecasting graphs for trend analysis. 60 | You will receive input images as graphs and you will have to answer questions based on the observed trends in brief and elaborate it. 61 | """ 62 | 63 | # Combine the default prompt with the user-provided prompt 64 | combined_prompt = f"{default_prompt}\n{user_prompt}" 65 | 66 | # Pass the combined prompt and image bytes to the model 67 | model = genai.GenerativeModel("gemini-1.5-flash") 68 | response = model.generate_content( 69 | [combined_prompt, image], 70 | generation_config = genai.types.GenerationConfig( 71 | temperature = 1.0), 72 | stream=True) 73 | response.resolve() 74 | 75 | st.session_state.conversation_history_image.append(("👦🏻", user_prompt, "user-message")) 76 | st.session_state.conversation_history_image.append(("🤖", response.text, "bot-message")) 77 | 78 | # Display the conversation history 79 | for speaker, message, css_class in st.session_state.conversation_history_image: 80 | st.markdown(f'