CosmickVisions commited on
Commit
4aa6c03
·
verified ·
1 Parent(s): 91c951d

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +281 -383
app.py CHANGED
@@ -1,420 +1,318 @@
1
  import streamlit as st
2
  import pandas as pd
3
  import plotly.express as px
4
- from pycaret.classification import setup as classification_setup, compare_models as compare_classification_models, evaluate_model as evaluate_classification_model, save_model as save_classification_model, plot_model as plot_classification_model, tune_model as tune_classification_model, get_config
5
- from pycaret.regression import setup as regression_setup, compare_models as compare_regression_models, evaluate_model as evaluate_regression_model, save_model as save_regression_model, plot_model as plot_regression_model, tune_model as tune_regression_model, get_config
6
- from pycaret.clustering import setup as clustering_setup, evaluate_model as evaluate_clustering_model, save_model as save_clustering_model, plot_model as plot_clustering_model, create_model as create_clustering_model, get_config
 
7
  from ydata_profiling import ProfileReport
8
  from streamlit_pandas_profiling import st_profile_report
9
- import os
10
  import requests
11
  import json
12
- import re
13
- import logging
14
 
15
  # Set page config
16
  st.set_page_config(page_title="Neural-Vision Enhanced", layout="wide")
17
 
18
- # Helper Functions
19
- def enhance_section_title(title):
20
- st.markdown(f"<h2 style='border-bottom: 2px solid #ccc; padding-bottom: 5px;'>{title}</h2>", unsafe_allow_html=True)
21
 
22
- def get_available_models(problem_type):
23
- if problem_type == "Classification":
24
- return list(get_config('available_estimators')['classification'].keys())
25
- elif problem_type == "Regression":
26
- return list(get_config('available_estimators')['regression'].keys())
27
- elif problem_type == "Clustering":
28
- return list(get_config('available_estimators')['clustering'].keys())
29
- return []
30
 
31
- def get_context():
32
- context = "You are using Neural-Vision Enhanced, an AI-powered data analysis and modeling tool.\n"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
33
  if 'df' in st.session_state:
34
- df = st.session_state['df']
35
- context += f"Current dataset has {df.shape[0]} rows and {df.shape[1]} columns.\n"
36
- context += f"Missing values: {df.isna().sum().sum()}\n"
37
- context += "Columns:\n"
38
- for col in df.columns:
39
- context += f"- {col} ({df[col].dtype}): Missing={df[col].isna().sum()}\n"
40
- if 'problem_type' in st.session_state:
41
- context += f"Selected problem type: {st.session_state['problem_type']}\n"
42
- if 'target' in st.session_state and st.session_state['problem_type'] != "Clustering":
43
- context += f"Target column: {st.session_state['target']}\n"
44
- if 'best_model' in st.session_state:
45
- context += f"Best model trained: {st.session_state['best_model']}\n"
46
- return context
47
 
48
- def deepseek_chat(user_input, app_mode):
49
- system_prompt = (
50
- "You are an AI assistant in Neural-Vision Enhanced, a data analysis and modeling app. "
51
- "The app has three pages:\n"
52
- "- **Data Upload**: Upload CSV files, view stats, or generate EDA reports.\n"
53
- "- **Model Training**: Train classification, regression, or clustering models using PyCaret.\n"
54
- "- **Validation & Exploration**: Evaluate and visualize trained models.\n"
55
- f"The user is on the '{app_mode}' page.\n"
56
- f"Current context:\n{get_context()}"
57
- )
58
- payload = {
59
- "model": "deepseek-chat",
60
- "messages": [
61
- {"role": "system", "content": system_prompt},
62
- {"role": "user", "content": user_input}
63
- ],
64
- "max_tokens": 150,
65
- "temperature": 0.7
66
- }
67
- headers = {"Authorization": f"Bearer {api_key}"}
68
  try:
69
  response = requests.post(
70
- "https://api.deepseek.com/v1/chat/completions",
71
- json=payload,
72
- headers=headers,
73
- timeout=10 # Increased timeout
 
 
74
  )
