WaysAhead Global commited on
Commit
9b1174e
Β·
verified Β·
1 Parent(s): 7c49ebf

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +28 -39
app.py CHANGED
@@ -4,8 +4,7 @@ import numpy as np
4
  import os
5
  import matplotlib.pyplot as plt
6
  import seaborn as sns
7
- from sklearn.cluster import KMeans
8
- from statsmodels.tsa.holtwinters import ExponentialSmoothing
9
  from langchain_openai import ChatOpenAI
10
  from dotenv import load_dotenv
11
 
@@ -38,7 +37,7 @@ for mall, file in competitor_files.items():
38
  competitor_data[mall] = pd.read_csv(file, encoding="ISO-8859-1")
39
 
40
  # βœ… Streamlit Page Configuration
41
- st.set_page_config(page_title="AI Store Replacement, Demand Prediction & Chatbot", layout="wide")
42
 
43
  # βœ… Title
44
  st.title("πŸ”„ AI-Powered Store Replacement, Demand Prediction & Chatbot")
@@ -61,7 +60,7 @@ if selected_mall:
61
  store_to_replace = st.selectbox("πŸšͺ Select the store that is closing:", mall_data["Store_Brand"].unique())
62
 
63
  if store_to_replace:
64
- llm = ChatOpenAI(model="gpt-3.5-turbo", api_key=openai_api_key)
65
 
66
  # βœ… Identify Store Category
67
  category_prompt = f"Given that {store_to_replace} is a retail brand, what type of store is it? Categorize it broadly (e.g., Fashion, Electronics, Footwear, Food, Home Decor, etc.)."
@@ -80,55 +79,45 @@ if selected_mall:
80
  for competitor in competitor_list:
81
  st.write(f"- {competitor}")
82
 
83
- # βœ… AI-Based Store Clustering (Finding Best Replacements)
84
- store_features = df[["Annual_Sales", "Footfall", "Gross_Margin"]].dropna()
85
- kmeans = KMeans(n_clusters=5, random_state=42) # 5 Clusters
86
- df["Cluster"] = kmeans.fit_predict(store_features)
87
 
88
- # βœ… Find replacement store from `kpi.xlsx` (Not in this mall)
89
- available_stores = list(set(df["Store_Brand"].unique()) - set(mall_data["Store_Brand"].unique()))
 
 
90
 
91
- # βœ… Debugging: Check available replacements
92
- st.write(f"πŸ” **Available Replacement Stores:** {available_stores}")
93
 
94
  if available_stores:
95
  replacement_prompt = f"Suggest 3 replacement stores from the list below that are not already in {selected_mall}. The stores should match the mall’s customer base and the category: {store_category}. Store List: {available_stores}"
96
  replacement_response = llm.invoke(replacement_prompt).content
97
-
98
- # βœ… Debugging: Print AI Response
99
- st.write(f"🧠 **AI Raw Response:** {replacement_response}")
100
-
101
- # βœ… Ensure AI Response is Valid
102
  replacement_stores = [store.strip() for store in replacement_response.split("\n") if store.strip()]
103
  replacement_stores = [store for store in replacement_stores if store in available_stores]
104
 
105
  if replacement_stores:
106
- st.success(f"πŸ”„ **Recommended Replacement Stores:**")
107
  for replacement_store in replacement_stores:
108
  store_data = df[df["Store_Brand"] == replacement_store]
109
 
110
  if not store_data.empty:
111
- sales_history = store_data["Annual_Sales"]
112
- if len(sales_history) > 3:
113
- # βœ… Time-Series Forecasting for Demand Prediction
114
- model = ExponentialSmoothing(sales_history, trend="add", seasonal="add", seasonal_periods=3)
115
- fit = model.fit()
116
- forecast_sales = fit.forecast(1).values[0] # Predict next year's sales
117
-
118
- expected_footfall = store_data["Footfall"].mean()
119
- expected_conversion = store_data["Conversion_Rate"].mean()
120
- expected_margin = store_data["Gross_Margin"].mean()
121
-
122
- st.write(f"**{replacement_store}**")
123
- st.write(f"πŸ“Š **Projected Sales:** AED {forecast_sales:,.2f}")
124
- st.write(f"πŸ‘£ **Projected Footfall:** {expected_footfall:,.0f} visitors")
125
- st.write(f"πŸ’° **Projected Margin:** AED {expected_margin:,.2f}")
126
- st.write(f"πŸ”„ **Projected Conversion Rate:** {expected_conversion:.2f}%")
127
-
128
- # βœ… Justification
129
- justification_prompt = f"Explain why {replacement_store} is a good replacement for {store_to_replace} in {selected_mall}. Include numeric KPIs: expected sales, footfall, conversion rate, and profit margins."
130
- justification = llm.invoke(justification_prompt).content
131
- st.write(f"πŸ€– **AI Justification:** {justification}")
132
 
