Spaces:
Paused
Paused
| # utils/gemini_explainer.py | |
| import streamlit as st | |
| import google.generativeai as genai | |
| from typing import Dict, Any, Optional | |
| import h2o | |
| import os | |
| def generate_dataset_explanation(dataset, api_key=None): | |
| """ | |
| Generate a dataset explanation using Gemini AI | |
| Args: | |
| dataset (pd.DataFrame): DataFrame to explain | |
| api_key (str, optional): Gemini API key | |
| Returns: | |
| str: Explanation of the dataset | |
| """ | |
| try: | |
| # Prepare dataset information | |
| dataset_info = { | |
| 'rows': len(dataset), | |
| 'columns': len(dataset.columns), | |
| 'column_names': list(dataset.columns), | |
| 'data_types': str(dataset.dtypes), | |
| 'first_rows': dataset.head().to_string(), | |
| 'basic_stats': dataset.describe().to_string() | |
| } | |
| # Initialize Gemini Explainer | |
| explainer = GeminiExplainer(api_key) | |
| # Generate explanation | |
| explanation = explainer.generate_dataset_explanation(dataset_info) | |
| return explanation | |
| except Exception as e: | |
| return f"Error generating dataset explanation: {str(e)}" | |
| def generate_model_explanation(self, model_info: Dict[str, Any]) -> str: | |
| """ | |
| Generar una explicación detallada de un modelo de machine learning | |
| Args: | |
| model_info (dict): Información del modelo | |
| Returns: | |
| str: Explicación generada por Gemini | |
| """ | |
| prompt = f"""Proporciona una explicación detallada del modelo de machine learning: | |
| Información del Modelo: | |
| - Nombre del Modelo: {model_info.get('name', 'N/A')} | |
| - Tipo de Problema: {model_info.get('problem_type', 'N/A')} | |
| - Hiperparámetros: {model_info.get('hyperparameters', 'N/A')} | |
| - Métricas de Rendimiento: | |
| * Accuracy/R²: {model_info.get('performance_metric', 'N/A')} | |
| * Otras métricas: {model_info.get('additional_metrics', 'N/A')} | |
| En tu explicación, incluye: | |
| 1. Descripción del algoritmo | |
| 2. Funcionamiento interno del modelo | |
| 3. Interpretación de los hiperparámetros | |
| 4. Análisis de las métricas de rendimiento | |
| 5. Fortalezas y limitaciones del modelo | |
| 6. Recomendaciones para posibles mejoras""" | |
| try: | |
| response = self.model.generate_content(prompt) | |
| return response.text | |
| except Exception as e: | |
| return f"Error al generar explicación: {str(e)}" | |
| class GeminiExplainer: | |
| def __init__(self, api_key: Optional[str] = None): | |
| """ | |
| Inicializar el explicador de Gemini | |
| Args: | |
| api_key (str, opcional): API key de Google Generative AI | |
| """ | |
| self.api_key = api_key or st.session_state.get('gemini_api_key') | |
| if not self.api_key: | |
| raise ValueError("No se ha proporcionado una API key de Gemini") | |
| # Configurar la API de Gemini | |
| genai.configure(api_key=self.api_key) | |
| # Seleccionar modelo | |
| self.model = genai.GenerativeModel('gemini-1.5-flash') | |
| def generate_dataset_explanation(self, dataset_info: Dict[str, Any]) -> str: | |
| """ | |
| Generar una explicación detallada del dataset | |
| Args: | |
| dataset_info (dict): Información del dataset | |
| Returns: | |
| str: Explicación generada por Gemini | |
| """ | |
| prompt = f"""Analiza este dataset y proporciona una explicación clara y concisa de su estructura y contenido: | |
| Información del Dataset: | |
| - Dimensiones: {dataset_info.get('rows', 'N/A')} filas × {dataset_info.get('columns', 'N/A')} columnas | |
| - Columnas: {', '.join(dataset_info.get('column_names', []))} | |
| - Tipos de datos: {dataset_info.get('data_types', 'N/A')} | |
| - Primeras filas: {dataset_info.get('first_rows', 'N/A')} | |
| - Estadísticas básicas: {dataset_info.get('basic_stats', 'N/A')} | |
| En tu explicación, incluye: | |
| 1. Descripción general del dataset | |
| 2. Tipos de variables presentes | |
| 3. Posibles desafíos o consideraciones para el análisis | |
| 4. Sugerencias iniciales de preprocesamiento | |
| 5. Potenciales insights o patrones preliminares""" | |
| try: | |
| response = self.model.generate_content(prompt) | |
| return response.text | |
| except Exception as e: | |
| return f"Error al generar explicación: {str(e)}" | |
| def generate_model_explanation(self, model_info: Dict[str, Any]) -> str: | |
| """ | |
| Generar una explicación detallada de un modelo de machine learning | |
| Args: | |
| model_info (dict): Información del modelo | |
| Returns: | |
| str: Explicación generada por Gemini | |
| """ | |
| # Extraer hiperparámetros en formato legible | |
| hyperparameters = model_info.get('hyperparameters', {}) | |
| if isinstance(hyperparameters, dict): | |
| hyperparams_str = "\n".join([f"- {k}: {v}" for k, v in hyperparameters.items()]) | |
| else: | |
| hyperparams_str = str(hyperparameters) | |
| prompt = f"""Proporciona una explicación detallada del modelo de machine learning: | |
| Información del Modelo: | |
| - Nombre del Modelo: {model_info.get('name', 'N/A')} | |
| - Tipo de Problema: {model_info.get('problem_type', 'N/A')} | |
| - Hiperparámetros: | |
| {hyperparams_str} | |
| - Métricas de Rendimiento: | |
| * Accuracy/R²: {model_info.get('performance_metric', 'N/A')} | |
| * Tiempo de Entrenamiento: {model_info.get('training_time', 'N/A')} | |
| En tu explicación, incluye: | |
| 1. Descripción del algoritmo | |
| 2. Funcionamiento interno del modelo | |
| 3. Interpretación de los hiperparámetros | |
| 4. Análisis de las métricas de rendimiento | |
| 5. Fortalezas y limitaciones del modelo | |
| 6. Recomendaciones para posibles mejoras""" | |
| try: | |
| response = self.model.generate_content(prompt) | |
| return response.text | |
| except Exception as e: | |
| return f"Error al generar explicación: {str(e)}" | |
| def generate_clustering_explanation(self, clustering_info: Dict[str, Any]) -> str: | |
| """ | |
| Generar una explicación de resultados de clustering | |
| Args: | |
| clustering_info (dict): Información del clustering | |
| Returns: | |
| str: Explicación generada por Gemini | |
| """ | |
| prompt = f"""Analiza los resultados del método de clustering: | |
| Información del Clustering: | |
| - Método: {clustering_info.get('method', 'N/A')} | |
| - Número de Clusters: {clustering_info.get('n_clusters', 'N/A')} | |
| - Parámetros: {clustering_info.get('parameters', 'N/A')} | |
| - Métricas: | |
| * Silhouette Score: {clustering_info.get('silhouette_score', 'N/A')} | |
| * Calinski-Harabasz: {clustering_info.get('calinski_score', 'N/A')} | |
| * Davies-Bouldin: {clustering_info.get('davies_bouldin', 'N/A')} | |
| En tu explicación, incluye: | |
| 1. Descripción del método de clustering | |
| 2. Interpretación de los parámetros utilizados | |
| 3. Significado de las métricas de evaluación | |
| 4. Análisis de la calidad de los clusters | |
| 5. Posibles insights o patrones detectados | |
| 6. Recomendaciones para ajustar el clustering""" | |
| try: | |
| response = self.model.generate_content(prompt) | |
| return response.text | |
| except Exception as e: | |
| return f"Error al generar explicación: {str(e)}" | |
| def generate_feature_importance_explanation(self, feature_importance_info: Dict[str, Any]) -> str: | |
| """ | |
| Generar una explicación de la importancia de características | |
| Args: | |
| feature_importance_info (dict): Información de importancia de características | |
| Returns: | |
| str: Explicación generada por Gemini | |
| """ | |
| method = feature_importance_info.get('method', 'N/A') | |
| features = feature_importance_info.get('features', []) | |
| importance_values = feature_importance_info.get('importance_values', {}) | |
| # Formatear la información de importancia | |
| importance_str = "\n".join([f"- {feat}: {val}" for feat, val in importance_values.items()]) | |
| prompt = f"""Analiza la importancia de las características en el modelo: | |
| Información de Importancia de Características: | |
| - Método de Evaluación: {method} | |
| - Características: | |
| {importance_str} | |
| En tu explicación, incluye: | |
| 1. Descripción del método de evaluación de importancia | |
| 2. Análisis de las características más importantes | |
| 3. Interpretación de los valores de importancia | |
| 4. Posibles implicaciones para el modelado | |
| 5. Recomendaciones para selección de características""" | |
| try: | |
| response = self.model.generate_content(prompt) | |
| return response.text | |
| except Exception as e: | |
| return f"Error al generar explicación: {str(e)}" | |
| def initialize_gemini_explainer(): | |
| """ | |
| Función de utilidad para inicializar el explicador de Gemini en Streamlit | |
| Returns: | |
| GeminiExplainer: Instancia del explicador de Gemini o None si hay error | |
| """ | |
| try: | |
| if 'gemini_api_key' not in st.session_state: | |
| st.warning("Por favor configura tu API key de Gemini primero") | |
| return None | |
| api_key = st.session_state.get('gemini_api_key') | |
| if not api_key: | |
| st.warning("API key de Gemini no encontrada") | |
| return None | |
| # Inicializar explicador con la API key | |
| explainer = GeminiExplainer(api_key=api_key) | |
| return explainer | |
| except Exception as e: | |
| st.error(f"Error al inicializar el explicador: {str(e)}") | |
| return None | |
| # Ejemplo de uso en Streamlit | |
| def main(): | |
| st.title("Explicaciones con Gemini") | |
| # Verificar configuración de API key | |
| if 'gemini_api_key' not in st.session_state: | |
| st.warning("Configura tu API key de Gemini") | |
| return | |
| explainer = initialize_gemini_explainer() | |
| if explainer: | |
| # Ejemplo de uso de métodos de explicación | |
| st.subheader("Explicación de Dataset") | |
| dataset_info = { | |
| 'rows': 100, | |
| 'columns': 5, | |
| 'column_names': ['age', 'income', 'education', 'credit_score', 'loan_approved'], | |
| 'data_types': 'Mixed (numeric and categorical)', | |
| 'first_rows': 'Sample data preview', | |
| 'basic_stats': 'Mean, median, standard deviation' | |
| } | |
| if st.button("Explicar Dataset"): | |
| explanation = explainer.generate_dataset_explanation(dataset_info) | |
| st.markdown(explanation) | |
| st.subheader("Explicación de Modelo") | |
| model_info = { | |
| 'name': 'Random Forest Classifier', | |
| 'problem_type': 'Clasificación binaria', | |
| 'hyperparameters': { | |
| 'n_estimators': 100, | |
| 'max_depth': 5, | |
| 'learning_rate': 0.1 | |
| }, | |
| 'performance_metric': 0.85, | |
| 'additional_metrics': { | |
| 'precision': 0.82, | |
| 'recall': 0.88, | |
| 'f1_score': 0.85 | |
| } | |
| } | |
| if st.button("Explicar Modelo"): | |
| explanation = explainer.generate_model_explanation(model_info) | |
| st.markdown(explanation) | |
| st.subheader("Explicación de Clustering") | |
| clustering_info = { | |
| 'method': 'K-Means', | |
| 'n_clusters': 3, | |
| 'parameters': { | |
| 'eps': 0.5, | |
| 'min_samples': 5 | |
| }, | |
| 'silhouette_score': 0.7, | |
| 'calinski_score': 150.5, | |
| 'davies_bouldin': 0.4 | |
| } | |
| if st.button("Explicar Clustering"): | |
| explanation = explainer.generate_clustering_explanation(clustering_info) | |
| st.markdown(explanation) | |
| st.subheader("Explicación de Importancia de Características") | |
| feature_importance_info = { | |
| 'method': 'SHAP Values', | |
| 'features': ['age', 'income', 'education', 'credit_score'], | |
| 'importance_values': { | |
| 'age': 0.35, | |
| 'income': 0.25, | |
| 'education': 0.2, | |
| 'credit_score': 0.2 | |
| } | |
| } | |
| if st.button("Explicar Importancia de Características"): | |
| explanation = explainer.generate_feature_importance_explanation(feature_importance_info) | |
| st.markdown(explanation) | |
| # Función para manejar errores de API key | |
| def validate_gemini_api_key(api_key: str) -> bool: | |
| """ | |
| Validar la API key de Gemini | |
| Args: | |
| api_key (str): API key a validar | |
| Returns: | |
| bool: True si la API key es válida, False en caso contrario | |
| """ | |
| try: | |
| genai.configure(api_key=api_key) | |
| model = genai.GenerativeModel('gemini-1.5-flash') | |
| # Intentar generar una respuesta simple | |
| response = model.generate_content("Hola, ¿estás funcionando?") | |
| return True | |
| except Exception as e: | |
| st.error(f"Error de validación de API key: {str(e)}") | |
| return False | |
| # Función de configuración de API key en Streamlit | |
| def setup_gemini_api_key(): | |
| """ | |
| Configurar y validar la API key de Gemini en Streamlit | |
| """ | |
| st.sidebar.header("🔑 Configuración de Gemini API") | |
| # Input para la API key | |
| api_key = st.sidebar.text_input( | |
| "Ingresa tu Gemini API Key", | |
| type="password", | |
| help="Puedes obtener tu API key en Google AI Studio" | |
| ) | |
| # Botón de validación | |
| if st.sidebar.button("Validar API Key"): | |
| if api_key: | |
| if validate_gemini_api_key(api_key): | |
| st.session_state.gemini_api_key = api_key | |
| st.sidebar.success("✅ API Key validada correctamente") | |
| else: | |
| st.sidebar.error("❌ API Key inválida") | |
| else: | |
| st.sidebar.warning("Por favor, ingresa una API Key") | |
| # Mostrar estado actual | |
| if 'gemini_api_key' in st.session_state: | |
| st.sidebar.info("API Key configurada") | |
| # Configuraciones adicionales y documentación | |
| def get_gemini_documentation(): | |
| """ | |
| Generar documentación sobre el uso de Gemini en el proyecto | |
| Returns: | |
| str: Documentación en formato markdown | |
| """ | |
| documentation = """ | |
| ## 🤖 Explicaciones con Gemini AI | |
| ### Características | |
| - Generación de explicaciones detalladas para: | |
| * Datasets | |
| * Modelos de Machine Learning | |
| * Resultados de Clustering | |
| * Importancia de Características | |
| ### Requisitos | |
| - API Key de Google AI Studio | |
| - Conexión a internet | |
| - Biblioteca `google-generativeai` | |
| ### Configuración | |
| 1. Obtén tu API Key en [Google AI Studio](https://makersuite.google.com/app/apikey) | |
| 2. Configura la API Key en la barra lateral | |
| 3. Valida la conexión con el botón "Validar API Key" | |
| ### Limitaciones | |
| - Depende de la disponibilidad del servicio | |
| - Consumo de tokens de API | |
| - Explicaciones generadas por IA pueden no ser 100% precisas | |
| ### Mejores Prácticas | |
| - Usar como complemento, no como única fuente de verdad | |
| - Verificar siempre las explicaciones generadas | |
| - Tener contexto del problema al interpretar resultados | |
| """ | |
| return documentation | |
| # Punto de entrada principal | |
| if __name__ == "__main__": | |
| main() |