75
- response.raise_for_status()
76
- return response.json()["choices"][0]["message"]["content"]
77
- except requests.exceptions.RequestException as e:
78
- st.error(f"Error: Could not connect to DeepSeek API. {str(e)}")
79
- return "I'm sorry, I couldn't process your request. Please try again later."
80
-
81
- # LLM Command Functions
82
- def drop_columns(columns):
83
- if 'df' in st.session_state:
84
- df = st.session_state['df'].copy()
85
- columns_to_drop = [col.strip() for col in columns.split(',')]
86
- valid_columns = [col for col in columns_to_drop if col in df.columns]
87
- if valid_columns:
88
- df.drop(valid_columns, axis=1, inplace=True)
89
- st.session_state['df'] = df
90
- st.rerun()
91
- return f"Dropped columns: {', '.join(valid_columns)}"
92
- else:
93
- return "No valid columns found to drop."
94
- return "No dataset loaded."
95
-
96
- def generate_scatter_plot(params):
97
- if 'df' in st.session_state:
98
- df = st.session_state['df']
99
- match = re.search(r"([\w\s]+)\s+vs\s+([\w\s]+)", params)
100
- if match and len(match.groups()) >= 2:
101
- x_axis, y_axis = match.group(1).strip(), match.group(2).strip()
102
- if x_axis in df.columns and y_axis in df.columns:
103
- fig = px.scatter(df, x=x_axis, y=y_axis, title=f'Scatter Plot of {x_axis} vs {y_axis}')
104
- st.plotly_chart(fig)
105
- st.session_state.last_plot = {"type": "Scatter Plot", "x": x_axis, "y": y_axis, "data": df[[x_axis, y_axis]].to_json()}
106
- return f"Generated scatter plot of {x_axis} vs {y_axis}"
107
- return "Invalid columns or no dataset loaded."
108
-
109
- def generate_histogram(params):
110
- if 'df' in st.session_state:
111
- df = st.session_state['df']
112
- x_axis = params.strip()
113
- if x_axis in df.columns:
114
- fig = px.histogram(df, x=x_axis, title=f'Histogram of {x_axis}')
115
- st.plotly_chart(fig)
116
- st.session_state.last_plot = {"type": "Histogram", "x": x_axis, "data": df[[x_axis]].to_json()}
117
- return f"Generated histogram of {x_axis}"
118
- return "Invalid column or no dataset loaded."
119
-
120
- def analyze_plot():
121
- if "last_plot" not in st.session_state:
122
- return "No plot available to analyze."
123
- plot_info = st.session_state.last_plot
124
- df = pd.read_json(plot_info["data"])
125
- plot_type = plot_info["type"]
126
- x_col = plot_info["x"]
127
- y_col = plot_info["y"] if "y" in plot_info else None
128
-
129
- if plot_type == "Scatter Plot" and y_col:
130
- correlation = df[x_col].corr(df[y_col])
131
- strength = "strong" if abs(correlation) > 0.7 else "moderate" if abs(correlation) > 0.3 else "weak"
132
- direction = "positive" if correlation > 0 else "negative"
133
- return f"The scatter plot of {x_col} vs {y_col} shows a {strength} {direction} correlation (Pearson r = {correlation:.2f})."
134
- elif plot_type == "Histogram":
135
- skewness = df[x_col].skew()
136
- skew_desc = "positively skewed" if skewness > 1 else "negatively skewed" if skewness < -1 else "approximately symmetric"
137
- return f"The histogram of {x_col} is {skew_desc} (skewness = {skewness:.2f})."
138
- return "Inference not available for this plot type."
139
-
140
- def suggest_preprocessing():
141
- if 'df' in st.session_state:
142
- df = st.session_state['df']
143
- missing = df.isna().sum().sum()
144
- if missing > 0:
145
- return f"Your dataset has {missing} missing values. Consider imputation or dropping rows/columns with missing data before training."
146
- if df.duplicated().sum() > 0:
147
- return f"Your dataset has {df.duplicated().sum()} duplicates. Consider removing them for better model performance."
148
- return "Your dataset looks clean. Proceed to model training."
149
- return "No dataset loaded yet."
150
-
151
- def suggest_model():
152
- if 'df' in st.session_state and 'problem_type' in st.session_state:
153
- df = st.session_state['df']
154
- problem_type = st.session_state['problem_type']
155
- if problem_type == "Classification" and 'target' in st.session_state:
156
- target = st.session_state['target']
157
- if df[target].nunique() == 2:
158
- return "For binary classification, try Logistic Regression or Random Forest."
159
- return "For multi-class classification, try Gradient Boosting or SVM."
160
- elif problem_type == "Regression":
161
- return "For regression, try Linear Regression or Gradient Boosting."
162
- elif problem_type == "Clustering":
163
- return "For clustering, try K-Means or DBSCAN based on your data distribution."
164
- return "Setup PyCaret first to get model suggestions."
165
-
166
- # Parse Chatbot Commands
167
- def parse_command(command):
168
- command = command.lower().strip()
169
- if "drop columns" in command or "drop column" in command:
170
- columns = command.replace("drop columns", "").replace("drop column", "").strip()
171
- return drop_columns, columns
172
- elif "show a scatter plot" in command or "scatter plot of" in command:
173
- params = command.replace("show a scatter plot of", "").replace("scatter plot of", "").strip()
174
- return generate_scatter_plot, params
175
- elif "show a histogram" in command or "histogram of" in command:
176
- params = command.replace("show a histogram of", "").replace("histogram of", "").strip()
177
- return generate_histogram, params
178
- elif "analyze plot" in command:
179
- return lambda x: analyze_plot(), None
180
- elif "suggest preprocessing" in command:
181
- return lambda x: suggest_preprocessing(), None
182
- elif "suggest model" in command:
183
- return lambda x: suggest_model(), None
184
- return None, "Command not recognized. Try 'drop columns X, Y', 'scatter plot of X vs Y', 'suggest preprocessing', or 'analyze plot'."
185
-
186
- # Dataset Preview Function
187
- def display_dataset_preview():
188
- if 'df' in st.session_state:
189
- st.subheader("Current Dataset Preview")
190
- st.dataframe(st.session_state['df'].head(10), use_container_width=True)
191
- st.write("---")
192
-
193
- # Sidebar Navigation with API Key Input
194
- with st.sidebar:
195
- st.title("🔮 Neural-Vision Enhanced")
196
- st.markdown("Your AI-powered model toolbox.")
197
- st.markdown("---")
198
- app_mode = st.selectbox("Navigation", ["Data Upload", "Model Training", "Validation & Exploration"])
199
- data_type = st.selectbox("Data Type", ["Tabular"])
200
 