133
  # βœ… AI Chatbot for Dynamic Insights
134
  st.subheader("πŸ’¬ AI-Powered Chatbot")
 
4
  import os
5
  import matplotlib.pyplot as plt
6
  import seaborn as sns
7
+ from pycaret.regression import setup, compare_models, predict_model, pull
 
8
  from langchain_openai import ChatOpenAI
9
  from dotenv import load_dotenv
10
 
 
37
  competitor_data[mall] = pd.read_csv(file, encoding="ISO-8859-1")
38
 
39
  # βœ… Streamlit Page Configuration
40
+ st.set_page_config(page_title="AI Store Replacement with PyCaret KPI Forecasting", layout="wide")
41
 
42
  # βœ… Title
43
  st.title("πŸ”„ AI-Powered Store Replacement, Demand Prediction & Chatbot")
 
60
  store_to_replace = st.selectbox("πŸšͺ Select the store that is closing:", mall_data["Store_Brand"].unique())
61
 
62
  if store_to_replace:
63
+ llm = ChatOpenAI(model="gpt-4", api_key=openai_api_key)
64
 
65
  # βœ… Identify Store Category
66
  category_prompt = f"Given that {store_to_replace} is a retail brand, what type of store is it? Categorize it broadly (e.g., Fashion, Electronics, Footwear, Food, Home Decor, etc.)."
 
79
  for competitor in competitor_list:
80
  st.write(f"- {competitor}")
81
 
82
+ # βœ… Train PyCaret Model for KPI Prediction
83
+ st.subheader("πŸ“ˆ Training PyCaret Model for KPI Forecasting")
 
 
84
 
85
+ kpi_data = df.drop(columns=["Store_Brand", "Mall", "Location", "Country", "City"]) # Exclude categorical features
86
+ reg = setup(kpi_data, target="Annual_Sales", silent=True)
87
+ best_model = compare_models()
88
+ st.write("πŸ† Best Model Selected:", best_model)
89
 
90
+ # βœ… Find a replacement store in the same category (From kpi.xlsx, Not in this mall)
91
+ available_stores = list(set(df["Store_Brand"].unique()) - set(mall_data["Store_Brand"].unique()))
92
 
93
  if available_stores:
94
  replacement_prompt = f"Suggest 3 replacement stores from the list below that are not already in {selected_mall}. The stores should match the mall’s customer base and the category: {store_category}. Store List: {available_stores}"
95
  replacement_response = llm.invoke(replacement_prompt).content
 
 
 
 
 
96
  replacement_stores = [store.strip() for store in replacement_response.split("\n") if store.strip()]
97
  replacement_stores = [store for store in replacement_stores if store in available_stores]
98
 
99
  if replacement_stores:
100
+ st.success(f"πŸ”„ **Recommended Replacement Stores with Forecasted KPIs:**")
101
  for replacement_store in replacement_stores:
102
  store_data = df[df["Store_Brand"] == replacement_store]
103
 
104
  if not store_data.empty:
105
+ forecast_kpis = predict_model(best_model, data=store_data)
106
+ forecasted_sales = forecast_kpis["Label"].values[0]
107
+ expected_footfall = store_data["Footfall"].mean()
108
+ expected_conversion = store_data["Conversion_Rate"].mean()
109
+ expected_margin = store_data["Gross_Margin"].mean()
110
+
111
+ st.write(f"**{replacement_store}**")
112
+ st.write(f"πŸ“Š **Projected Sales:** AED {forecasted_sales:,.2f}")
113
+ st.write(f"πŸ‘£ **Projected Footfall:** {expected_footfall:,.0f} visitors")
114
+ st.write(f"πŸ’° **Projected Margin:** AED {expected_margin:,.2f}")
115
+ st.write(f"πŸ”„ **Projected Conversion Rate:** {expected_conversion:.2f}%")
116
+
117
+ # βœ… Justification
118
+ justification_prompt = f"Explain why {replacement_store} is a good replacement for {store_to_replace} in {selected_mall}. Include numeric KPIs: expected sales, footfall, conversion rate, and profit margins."
119
+ justification = llm.invoke(justification_prompt).content
120
+ st.write(f"πŸ€– **AI Justification:** {justification}")
 
 
 
 
 
121
 
122
  # βœ… AI Chatbot for Dynamic Insights
123
  st.subheader("πŸ’¬ AI-Powered Chatbot")