Spaces:
Sleeping
Sleeping
| """ | |
| DataCrew AI - Interface Gradio para Hugging Face Spaces | |
| Análise Inteligente de Dados com IA | |
| Desenvolvido por: Gleison Leoni | |
| """ | |
| import gradio as gr | |
| import pandas as pd | |
| import os | |
| import requests | |
| import json | |
| import plotly.express as px | |
| import plotly.graph_objects as go | |
| # API Key Groq (será configurada pelo usuário) | |
| groq_api_key = None | |
| def initialize_groq(api_key): | |
| """Inicializa/valida a API key do Groq""" | |
| global groq_api_key | |
| if not api_key or not api_key.startswith('gsk_'): | |
| return "❌ API Key inválida! Deve começar com 'gsk_'" | |
| try: | |
| # Testar a API key com uma chamada simples | |
| headers = { | |
| "Authorization": f"Bearer {api_key}", | |
| "Content-Type": "application/json" | |
| } | |
| response = requests.post( | |
| "https://api.groq.com/openai/v1/chat/completions", | |
| headers=headers, | |
| json={ | |
| "model": "llama-3.3-70b-versatile", | |
| "messages": [{"role": "user", "content": "test"}], | |
| "max_tokens": 5 | |
| }, | |
| timeout=10 | |
| ) | |
| if response.status_code == 200: | |
| groq_api_key = api_key | |
| return "✅ API Key configurada com sucesso!" | |
| elif response.status_code == 401: | |
| return "❌ API Key inválida ou expirada" | |
| else: | |
| return f"❌ Erro: {response.status_code} - {response.text[:100]}" | |
| except requests.exceptions.Timeout: | |
| return "❌ Timeout - Verifique sua conexão" | |
| except Exception as e: | |
| return f"❌ Erro ao validar API Key: {str(e)}" | |
| def analyze_csv(file): | |
| """Analisa o arquivo CSV e retorna estatísticas""" | |
| if file is None: | |
| return "⚠️ Por favor, faça upload de um arquivo CSV primeiro.", None | |
| try: | |
| # Ler CSV | |
| df = pd.read_csv(file.name) | |
| # Análise básica | |
| analysis = f""" | |
| 📊 **Análise Automática do Dataset** | |
| **Dimensões:** | |
| - Linhas: {len(df):,} | |
| - Colunas: {len(df.columns)} | |
| - Tamanho: {df.memory_usage(deep=True).sum() / 1024:.2f} KB | |
| **Colunas ({len(df.columns)}):** | |
| {chr(10).join([f"• {col} ({df[col].dtype})" for col in df.columns])} | |
| **Valores Ausentes:** | |
| {df.isnull().sum().to_string() if df.isnull().sum().sum() > 0 else "✅ Nenhum valor ausente"} | |
| **Duplicatas:** | |
| {"✅ Nenhuma duplicata encontrada" if df.duplicated().sum() == 0 else f"⚠️ {df.duplicated().sum()} linhas duplicadas"} | |
| **Primeiras 10 Linhas:** | |
| """ | |
| # Retornar análise + preview dos dados | |
| return analysis, df.head(10) | |
| except Exception as e: | |
| return f"❌ Erro ao analisar CSV: {str(e)}", None | |
| def get_statistics(file): | |
| """Retorna estatísticas descritivas""" | |
| if file is None: | |
| return "⚠️ Faça upload de um CSV primeiro." | |
| try: | |
| df = pd.read_csv(file.name) | |
| # Estatísticas numéricas | |
| numeric_cols = df.select_dtypes(include=['number']).columns | |
| if len(numeric_cols) == 0: | |
| return "⚠️ Nenhuma coluna numérica encontrada no dataset." | |
| stats = f""" | |
| 📈 **Estatísticas Descritivas** | |
| **Colunas Numéricas: {len(numeric_cols)}** | |
| """ | |
| for col in numeric_cols: | |
| stats += f""" | |
| **{col}:** | |
| - Média: {df[col].mean():.2f} | |
| - Mediana: {df[col].median():.2f} | |
| - Desvio Padrão: {df[col].std():.2f} | |
| - Mínimo: {df[col].min():.2f} | |
| - Máximo: {df[col].max():.2f} | |
| - Q1 (25%): {df[col].quantile(0.25):.2f} | |
| - Q3 (75%): {df[col].quantile(0.75):.2f} | |
| """ | |
| return stats | |
| except Exception as e: | |
| return f"❌ Erro: {str(e)}" | |
| def create_visualization(file, chart_type, x_col, y_col): | |
| """Cria visualizações com Plotly""" | |
| if file is None: | |
| return None, "⚠️ Faça upload de um CSV primeiro." | |
| try: | |
| df = pd.read_csv(file.name) | |
| if x_col not in df.columns: | |
| return None, f"❌ Coluna '{x_col}' não encontrada no dataset.\n\nColunas disponíveis: {', '.join(df.columns)}" | |
| # Criar gráfico baseado no tipo | |
| if chart_type == "Histograma": | |
| fig = px.histogram(df, x=x_col, title=f"Distribuição de {x_col}", | |
| color_discrete_sequence=['#3B82F6']) | |
| elif chart_type == "Gráfico de Barras": | |
| value_counts = df[x_col].value_counts().head(20) | |
| fig = px.bar(x=value_counts.index, y=value_counts.values, | |
| labels={'x': x_col, 'y': 'Contagem'}, | |
| title=f"Contagem de {x_col}", | |
| color_discrete_sequence=['#8B5CF6']) | |
| elif chart_type == "Scatter Plot": | |
| if y_col and y_col in df.columns: | |
| fig = px.scatter(df, x=x_col, y=y_col, | |
| title=f"{x_col} vs {y_col}", | |
| color_discrete_sequence=['#EC4899']) | |
| else: | |
| return None, "❌ Para Scatter Plot, selecione duas colunas numéricas." | |
| elif chart_type == "Box Plot": | |
| fig = px.box(df, y=x_col, title=f"Box Plot de {x_col}", | |
| color_discrete_sequence=['#10B981']) | |
| elif chart_type == "Matriz de Correlação": | |
| numeric_df = df.select_dtypes(include=['number']) | |
| if len(numeric_df.columns) < 2: | |
| return None, "❌ Necessário pelo menos 2 colunas numéricas para matriz de correlação." | |
| corr = numeric_df.corr() | |
| fig = px.imshow(corr, text_auto=True, aspect="auto", | |
| title="Matriz de Correlação", | |
| color_continuous_scale='RdBu_r') | |
| else: | |
| return None, "❌ Tipo de gráfico não reconhecido." | |
| fig.update_layout( | |
| template="plotly_white", | |
| height=500, | |
| font=dict(size=12) | |
| ) | |
| return fig, f"✅ Gráfico '{chart_type}' gerado com sucesso!" | |
| except Exception as e: | |
| return None, f"❌ Erro ao criar visualização: {str(e)}" | |
| def ask_question(file, question, api_key): | |
| """Responde perguntas usando Groq via API HTTP""" | |
| global groq_api_key | |
| if not api_key: | |
| return "⚠️ Por favor, configure sua API Key do Groq primeiro na seção acima." | |
| if file is None: | |
| return "⚠️ Faça upload de um CSV primeiro." | |
| if not question: | |
| return "⚠️ Digite uma pergunta." | |
| try: | |
| # Atualizar API key se mudou | |
| if api_key != groq_api_key: | |
| result = initialize_groq(api_key) | |
| if "❌" in result: | |
| return result | |
| # Ler dados | |
| df = pd.read_csv(file.name) | |
| # Preparar contexto | |
| context = f""" | |
| Você é um analista de dados especializado. Responda a pergunta do usuário sobre este dataset de forma clara e objetiva. | |
| **Dataset:** {os.path.basename(file.name)} | |
| **Dimensões:** {len(df)} linhas × {len(df.columns)} colunas | |
| **Colunas e Tipos:** | |
| {chr(10).join([f"- {col}: {df[col].dtype} ({df[col].nunique()} valores únicos)" for col in df.columns])} | |
| **Amostra dos dados (5 primeiras linhas):** | |
| {df.head(5).to_string()} | |
| **Estatísticas das colunas numéricas:** | |
| {df.describe().to_string()} | |
| **Pergunta do usuário:** {question} | |
| Instruções para resposta: | |
| - Seja claro e objetivo | |
| - Use markdown para formatação | |
| - Destaque insights importantes com **negrito** | |
| - Se relevante, mencione números e estatísticas | |
| - Responda em português brasileiro | |
| """ | |
| # Chamar API Groq via HTTP | |
| headers = { | |
| "Authorization": f"Bearer {groq_api_key}", | |
| "Content-Type": "application/json" | |
| } | |
| payload = { | |
| "model": "llama-3.3-70b-versatile", | |
| "messages": [ | |
| {"role": "system", "content": "Você é um assistente especializado em análise de dados. Forneça respostas claras, objetivas e baseadas em dados."}, | |
| {"role": "user", "content": context} | |
| ], | |
| "temperature": 0.7, | |
| "max_tokens": 2000 | |
| } | |
| response = requests.post( | |
| "https://api.groq.com/openai/v1/chat/completions", | |
| headers=headers, | |
| json=payload, | |
| timeout=30 | |
| ) | |
| if response.status_code == 200: | |
| answer = response.json()['choices'][0]['message']['content'] | |
| return f"🤖 **Resposta da IA:**\n\n{answer}" | |
| else: | |
| return f"❌ Erro na API Groq ({response.status_code}): {response.text[:200]}" | |
| except requests.exceptions.Timeout: | |
| return "❌ Timeout - A IA demorou muito para responder. Tente novamente." | |
| except Exception as e: | |
| return f"❌ Erro ao processar pergunta: {str(e)}\n\nVerifique se sua API Key está correta." | |
| # ============================================================================ | |
| # Interface Gradio | |
| # ============================================================================ | |
| with gr.Blocks( | |
| theme=gr.themes.Soft( | |
| primary_hue="blue", | |
| secondary_hue="purple", | |
| ), | |
| title="DataCrew AI - Análise Inteligente de Dados", | |
| css=""" | |
| .gradio-container { | |
| font-family: 'Inter', sans-serif; | |
| } | |
| """ | |
| ) as demo: | |
| # Header | |
| gr.Markdown(""" | |
| # 🧠 DataCrew AI | |
| ### Análise Inteligente de Dados com Inteligência Artificial | |
| **Desenvolvido por:** Gleison Leoni | **Tecnologia:** Groq (LLaMA 3.3) + Pandas + Plotly | |
| Faça upload de um arquivo CSV e converse com seus dados usando IA de última geração! | |
| """) | |
| gr.Markdown("---") | |
| # API Key | |
| gr.Markdown("### 🔑 Configuração") | |
| gr.Markdown("Obtenha sua chave gratuita em: [console.groq.com](https://console.groq.com)") | |
| with gr.Row(): | |
| api_key_input = gr.Textbox( | |
| label="API Key do Groq", | |
| placeholder="gsk_...", | |
| type="password", | |
| scale=3 | |
| ) | |
| api_status = gr.Textbox(label="Status", interactive=False, scale=1) | |
| api_key_input.change( | |
| fn=initialize_groq, | |
| inputs=[api_key_input], | |
| outputs=[api_status] | |
| ) | |
| gr.Markdown("---") | |
| # Upload de arquivo | |
| gr.Markdown("### 📁 Upload do Dataset") | |
| file_input = gr.File( | |
| label="Arraste seu arquivo CSV aqui ou clique para fazer upload", | |
| file_types=[".csv"], | |
| type="filepath" | |
| ) | |
| gr.Markdown("---") | |
| # Tabs | |
| with gr.Tabs(): | |
| # Tab 1: Análise Automática | |
| with gr.Tab("📊 Análise Automática"): | |
| gr.Markdown(""" | |
| Clique no botão abaixo para obter uma análise completa do seu dataset: | |
| - Dimensões (linhas e colunas) | |
| - Tipos de dados | |
| - Valores ausentes e duplicatas | |
| - Preview dos dados | |
| """) | |
| analyze_btn = gr.Button("🔍 Analisar Dataset", variant="primary", size="lg") | |
| with gr.Row(): | |
| analysis_output = gr.Markdown(label="Análise") | |
| with gr.Row(): | |
| data_preview = gr.DataFrame(label="Preview dos Dados (10 primeiras linhas)") | |
| analyze_btn.click( | |
| fn=analyze_csv, | |
| inputs=[file_input], | |
| outputs=[analysis_output, data_preview] | |
| ) | |
| # Tab 2: Estatísticas | |
| with gr.Tab("📈 Estatísticas Descritivas"): | |
| gr.Markdown(""" | |
| Obtenha estatísticas detalhadas das colunas numéricas: | |
| - Média, mediana, desvio padrão | |
| - Valores mínimo e máximo | |
| - Quartis (25%, 75%) | |
| """) | |
| stats_btn = gr.Button("📊 Calcular Estatísticas", variant="primary", size="lg") | |
| stats_output = gr.Markdown(label="Estatísticas") | |
| stats_btn.click( | |
| fn=get_statistics, | |
| inputs=[file_input], | |
| outputs=[stats_output] | |
| ) | |
| # Tab 3: Visualizações | |
| with gr.Tab("📉 Gráficos e Visualizações"): | |
| gr.Markdown(""" | |
| Crie gráficos interativos dos seus dados: | |
| 1. Escolha o tipo de gráfico | |
| 2. Digite o nome da coluna (exatamente como aparece no CSV) | |
| 3. Clique em "Gerar Gráfico" | |
| """) | |
| with gr.Row(): | |
| chart_type = gr.Dropdown( | |
| choices=[ | |
| "Histograma", | |
| "Gráfico de Barras", | |
| "Scatter Plot", | |
| "Box Plot", | |
| "Matriz de Correlação" | |
| ], | |
| label="Tipo de Gráfico", | |
| value="Histograma" | |
| ) | |
| with gr.Row(): | |
| x_column = gr.Textbox( | |
| label="Coluna X", | |
| placeholder="Digite o nome exato da coluna", | |
| info="Para Histograma, Barras e Box Plot" | |
| ) | |
| y_column = gr.Textbox( | |
| label="Coluna Y (opcional)", | |
| placeholder="Apenas para Scatter Plot", | |
| info="Segunda coluna para comparação" | |
| ) | |
| create_chart_btn = gr.Button("📊 Gerar Gráfico", variant="primary", size="lg") | |
| chart_status = gr.Textbox(label="Status", interactive=False) | |
| with gr.Row(): | |
| chart_output = gr.Plot(label="Gráfico Interativo") | |
| create_chart_btn.click( | |
| fn=create_visualization, | |
| inputs=[file_input, chart_type, x_column, y_column], | |
| outputs=[chart_output, chart_status] | |
| ) | |
| # Tab 4: Chat com IA | |
| with gr.Tab("💬 Chat com IA"): | |
| gr.Markdown(""" | |
| ### Faça perguntas sobre seus dados em linguagem natural! | |
| A IA (LLaMA 3.3 70B via Groq) irá analisar seus dados e responder suas perguntas de forma inteligente. | |
| **💡 Exemplos de perguntas:** | |
| - "Quais são as principais estatísticas deste dataset?" | |
| - "Qual coluna tem mais valores ausentes?" | |
| - "Identifique possíveis outliers nos dados" | |
| - "Mostre insights sobre correlações entre variáveis" | |
| - "Faça uma análise exploratória completa" | |
| - "Sugira próximos passos para análise" | |
| """) | |
| question_input = gr.Textbox( | |
| label="❓ Sua Pergunta", | |
| placeholder="Digite sua pergunta sobre os dados...", | |
| lines=3 | |
| ) | |
| ask_btn = gr.Button("🤖 Perguntar à IA", variant="primary", size="lg") | |
| answer_output = gr.Markdown(label="Resposta da IA") | |
| # Exemplos de perguntas | |
| gr.Examples( | |
| examples=[ | |
| "Quais são as 5 principais estatísticas deste dataset?", | |
| "Identifique outliers nas colunas numéricas", | |
| "Mostre correlações entre as variáveis", | |
| "Faça uma análise exploratória completa dos dados", | |
| ], | |
| inputs=question_input, | |
| label="Clique em um exemplo para testar:" | |
| ) | |
| ask_btn.click( | |
| fn=ask_question, | |
| inputs=[file_input, question_input, api_key_input], | |
| outputs=[answer_output] | |
| ) | |
| # Footer | |
| gr.Markdown(""" | |
| --- | |
| ### 📚 Sobre este Projeto | |
| **DataCrew AI** é uma plataforma de análise inteligente de dados desenvolvida como parte do curso de Inteligência Artificial. | |
| **Tecnologias:** | |
| - 🤖 Groq (LLaMA 3.3 70B) - Processamento de linguagem natural | |
| - 🐼 Pandas - Manipulação de dados | |
| - 📊 Plotly - Visualizações interativas | |
| - 🎨 Gradio - Interface web | |
| **Desenvolvedor:** Gleison Leoni | |
| **Código Fonte:** [GitHub](https://github.com/gleison-leoni/datacrew-ai) | |
| """) | |
| # ============================================================================ | |
| # Executar | |
| # ============================================================================ | |
| if __name__ == "__main__": | |
| demo.launch() | |