201
- # API Key Input Field
202
- api_key_input = st.text_input(
203
- "Enter DeepSeek API Key (optional)",
204
- type="password",
205
- help="Enter your DeepSeek API key to override the default. Leave blank to use the app's default key."
206
- )
207
-
208
- st.markdown("---")
209
- st.markdown("**Dependencies**: `pycaret`, `pandas`, `streamlit`, `ydata-profiling`, `plotly`, `requests`")
210
- st.markdown("Created by Calvin Allen-Crawford | v2.0 | © 2025")
211
-
212
- # Determine which API key to use
213
- if api_key_input:
214
- api_key = api_key_input # Use the user-provided API key from the sidebar
215
- else:
216
- api_key = st.secrets.get("DEEPSEEK_API_KEY", os.getenv("DEEPSEEK_API_KEY")) # Fall back to secret or environment variable
217
-
218
- if not api_key:
219
- st.error("DeepSeek API key is required. Please provide it in the sidebar or ensure it’s set in the app’s secrets.")
220
- st.stop()
221
-
222
- # Display dataset preview at the top of each page
223
- display_dataset_preview()
224
-
225
- # Main App Sections
226
- if app_mode == "Data Upload":
227
- st.title("📤 Data Upload")
228
- uploaded_file = st.file_uploader("Upload CSV Dataset", type=["csv"])
229
  if uploaded_file:
230
  df = pd.read_csv(uploaded_file)
231
- st.session_state['df'] = df
232
- st.session_state.pop('problem_type', None)
233
- st.session_state.pop('setup_complete', None)
234
- st.session_state.pop('best_model', None)
235
- st.session_state.pop('target', None)
236
- st.write("---")
237
- st.subheader("Statistics")
238
  col1, col2, col3 = st.columns(3)
239
- with col1: st.metric("Rows", df.shape[0])
240
- with col2: st.metric("Columns", df.shape[1])
241
- with col3: st.metric("Missing Values", df.isna().sum().sum())
242
- st.write("---")
243
- st.subheader("Exploratory Data Analysis (EDA)")
244
- if st.button("Generate EDA Report"):
245
- with st.spinner("Generating EDA Report..."):
246
  profile = ProfileReport(df, explorative=True)
247
  st_profile_report(profile)
248
- with st.expander("AI Suggestions"):
249
- st.write(suggest_preprocessing())
250
 
