AIdashboard / src /app.py
enacimie's picture
Update src/app.py
9b43a45 verified
raw
history blame
8.29 kB
import streamlit as st
import pandas as pd
import plotly.express as px
import plotly.graph_objects as go
from sklearn.linear_model import LinearRegression
from sklearn.preprocessing import PolynomialFeatures
from sklearn.neighbors import KNeighborsRegressor
from sklearn.metrics import r2_score, mean_squared_error
import numpy as np
import requests
# Configuración inicial
st.set_page_config(page_title="📊 Dashboard Avanzado", layout="wide")
st.title("🧠 Dashboard Dinámico con Análisis Avanzado")
st.markdown("Carga un CSV y explora visualizaciones + modelos de ML + IA generativa.")
# Subida de archivo
uploaded_file = st.file_uploader("📁 Cargar archivo CSV", type=["csv"])
if uploaded_file:
df = pd.read_csv(uploaded_file)
# Tabs para organización
tabs = st.tabs([
"🔍 Datos",
"📊 Visualizaciones",
"🤖 Machine Learning",
"🧠 Análisis con IA Generativa"
])
# Pestaña 1: Datos
with tabs[0]:
st.subheader("Datos Cargados")
st.dataframe(df.head(10))
st.subheader("Resumen Estadístico")
st.write(df.describe(include="all"))
# Pestaña 2: Visualizaciones
with tabs[1]:
st.subheader("Generador Automático de Visualizaciones")
# Filtro de columnas numéricas/categóricas
numeric_cols = df.select_dtypes(include=np.number).columns.tolist()
cat_cols = df.select_dtypes(exclude=np.number).columns.tolist()
# Selección de tipo de gráfico
plot_type = st.selectbox(
"Selecciona el tipo de gráfico",
["Scatter", "Line", "Bar", "Histogram", "Box", "Correlation Matrix"]
)
# Parámetros dinámicos según tipo de gráfico
cols_to_use = []
if plot_type in ["Scatter", "Line"]:
cols_to_use = numeric_cols
elif plot_type == "Bar":
cols_to_use = cat_cols + numeric_cols
elif plot_type == "Histogram":
cols_to_use = numeric_cols
elif plot_type == "Box":
cols_to_use = numeric_cols
cat_cols.insert(0, "None")
category = st.selectbox("Variable categórica (opcional)", cat_cols)
if cols_to_use:
x_col = st.selectbox("Eje X", cols_to_use)
y_col = st.selectbox("Eje Y", cols_to_use if plot_type != "Histogram" else [None])
# Generar gráfico
if st.button("Generar Gráfico"):
try:
fig = None
if plot_type == "Scatter":
fig = px.scatter(df, x=x_col, y=y_col) # Sin trendline para evitar dependencia statsmodels
elif plot_type == "Line":
fig = px.line(df, x=x_col, y=y_col)
elif plot_type == "Bar":
fig = px.bar(df.groupby(x_col)[y_col].mean().reset_index(), x=x_col, y=y_col)
elif plot_type == "Histogram":
fig = px.histogram(df, x=x_col)
elif plot_type == "Box":
fig = px.box(df, x=category if category != "None" else None, y=x_col)
elif plot_type == "Correlation Matrix":
fig = px.imshow(df.corr(numeric_only=True))
if fig:
st.plotly_chart(fig)
except Exception as e:
st.error(f"Error al generar el gráfico: {e}")
# Pestaña 3: Machine Learning
with tabs[2]:
st.subheader("Modelos de Machine Learning")
# Selección de modelo
model_type = st.selectbox(
"Selecciona un modelo",
["Linear Regression", "Polynomial Regression", "K-Nearest Neighbors"]
)
# Selección de variables
numeric_cols = df.select_dtypes(include=np.number).columns.tolist()
if len(numeric_cols) < 2:
st.warning("Necesitas al menos dos columnas numéricas para entrenar un modelo.")
else:
target = st.selectbox("Variable objetivo (Y)", numeric_cols)
features = st.multiselect("Variables independientes (X)", numeric_cols, default=numeric_cols[:1])
if st.button("Entrenar Modelo"):
if len(features) == 0 or target is None:
st.error("Selecciona al menos una variable independiente y una dependiente.")
else:
X = df[features]
y = df[target]
# Entrenamiento según modelo
model = None
if model_type == "Linear Regression":
model = LinearRegression()
elif model_type == "Polynomial Regression":
poly = PolynomialFeatures(degree=2)
X = poly.fit_transform(X)
model = LinearRegression()
elif model_type == "K-Nearest Neighbors":
model = KNeighborsRegressor(n_neighbors=5)
model.fit(X, y)
y_pred = model.predict(X)
# Métricas
r2 = r2_score(y, y_pred)
mse = mean_squared_error(y, y_pred)
# Resultados
st.write(f"**R² Score:** {r2:.2f}")
st.write(f"**Mean Squared Error:** {mse:.2f}")
# Gráfico de predicción vs real
fig = go.Figure()
fig.add_trace(go.Scatter(x=y, y=y_pred, mode='markers', name='Predicción'))
fig.add_trace(go.Scatter(x=[y.min(), y.max()], y=[y.min(), y.max()], mode='lines', name='Ideal'))
fig.update_layout(title="Predicción vs Valores Reales", xaxis_title="Real", yaxis_title="Predicho")
st.plotly_chart(fig)
# Pestaña 4: IA Generativa
with tabs[3]:
st.subheader("💬 Usar IA Generativa (Gemini API)")
st.markdown("Introduce tu clave de API de Gemini y haz preguntas sobre los datos.")
# Campo para la API Key
gemini_api_key = st.text_input("Gemini API Key", type="password")
# Campo para la pregunta
user_query = st.text_area(
"Haz una pregunta sobre los datos",
"¿Cuál es el promedio de la columna X? ¿Hay alguna correlación entre X e Y?"
)
if st.button("Enviar a Gemini"):
if not gemini_api_key:
st.error("Por favor, introduce una API Key válida.")
else:
try:
# Datos del dataset como contexto
context = f"""
Estos son los primeros 5 registros del dataset cargado:
{df.head().to_string()}
Pregunta del usuario: {user_query}
"""
# Llamada a la API de Gemini
url = "https://generativelanguage.googleapis.com/v1beta/models/gemini-pro:generateContent?key=" + gemini_api_key
payload = {
"contents": [{"parts": [{"text": context}]}]
}
headers = {
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
if response.status_code == 200:
result = response.json()
ai_response = result["candidates"][0]["content"]["parts"][0]["text"]
st.markdown("### 🤖 Respuesta de Gemini:")
st.markdown(ai_response)
else:
st.error(f"Error en la API: {response.status_code} - {response.text}")
except Exception as e:
st.error(f"Error al conectar con Gemini: {e}")