-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathapp.py
More file actions
209 lines (182 loc) · 8.33 KB
/
Copy pathapp.py
File metadata and controls
209 lines (182 loc) · 8.33 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
import streamlit as st
import pandas as pd
import os
from ml_engine import PredictIQEngine
import base64
from dotenv import load_dotenv
# Load environment variables
load_dotenv()
# Set Page Config
st.set_page_config(
page_title="PredictIQ - AI Data Analyst",
page_icon="🧠",
layout="wide",
initial_sidebar_state="expanded"
)
# Load CSS
def local_css(file_name):
with open(file_name) as f:
st.markdown(f"<style>{f.read()}</style>", unsafe_allow_html=True)
# Helper for base64 images
def show_b64_img(b64_str):
st.image(base64.b64decode(b64_str), use_container_width=True)
# Initialize Engine
if 'engine' not in st.session_state:
# Use environment variable for security
api_key = os.getenv("GROQ_API_KEY")
st.session_state.engine = PredictIQEngine(groq_api_key=api_key)
if 'results' not in st.session_state:
st.session_state.results = None
# App Layout
local_css("style.css")
with st.sidebar:
st.markdown("<h1 style='color: #818cf8;'>PredictIQ</h1>", unsafe_allow_html=True)
st.markdown("---")
uploaded_file = st.file_uploader("Upload Dataset (CSV)", type=["csv"])
if uploaded_file:
# Reset results if a different file is uploaded
if 'last_file' not in st.session_state or st.session_state.last_file != uploaded_file.name:
st.session_state.results_ready = False
st.session_state.eval_data = None
st.session_state.last_file = uploaded_file.name
df = pd.read_csv(uploaded_file)
# Use a consistent variable name 'columns'
columns = st.session_state.engine.load_data(df)
st.write("### ⚙️ Configuration")
# Smart Target Detection
suggested_target = st.session_state.engine.detect_target()
target_col = st.selectbox(
"Target Column:",
options=columns,
index=columns.index(suggested_target)
)
# Feature Selection
suggested_drops = st.session_state.engine.get_suggested_drops()
cols_to_drop = st.multiselect(
"Exclude Columns:",
options=[c for c in columns if c != target_col],
default=[c for c in suggested_drops if c in columns and c != target_col],
help="PredictIQ identified these as likely IDs or high-cardinality columns."
)
st.markdown("---")
if st.button("🚀 Run AI Analysis", use_container_width=True):
with st.spinner("🧠 Training & Analyzing..."):
try:
# Training with universal parameters
st.session_state.engine.train(target_col, columns_to_drop=cols_to_drop)
st.session_state.eval_data = st.session_state.engine.evaluate()
st.session_state.results_ready = True
st.success("Analysis Complete!")
except Exception as e:
st.error(f"Analysis failed: {str(e)}")
st.session_state.results_ready = False
st.markdown("---")
st.info("PredictIQ uses AutoML and Groq LLM to provide deep insights into your datasets.")
# Main Interface
st.markdown("<div class='main-title'>PredictIQ AI Analyst</div>", unsafe_allow_html=True)
st.markdown("<div class='subtitle'>Automated Machine Learning & AI-Powered Data Insights</div>", unsafe_allow_html=True)
if not uploaded_file:
st.markdown("""
<div class='glass-card animate-fade-in'>
<h3>Welcome to PredictIQ</h3>
<p>Upload a CSV file in the sidebar to begin your automated analysis.</p>
<ul>
<li>Automated Feature Engineering</li>
<li>Problem Type Detection (Classification/Regression)</li>
<li>Intelligent Feature Selection (ID detection)</li>
<li>AI-Powered Narrative Insights</li>
</ul>
</div>
""", unsafe_allow_html=True)
else:
# Data Preview Section
with st.expander("📊 Dataset Exploration", expanded=True):
st.write("### Data Preview")
st.dataframe(df.head(10), use_container_width=True)
st.info(f"💾 **Stats:** {df.shape[0]} rows | {df.shape[1]} columns")
if st.session_state.get('results_ready'):
# RESULTS DASHBOARD
st.markdown("## 📈 Performance Summary")
col1, col2, col3 = st.columns(3)
with col1:
st.markdown(f"""
<div class='metric-card'>
<div class='metric-label'>Best Model</div>
<div class='metric-value' style='font-size: 1.5rem;'>{st.session_state.engine.results['best_model']}</div>
</div>
""", unsafe_allow_html=True)
with col2:
score_label = "Accuracy" if st.session_state.engine.problem_type == "classification" else "R² Score"
st.markdown(f"""
<div class='metric-card'>
<div class='metric-label'>{score_label}</div>
<div class='metric-value'>{st.session_state.engine.best_score:.4f}</div>
</div>
""", unsafe_allow_html=True)
with col3:
st.markdown(f"""
<div class='metric-card'>
<div class='metric-label'>Problem Type</div>
<div class='metric-value'>{st.session_state.engine.problem_type.capitalize()}</div>
</div>
""", unsafe_allow_html=True)
# EDA & Evaluation Tabs
tab1, tab2, tab3 = st.tabs(["🔍 Exploratory Data Analysis", "🎯 Model Evaluation", "🤖 AI Analyst Report"])
with tab1:
st.markdown("### Automated EDA")
plots = st.session_state.engine.get_eda_plots()
if 'correlation_matrix' in plots:
st.write("#### Feature Correlation")
show_b64_img(plots['correlation_matrix'])
st.write("#### Feature Distributions")
cols = st.columns(2)
for i, (name, b64) in enumerate(plots.items()):
if name != 'correlation_matrix':
with cols[i % 2]:
show_b64_img(b64)
with tab2:
st.markdown("### Model Metrics")
eval_data = st.session_state.eval_data
if st.session_state.engine.problem_type == "classification":
c1, c2 = st.columns([1, 1])
with c1:
st.write("#### Classification Report")
report_df = pd.DataFrame(eval_data['report']).transpose()
st.dataframe(report_df.style.highlight_max(axis=0))
with c2:
st.write("#### Confusion Matrix")
show_b64_img(eval_data['confusion_matrix'])
else:
st.write("#### Regression Metrics")
metrics = eval_data['metrics']
m_col1, m_col2, m_col3 = st.columns(3)
m_col1.metric("R² Score", f"{metrics['R2']:.4f}")
m_col2.metric("MAPE", f"{metrics['MAPE']:.4f}")
m_col3.metric("RMSE", f"{metrics['RMSE']:.4f}")
with tab3:
st.markdown("### AI-Generated Insights")
st.markdown(f"""
<div class='glass-card' style='border-left: 5px solid #a855f7;'>
{st.session_state.eval_data['ai_insights']}
</div>
""", unsafe_allow_html=True)
# Download Report
report_text = f"PredictIQ Analysis Report\n" + "="*25 + "\n"
report_text += f"Best Model: {st.session_state.engine.results['best_model']}\n"
report_text += f"Score: {st.session_state.engine.best_score:.4f}\n\n"
report_text += "AI ANALYST INSIGHTS:\n" + st.session_state.eval_data['ai_insights']
st.download_button(
label="📥 Download Analysis Report",
data=report_text,
file_name="predictiq_report.txt",
mime="text/plain"
)
# Download Model
model_path = st.session_state.engine.save_model()
with open(model_path, "rb") as f:
st.download_button(
label="💾 Download Best Model (.pkl)",
data=f,
file_name="best_model.pkl",
mime="application/octet-stream"
)