251
- elif app_mode == "Model Training":
252
- st.title("🧠 Model Training")
 
253
  if 'df' not in st.session_state:
254
- st.warning("Please upload a dataset first.")
255
- st.stop()
256
-
257
- df = st.session_state['df']
258
- problem_type = st.selectbox("Problem Type", ["Classification", "Regression", "Clustering"])
259
- target = st.selectbox("Select Target Column", df.columns) if problem_type != "Clustering" else None
260
-
261
- if st.button("Setup PyCaret"):
262
- with st.spinner("Setting up PyCaret..."):
 
 
 
 
263
  if problem_type == "Classification":
264
- classification_setup(data=df, target=target, session_id=123, verbose=False)
265
- st.session_state['problem_type'] = "Classification"
266
- st.session_state['target'] = target
267
- st.session_state['setup_complete'] = True
268
  elif problem_type == "Regression":
269
- regression_setup(data=df, target=target, session_id=123, verbose=False)
270
- st.session_state['problem_type'] = "Regression"
271
- st.session_state['target'] = target
272
- st.session_state['setup_complete'] = True
273
- elif problem_type == "Clustering":
274
- clustering_setup(data=df, session_id=123, verbose=False)
275
- st.session_state['problem_type'] = "Clustering"
276
- st.session_state['setup_complete'] = True
277
- st.success("PyCaret setup complete! You can now train models.")
278
-
279
- if st.session_state.get('setup_complete', False):
280
- st.subheader("Train Models")
281
- with st.expander("Advanced Options", expanded=False):
282
- if problem_type in ["Classification", "Regression"]:
283
- available_models = get_available_models(problem_type)
284
- selected_models = st.multiselect("Select Models to Compare (leave empty for all)", available_models, default=None)
285
- folds = st.number_input("Number of Cross-Validation Folds", min_value=2, max_value=20, value=10, step=1)
286
- if problem_type == "Classification":
287
- sort_metric = st.selectbox("Sort Metric", ["Accuracy", "AUC", "Recall", "Precision", "F1"], index=0)
288
- else: # Regression
289
- sort_metric = st.selectbox("Sort Metric", ["R2", "MAE", "MSE", "RMSE"], index=0)
290
- elif problem_type == "Clustering":
291
- available_models = get_available_models(problem_type)
292
- selected_model = st.selectbox("Select Clustering Algorithm", available_models)
293
- if selected_model == "kmeans":
294
- num_clusters = st.number_input("Number of Clusters", min_value=2, max_value=20, value=4, step=1)
295
- elif selected_model == "dbscan":
296
- eps = st.number_input("Epsilon (eps)", min_value=0.1, max_value=10.0, value=0.5, step=0.1)
297
- min_samples = st.number_input("Minimum Samples", min_value=2, max_value=20, value=5, step=1)
298
- elif selected_model == "hclust":
299
- num_clusters = st.number_input("Number of Clusters", min_value=2, max_value=20, value=4, step=1)
300
-
301
- with st.expander("AI Suggestions"):
302
- st.write(suggest_model())
303
 
304
- if problem_type in ["Classification", "Regression"]:
305
- if st.button("Compare Models"):
306
- with st.spinner("Comparing models..."):
307
- if selected_models:
308
- if problem_type == "Classification":
309
- best_model = compare_classification_models(include=selected_models, fold=folds, sort=sort_metric)
310
- else:
311
- best_model = compare_regression_models(include=selected_models, fold=folds, sort=sort_metric)
312
- else:
313
- if problem_type == "Classification":
314
- best_model = compare_classification_models(fold=folds, sort=sort_metric)
315
- else:
316
- best_model = compare_regression_models(fold=folds, sort=sort_metric)
317
- st.session_state['best_model'] = best_model
318
- st.success(f"Best Model: {best_model}")
319
-
320
- elif problem_type == "Clustering":
321
- if st.button("Create Model"):
322
- with st.spinner("Creating model..."):
323
- if selected_model == "kmeans":
324
- best_model = create_clustering_model("kmeans", num_clusters=num_clusters)
325
- elif selected_model == "dbscan":
326
- best_model = create_clustering_model("dbscan", eps=eps, min_samples=min_samples)
327
- elif selected_model == "hclust":
328
- best_model = create_clustering_model("hclust", num_clusters=num_clusters)
329
  else:
330
- best_model = create_clustering_model(selected_model)
331
- st.session_state['best_model'] = best_model
332
- st.success(f"Model Created: {selected_model}")
333
-
334
- if 'best_model' in st.session_state and st.session_state['best_model'] is not None:
335
- st.subheader("Model Evaluation and Tuning")
336
- col1, col2 = st.columns(2)
337
- with col1:
338
- if st.button("Evaluate Model"):
339
- with st.spinner("Evaluating model..."):
340
- if st.session_state['problem_type'] == "Classification":
341
- evaluate_classification_model(st.session_state['best_model'])
342
- elif st.session_state['problem_type'] == "Regression":
343
- evaluate_regression_model(st.session_state['best_model'])
344
- elif st.session_state['problem_type'] == "Clustering":
345
- evaluate_clustering_model(st.session_state['best_model'])
346
- st.success("Model evaluation complete!")
347
- with col2:
348
- if problem_type in ["Classification", "Regression"]:
349
- if st.button("Tune Model"):
350
- with st.spinner("Tuning model..."):
351
- if problem_type == "Classification":
352
- tuned_model = tune_classification_model(st.session_state['best_model'], fold=folds, optimize=sort_metric)
353
- else:
354
- tuned_model = tune_regression_model(st.session_state['best_model'], fold=folds, optimize=sort_metric)
355
- st.session_state['best_model'] = tuned_model
356
- st.success(f"Tuned Model: {tuned_model}")
 
 
 
 
 
 
 
357
 
358
- if st.button("Save Model"):
359
- if st.session_state['problem_type'] == "Classification":
360
- save_classification_model(st.session_state['best_model'], "best_model")
361
- elif st.session_state['problem_type'] == "Regression":
362
- save_regression_model(st.session_state['best_model'], "best_model")
363
- elif st.session_state['problem_type'] == "Clustering":
364
- save_clustering_model(st.session_state['best_model'], "best_model")
365
- st.success("Model saved as `best_model.pkl`!")
366
- with open("best_model.pkl", "rb") as f:
367
- st.download_button("Download Model", f, file_name="best_model.pkl")
 
 
 
 
 
 
368
 
369
- elif app_mode == "Validation & Exploration":
370
- st.title("🔍 Validation & Exploration")
371
- if 'best_model' not in st.session_state or st.session_state['best_model'] is None:
372
- st.warning("Please train a model first.")
373
- st.stop()
 
374
 
375
- st.subheader("Model Performance")
376
- if st.session_state['problem_type'] == "Classification":
377
- st.write("Classification Report:")
378
- plot_classification_model(st.session_state['best_model'], plot="confusion_matrix", display_format="streamlit")
379
- plot_classification_model(st.session_state['best_model'], plot="auc", display_format="streamlit")
380
- elif st.session_state['problem_type'] == "Regression":
381
- st.write("Regression Metrics:")
382
- plot_regression_model(st.session_state['best_model'], plot="residuals", display_format="streamlit")
383
- plot_regression_model(st.session_state['best_model'], plot="error", display_format="streamlit")
384
- elif st.session_state['problem_type'] == "Clustering":
385
- st.write("Clustering Results:")
386
- plot_clustering_model(st.session_state['best_model'], plot="cluster", display_format="streamlit")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
387
 
388
- # Chatbot Section
389
- st.markdown("---")
390
- st.subheader("💬 AI Chatbot Assistant (DeepSeek Powered)")
391
- st.info("Ask me to adjust data, explore it, or get suggestions! Try: 'drop columns X, Y', 'scatter plot of X vs Y', 'suggest preprocessing', or 'analyze plot'")
392
- if "chat_history" not in st.session_state:
393
- st.session_state.chat_history = []
394
 
395
- for message in st.session_state.chat_history:
396
- with st.chat_message(message["role"]):
397
- st.markdown(message["content"])
 
 
 
 
 
 
 
 
 
 
 
 
 
 
398
 
399
- user_input = st.chat_input("Ask me anything about the app or your data...")
400
- if user_input:
401
- st.session_state.chat_history.append({"role": "user", "content": user_input})
402
- with st.chat_message("user"):
403
- st.markdown(user_input)
404
- with st.spinner("Processing..."):
405
- func, param = parse_command(user_input)
406
- if func:
407
- response = func(param) if param else func(None)
408
- else:
409
- response = deepseek_chat(user_input, app_mode)
410
- st.session_state.chat_history.append({"role": "assistant", "content": response})
411
- with st.chat_message("assistant"):
412
- st.markdown(response)
413
 
414
- # Custom CSS
415
- st.markdown("""
416
- <style>
417
- .stButton>button {background-color: #4CAF50; color: white;}
418
- h1, h2 {color: #1e3a8a;}
419
- </style>
420
- """, unsafe_allow_html=True)
 
1
  import streamlit as st
2
  import pandas as pd
3
  import plotly.express as px
4
+ import numpy as np
5
+ from pycaret.classification import *
6
+ from pycaret.regression import *
7
+ from pycaret.clustering import *
8
  from ydata_profiling import ProfileReport
9
  from streamlit_pandas_profiling import st_profile_report
10
+ import mlflow
11
  import requests
12
  import json
13
+ import os
 
14
 
15
  # Set page config
16
  st.set_page_config(page_title="Neural-Vision Enhanced", layout="wide")
17
 
18
+ # MLflow Tracking
19
+ mlflow.set_tracking_uri("http://127.0.0.1:5000")
20
+ mlflow.set_experiment("Neural-Vision Enhanced")
21
 
22
+ # Initialize session state
23
+ if 'metrics' not in st.session_state:
24
+ st.session_state.metrics = {}
25
+ if 'chat_history' not in st.session_state:
26
+ st.session_state.chat_history = []
 
 
 
27
 
28
+ # Enhanced Visualization Functions
29
+ def visualize_classification():
30
+ col1, col2 = st.columns(2)
31
+ with col1:
32
+ plot_model(st.session_state.best_model, plot='confusion_matrix', display_format='streamlit')
33
+ with col2:
34
+ plot_model(st.session_state.best_model, plot='auc', display_format='streamlit')
35
+
36
+ col3, col4 = st.columns(2)
37
+ with col3:
38
+ plot_model(st.session_state.best_model, plot='feature', display_format='streamlit')
39
+ with col4:
40
+ plot_model(st.session_state.best_model, plot='pr', display_format='streamlit')
41
+
42
+ def visualize_regression():
43
+ col1, col2 = st.columns(2)
44
+ with col1:
45
+ plot_model(st.session_state.best_model, plot='residuals', display_format='streamlit')
46
+ with col2:
47
+ plot_model(st.session_state.best_model, plot='error', display_format='streamlit')
48
+
49
+ col3, col4 = st.columns(2)
50
+ with col3:
51
+ plot_model(st.session_state.best_model, plot='cooks', display_format='streamlit')
52
+ with col4:
53
+ plot_model(st.session_state.best_model, plot='learning', display_format='streamlit')
54
+
55
+ def visualize_clustering():
56
+ col1, col2 = st.columns(2)
57
+ with col1:
58
+ plot_model(st.session_state.best_model, plot='cluster', display_format='streamlit')
59
+ with col2:
60
+ plot_model(st.session_state.best_model, plot='distribution', display_format='streamlit')
61
+
62
+ col3, col4 = st.columns(2)
63
+ with col3:
64
+ plot_model(st.session_state.best_model, plot='elbow', display_format='streamlit')
65
+ with col4:
66
+ plot_model(st.session_state.best_model, plot='silhouette', display_format='streamlit')
67
+
68
+ # Enhanced Context Generator
69
+ def get_app_context():
70
+ context = {
71
+ "current_state": {
72
+ "active_page": st.session_state.get('active_page', 'Data Upload'),
73
+ "dataset_stats": {},
74
+ "model_metrics": st.session_state.metrics,
75
+ "problem_type": st.session_state.get('problem_type'),
76
+ "target": st.session_state.get('target'),
77
+ "best_model": str(st.session_state.get('best_model', None))
78
+ },
79
+ "app_capabilities": [
80
+ "CSV data upload and statistical analysis",
81
+ "Automated EDA report generation",
82
+ "PyCaret-powered model training for classification, regression, and clustering",
83
+ "Advanced model evaluation visualizations",
84
+ "ML experiment tracking with MLflow",
85
+ "AI-powered analysis through DeepSeek integration"
86
+ ]
87
+ }
88
+
89
  if 'df' in st.session_state:
90
+ df = st.session_state.df
91
+ context["current_state"]["dataset_stats"] = {
92
+ "rows": df.shape[0],
93
+ "columns": df.shape[1],
94
+ "missing_values": df.isna().sum().sum(),
95
+ "columns": {col: str(df[col].dtype) for col in df.columns}
96
+ }
97
+
98
+ return json.dumps(context)
 
 
 
 
99
 
100
+ # Chatbot Handler
101
+ def handle_ai_query(prompt):
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
102
  try:
103
  response = requests.post(
104
+ "http://127.0.0.1:5001/analyze",
105
+ json={
106
+ "prompt": prompt,
107
+ "context": get_app_context(),
108
+ "metrics": st.session_state.metrics
109
+ }
110
  )
111
+ return response.json().get("analysis", "Error in analysis")
112
+ except Exception as e:
113
+ return f"Analysis error: {str(e)}"
114
+
115
+ # Main App Components
116
+ def data_upload_page():
117
+ st.title("📤 Data Upload & Analysis")
118
+ uploaded_file = st.file_uploader("Upload Dataset", type=["csv"])
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
119
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
120
  if uploaded_file:
121
  df = pd.read_csv(uploaded_file)
122
+ st.session_state.df = df
123
+ st.session_state.metrics = {}
124
+
125
+ st.subheader("Dataset Health Check")
 
 
 
126
  col1, col2, col3 = st.columns(3)
127
+ col1.metric("Total Samples", df.shape[0])
128
+ col2.metric("Features", df.shape[1])
129
+ col3.metric("Missing Values", df.isna().sum().sum())
130
+
131
+ if st.button("Generate Full EDA Report"):
132
+ with st.spinner("Generating comprehensive analysis..."):
 
133
  profile = ProfileReport(df, explorative=True)
134
  st_profile_report(profile)
 
 
135
 
136
+ def model_training_page():
137
+ st.title("🧠 Model Training Studio")
138
+
139
  if 'df' not in st.session_state:
140
+ st.warning("Upload data first!")
141
+ return
142
+
143
+ df = st.session_state.df
144
+ problem_type = st.selectbox("Select Problem Type",
145
+ ["Classification", "Regression", "Clustering"])
146
+
147
+ if problem_type != "Clustering":
148
+ target = st.selectbox("Select Target Variable", df.columns)
149
+ st.session_state.target = target
150
+
151
+ if st.button("Initialize Training Environment"):
152
+ with st.spinner("Configuring PyCaret..."):
153
  if problem_type == "Classification":
154
+ classification_setup(df, target=target, session_id=42)
 
 
 
155
  elif problem_type == "Regression":
156
+ regression_setup(df, target=target, session_id=42)
157
+ else:
158
+ clustering_setup(df, session_id=42)
159
+ st.session_state.problem_type = problem_type
160
+ st.success("Environment ready for modeling!")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
161
 
162
+ if 'problem_type' in st.session_state:
163
+ st.subheader("Model Training Dashboard")
164
+ if st.session_state.problem_type in ["Classification", "Regression"]:
165
+ compare_models = st.checkbox("Compare Multiple Models", True)
166
+ n_models = st.slider("Number of Models", 1, 15, 5) if compare_models else 1
167
+
168
+ if st.button("Start Training"):
169
+ with st.spinner("Training in progress..."):
170
+ if compare_models:
171
+ models = compare_models(n_select=n_models)
172
+ st.session_state.best_model = models[0]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
173
  else:
174
+ st.session_state.best_model = create_model()
175
+
176
+ # Capture metrics
177
+ results = pull()
178
+ st.session_state.metrics = results.to_dict()
179
+ st.success(f"Best Model: {st.session_state.best_model}")
180
+
181
+ # Log to MLflow
182
+ with mlflow.start_run():
183
+ mlflow.log_metrics(results.iloc[0].to_dict())
184
+ mlflow.sklearn.log_model(st.session_state.best_model, "model")
185
+
186
+ def visualization_page():
187
+ st.title("🔍 Model Evaluation Center")
188
+
189
+ if 'best_model' not in st.session_state:
190
+ st.warning("Train a model first!")
191
+ return
192
+
193
+ st.subheader("Performance Analysis")
194
+
195
+ if st.session_state.problem_type == "Classification":
196
+ visualize_classification()
197
+ elif st.session_state.problem_type == "Regression":
198
+ visualize_regression()
199
+ else:
200
+ visualize_clustering()
201
+
202
+ st.subheader("Metric Analysis")
203
+ st.dataframe(pd.DataFrame.from_dict(st.session_state.metrics))
204
+
205
+ if st.button("Request AI Analysis"):
206
+ analysis = handle_ai_query("Analyze these model metrics")
207
+ st.markdown(f"**AI Analysis:**\n\n{analysis}")
208
 
209
+ # Chatbot Interface
210
+ def ai_assistant():
211
+ st.markdown("---")
212
+ st.subheader("🧠 Neural Insight Assistant")
213
+
214
+ for msg in st.session_state.chat_history:
215
+ st.chat_message(msg["role"]).write(msg["content"])
216
+
217
+ if prompt := st.chat_input("Ask about models, data, or app usage"):
218
+ st.session_state.chat_history.append({"role": "user", "content": prompt})
219
+ st.chat_message("user").write(prompt)
220
+
221
+ response = handle_ai_query(prompt)
222
+
223
+ st.session_state.chat_history.append({"role": "assistant", "content": response})
224
+ st.chat_message("assistant").write(response)
225
 
226
+ # Flask Backend (app_backend.py)
227
+ """
228
+ from flask import Flask, request, jsonify
229
+ from flask_cors import CORS
230
+ import openai
231
+ import os
232
 
233
+ app = Flask(__name__)
234
+ CORS(app)
235
+
236
+ openai.api_key = os.getenv("DEEPSEEK_API_KEY")
237
+ openai.api_base = "https://api.deepseek.com/v1"
238
+
239
+ SYSTEM_PROMPT = '''
240
+ You are Neural Analyst, an AI assistant for the Neural-Vision Enhanced analytics platform.
241
+ Your capabilities include:
242
+
243
+ 1. Explaining model metrics and evaluation visualizations
244
+ 2. Interpreting dataset statistics and EDA reports
245
+ 3. Guiding users through app functionality
246
+ 4. Providing data science insights
247
+ 5. Comparing different model performances
248
+
249
+ Always consider:
250
+ - Current dataset statistics: {dataset_stats}
251
+ - Active problem type: {problem_type}
252
+ - Model metrics: {metrics}
253
+ - App state: {active_page}
254
+ '''
255
+
256
+ @app.route('/analyze', methods=['POST'])
257
+ def analyze():
258
+ data = request.json
259
+ context = json.loads(data['context'])
260
+
261
+ prompt = f'''
262
+ User Query: {data['prompt']}
263
+
264
+ Current Context:
265
+ - Active Page: {context['current_state']['active_page']}
266
+ - Problem Type: {context['current_state']['problem_type']}
267
+ - Target Variable: {context['current_state']['target']}
268
+ - Dataset Shape: {context['current_state']['dataset_stats'].get('rows', 0)} rows,
269
+ {context['current_state']['dataset_stats'].get('columns', 0)} columns
270
+ - Model Metrics: {json.dumps(context['current_state']['model_metrics'])}
271
+ '''
272
+
273
+ response = openai.ChatCompletion.create(
274
+ model="deepseek-chat",
275
+ messages=[{
276
+ "role": "system",
277
+ "content": SYSTEM_PROMPT.format(**context['current_state'])
278
+ }, {
279
+ "role": "user",
280
+ "content": prompt
281
+ }],
282
+ temperature=0.3,
283
+ max_tokens=500
284
+ )
285
+
286
+ return jsonify({"analysis": response.choices[0].message.content})
287
 
288
+ if __name__ == '__main__':
289
+ app.run(port=5001)
290
+ """
 
 
 
291
 
292
+ # App Layout
293
+ with st.sidebar:
294
+ st.title("🔮 Neural-Vision Enhanced")
295
+ page = st.selectbox("Navigation", [
296
+ "Data Upload & Analysis",
297
+ "Model Training Studio",
298
+ "Model Evaluation Center"
299
+ ])
300
+ st.session_state.active_page = page
301
+ st.markdown("---")
302
+ st.markdown("**DeepSeek API Key**")
303
+ os.environ["DEEPSEEK_API_KEY"] = st.text_input(
304
+ "Enter API Key:", type="password",
305
+ help="Required for AI analysis features"
306
+ )
307
+ st.markdown("---")
308
+ st.markdown("v4.0 | © 2025 Neural-Vision")
309
 
310
+ # Page Routing
311
+ if "Data Upload & Analysis" in page:
312
+ data_upload_page()
313
+ elif "Model Training Studio" in page:
314
+ model_training_page()
315
+ else:
316
+ visualization_page()
 
 
 
 
 
 
 
317
 
318
+ ai_assistant()