Daniel251's picture
Update app.py
6eca513 verified
Raw
History Blame Contribute Delete
43.8 kB
import gradio as gr
import pandas as pd
import numpy as np
import json
from datetime import datetime
import plotly.express as px
import plotly.graph_objects as go
from plotly.subplots import make_subplots
import warnings
from scipy import stats
warnings.filterwarnings('ignore')
# ========== SISTEMA DE ANÁLISE DE DADOS AVANÇADO ==========
class AnalisadorDadosAvancado:
"""Sistema avançado de análise e visualização de dados com 5-sigma de precisão"""
def __init__(self):
self.df = None
self.analises_realizadas = []
self.historico_analises = {}
def carregar_dados(self, dados, tipo="json"):
"""Carrega dados de diferentes fontes com validação robusta"""
try:
if tipo == "json":
if hasattr(dados, 'name'):
with open(dados.name, 'r', encoding='utf-8') as f:
conteudo = f.read()
dados_json = json.loads(conteudo)
self.df = pd.DataFrame(dados_json)
else:
dados_json = json.loads(dados)
self.df = pd.DataFrame(dados_json)
elif tipo == "csv":
self.df = pd.read_csv(dados.name, encoding='utf-8')
elif tipo == "excel":
self.df = pd.read_excel(dados.name)
# Validação de dados
if self.df is None or self.df.empty:
return False, "❌ Arquivo vazio - nenhum dado para processar"
# Converter colunas numéricas de forma mais robusta
for col in self.df.columns:
if self.df[col].dtype == 'object':
try:
self.df[col] = pd.to_numeric(self.df[col], errors='ignore')
except:
pass
self.analises_realizadas.append(f"Dados carregados - {self.df.shape[0]} linhas × {self.df.shape[1]} colunas")
return True, f"✅ Dados carregados com sucesso!\n📊 {self.df.shape[0]} linhas × {self.df.shape[1]} colunas"
except json.JSONDecodeError as e:
return False, f"❌ Erro no formato JSON: {str(e)}\nVerifique se o JSON está bem formatado."
except Exception as e:
return False, f"❌ Erro ao carregar dados: {str(e)}"
def analise_exploratoria(self):
"""Realiza análise exploratória completa com estatísticas de 5-sigma"""
if self.df is None or self.df.empty:
return {"erro": "Nenhum dado carregado"}
colunas_numericas = self.df.select_dtypes(include=[np.number]).columns.tolist()
colunas_categoricas = self.df.select_dtypes(include=['object', 'category']).columns.tolist()
analise = {
'dimensoes': f"{self.df.shape[0]} linhas × {self.df.shape[1]} colunas",
'tipos_dados': {str(k): str(v) for k, v in self.df.dtypes.to_dict().items()},
'valores_nulos': {str(k): int(v) for k, v in self.df.isnull().sum().to_dict().items()},
'percentual_nulos': {str(k): float(v) for k, v in (self.df.isnull().sum() / len(self.df) * 100).to_dict().items()},
'estatisticas_descritivas': self.df.describe().to_dict() if len(colunas_numericas) > 0 else {},
'colunas_numericas': colunas_numericas,
'colunas_categoricas': colunas_categoricas,
'memoria_uso': f"{self.df.memory_usage(deep=True).sum() / 1024**2:.2f} MB",
'valores_unicos': {str(col): int(self.df[col].nunique()) for col in self.df.columns}
}
self.analises_realizadas.append("Análise exploratória realizada")
self.historico_analises['exploratoria'] = analise
return analise
def analise_estatistica_cinco_sigma(self):
"""Análise estatística com precisão 5-sigma (99.99994% confiança)"""
if self.df is None or self.df.empty:
return {"erro": "Nenhum dado carregado"}
analise_avancada = {}
colunas_numericas = self.df.select_dtypes(include=[np.number]).columns
if len(colunas_numericas) == 0:
return {"erro": "Nenhuma coluna numérica encontrada para análise"}
for col in colunas_numericas:
dados = self.df[col].dropna()
if len(dados) < 2:
continue
try:
# Estatísticas básicas
media = float(dados.mean())
mediana = float(dados.median())
desvio = float(dados.std())
if desvio == 0:
desvio = 0.0001 # Evitar divisão por zero
# 5-sigma bounds (99.99994% confiança)
limite_inf_5sigma = media - 5 * desvio
limite_sup_5sigma = media + 5 * desvio
# 3-sigma bounds (99.7% confiança)
limite_inf_3sigma = media - 3 * desvio
limite_sup_3sigma = media + 3 * desvio
# Outliers em diferentes níveis
outliers_5sigma = int(len(dados[(dados < limite_inf_5sigma) | (dados > limite_sup_5sigma)]))
outliers_3sigma = int(len(dados[(dados < limite_inf_3sigma) | (dados > limite_sup_3sigma)]))
# IQR para outliers tradicionais
q1 = float(dados.quantile(0.25))
q3 = float(dados.quantile(0.75))
iqr = q3 - q1
if iqr > 0:
outliers_iqr = int(len(dados[(dados < q1 - 1.5*iqr) | (dados > q3 + 1.5*iqr)]))
else:
outliers_iqr = 0
# Testes de normalidade
if len(dados) >= 3:
try:
shapiro_stat, shapiro_p = stats.shapiro(dados.sample(min(5000, len(dados))))
shapiro_stat = float(shapiro_stat)
shapiro_p = float(shapiro_p)
except:
shapiro_stat, shapiro_p = 0.0, 1.0
else:
shapiro_stat, shapiro_p = 0.0, 1.0
# Intervalo de confiança 99.99994% (5-sigma)
try:
ic_5sigma = stats.t.interval(0.9999994, len(dados)-1,
loc=media,
scale=stats.sem(dados))
ic_5sigma_inf = float(ic_5sigma[0])
ic_5sigma_sup = float(ic_5sigma[1])
except:
ic_5sigma_inf = limite_inf_5sigma
ic_5sigma_sup = limite_sup_5sigma
analise_avancada[col] = {
'media': media,
'mediana': mediana,
'desvio_padrao': desvio,
'assimetria': float(dados.skew()),
'curtose': float(dados.kurtosis()),
'variancia': float(dados.var()),
'coef_variacao': float(desvio / media * 100 if media != 0 else 0),
'intervalo': f"{float(dados.min()):.2f} - {float(dados.max()):.2f}",
'amplitude': float(dados.max() - dados.min()),
'q1': q1,
'q3': q3,
'iqr': iqr,
'outliers_iqr': outliers_iqr,
'outliers_3sigma': outliers_3sigma,
'outliers_5sigma': outliers_5sigma,
'limite_inf_5sigma': limite_inf_5sigma,
'limite_sup_5sigma': limite_sup_5sigma,
'ic_5sigma_inf': ic_5sigma_inf,
'ic_5sigma_sup': ic_5sigma_sup,
'normalidade_shapiro_stat': shapiro_stat,
'normalidade_shapiro_p': shapiro_p,
'eh_normal': shapiro_p > 0.05,
'confianca_5sigma': '99.99994%'
}
except Exception as e:
print(f"Erro ao processar coluna {col}: {str(e)}")
continue
if len(analise_avancada) == 0:
return {"erro": "Não foi possível analisar nenhuma coluna"}
self.analises_realizadas.append("Análise 5-sigma realizada")
self.historico_analises['cinco_sigma'] = analise_avancada
return analise_avancada
def gerar_visualizacoes_interativas(self):
"""Gera visualizações interativas de alta qualidade"""
if self.df is None or self.df.empty:
return None, "❌ Nenhum dado carregado"
try:
colunas_numericas = self.df.select_dtypes(include=[np.number]).columns
colunas_categoricas = self.df.select_dtypes(include=['object', 'category']).columns
if len(colunas_numericas) == 0 and len(colunas_categoricas) == 0:
return None, "❌ Nenhuma coluna válida para visualização"
figuras = []
# 1. Heatmap de correlação com anotações
if len(colunas_numericas) > 1:
try:
corr_matrix = self.df[colunas_numericas].corr()
fig_corr = px.imshow(
corr_matrix,
title="🔥 Mapa de Correlação - Análise 5-Sigma",
color_continuous_scale="RdBu_r",
aspect="auto",
text_auto='.2f'
)
fig_corr.update_layout(
height=600,
title_font_size=20,
title_x=0.5
)
figuras.append(fig_corr)
except Exception as e:
print(f"Erro no heatmap: {e}")
# 2. Distribuições com limites 5-sigma
if len(colunas_numericas) > 0:
for col in list(colunas_numericas)[:4]:
try:
dados = self.df[col].dropna()
if len(dados) < 2:
continue
media = dados.mean()
desvio = dados.std()
fig = go.Figure()
# Histograma
fig.add_trace(go.Histogram(
x=dados,
name='Distribuição',
nbinsx=50,
marker_color='lightblue',
opacity=0.7
))
# Linhas de referência (5-sigma)
fig.add_vline(x=media, line_dash="dash", line_color="red",
annotation_text="Média", annotation_position="top")
if desvio > 0:
fig.add_vline(x=media - 5*desvio, line_dash="dot", line_color="orange",
annotation_text="-5σ", annotation_position="bottom left")
fig.add_vline(x=media + 5*desvio, line_dash="dot", line_color="orange",
annotation_text="+5σ", annotation_position="bottom right")
fig.update_layout(
title=f"📊 Distribuição com Limites 5-Sigma: {col}",
xaxis_title=col,
yaxis_title="Frequência",
height=500,
showlegend=True
)
figuras.append(fig)
except Exception as e:
print(f"Erro no histograma {col}: {e}")
continue
# 3. Box plots comparativos
if len(colunas_numericas) > 0:
try:
fig_box = go.Figure()
for col in list(colunas_numericas)[:10]: # Máximo 10 variáveis
dados_col = self.df[col].dropna()
if len(dados_col) > 0:
fig_box.add_trace(go.Box(
y=dados_col,
name=str(col),
boxmean='sd'
))
fig_box.update_layout(
title="📦 Box Plots Comparativos - Variáveis Numéricas",
yaxis_title="Valores",
height=500,
showlegend=True
)
figuras.append(fig_box)
except Exception as e:
print(f"Erro no boxplot: {e}")
# 4. Gráfico de barras para categóricas
if len(colunas_categoricas) > 0:
for col_cat in list(colunas_categoricas)[:2]:
try:
contagem = self.df[col_cat].value_counts().head(15)
if len(contagem) > 0:
fig_bar = px.bar(
x=contagem.index,
y=contagem.values,
title=f"📊 Top 15 - {col_cat}",
labels={'x': col_cat, 'y': 'Contagem'},
color=contagem.values,
color_continuous_scale='Viridis'
)
fig_bar.update_layout(height=500, showlegend=False)
figuras.append(fig_bar)
except Exception as e:
print(f"Erro no gráfico de barras {col_cat}: {e}")
continue
if len(figuras) == 0:
return None, "❌ Não foi possível gerar visualizações"
self.analises_realizadas.append("Visualizações interativas geradas")
return figuras, f"✅ {len(figuras)} visualizações criadas com sucesso!"
except Exception as e:
return None, f"❌ Erro nas visualizações: {str(e)}"
def gerar_relatorio_executivo(self):
"""Gera relatório executivo completo em HTML"""
if self.df is None or self.df.empty:
return "<h3>❌ Nenhum dado carregado para análise</h3>"
try:
analise_exp = self.analise_exploratoria()
if 'erro' in analise_exp:
return f"<h3>❌ {analise_exp['erro']}</h3>"
# Garantir que a análise 5-sigma foi executada
if 'cinco_sigma' not in self.historico_analises:
analise_sigma = self.analise_estatistica_cinco_sigma()
else:
analise_sigma = self.historico_analises['cinco_sigma']
if 'erro' in analise_sigma:
return f"<h3>❌ {analise_sigma['erro']}</h3>"
html_relatorio = f"""
<div style="font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; max-width: 1400px; margin: 20px auto; padding: 20px; background: #ffffff; border-radius: 15px; box-shadow: 0 8px 16px rgba(0,0,0,0.1);">
<!-- Cabeçalho Principal -->
<div style="background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); color: white; padding: 40px; border-radius: 15px; margin-bottom: 30px; text-align: center;">
<h1 style="margin: 0; font-size: 3em; font-weight: 700; text-shadow: 2px 2px 4px rgba(0,0,0,0.2);">📊 RELATÓRIO EXECUTIVO</h1>
<p style="font-size: 1.3em; opacity: 0.95; margin-top: 15px;">Análise de Dados com Precisão 5-Sigma (99.99994% Confiança)</p>
<p style="font-size: 1.1em; opacity: 0.85; margin-top: 10px;">📅 {datetime.now().strftime('%d/%m/%Y %H:%M:%S')}</p>
</div>
<!-- KPIs Principais -->
<div style="background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%); padding: 30px; border-radius: 15px; margin-bottom: 30px; color: white;">
<h2 style="margin: 0 0 20px 0; text-align: center; font-size: 2em;">🎯 Indicadores Chave (KPIs)</h2>
<div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 20px;">
<div style="background: rgba(255,255,255,0.2); backdrop-filter: blur(10px); padding: 20px; border-radius: 12px; text-align: center; border: 2px solid rgba(255,255,255,0.3);">
<div style="font-size: 2.5em; font-weight: bold;">📈</div>
<p style="margin: 10px 0 5px 0; font-size: 0.9em; opacity: 0.9;">Total de Registros</p>
<p style="font-size: 2em; font-weight: bold; margin: 0;">{self.df.shape[0]:,}</p>
</div>
<div style="background: rgba(255,255,255,0.2); backdrop-filter: blur(10px); padding: 20px; border-radius: 12px; text-align: center; border: 2px solid rgba(255,255,255,0.3);">
<div style="font-size: 2.5em; font-weight: bold;">🔢</div>
<p style="margin: 10px 0 5px 0; font-size: 0.9em; opacity: 0.9;">Variáveis Numéricas</p>
<p style="font-size: 2em; font-weight: bold; margin: 0;">{len(analise_exp['colunas_numericas'])}</p>
</div>
<div style="background: rgba(255,255,255,0.2); backdrop-filter: blur(10px); padding: 20px; border-radius: 12px; text-align: center; border: 2px solid rgba(255,255,255,0.3);">
<div style="font-size: 2.5em; font-weight: bold;">📝</div>
<p style="margin: 10px 0 5px 0; font-size: 0.9em; opacity: 0.9;">Variáveis Categóricas</p>
<p style="font-size: 2em; font-weight: bold; margin: 0;">{len(analise_exp['colunas_categoricas'])}</p>
</div>
<div style="background: rgba(255,255,255,0.2); backdrop-filter: blur(10px); padding: 20px; border-radius: 12px; text-align: center; border: 2px solid rgba(255,255,255,0.3);">
<div style="font-size: 2.5em; font-weight: bold;">💾</div>
<p style="margin: 10px 0 5px 0; font-size: 0.9em; opacity: 0.9;">Memória Utilizada</p>
<p style="font-size: 2em; font-weight: bold; margin: 0;">{analise_exp['memoria_uso']}</p>
</div>
</div>
</div>
<!-- Análise 5-Sigma -->
<div style="background: linear-gradient(135deg, #fa709a 0%, #fee140 100%); padding: 30px; border-radius: 15px; margin-bottom: 30px; color: #2c3e50;">
<h2 style="margin: 0 0 20px 0; text-align: center; font-size: 2em; color: white; text-shadow: 1px 1px 3px rgba(0,0,0,0.3);">🔬 ANÁLISE ESTATÍSTICA 5-SIGMA</h2>
"""
for col, stats in analise_sigma.items():
status_normalidade = "✅ Normal" if stats['eh_normal'] else "⚠️ Não-Normal"
cor_normalidade = "#27ae60" if stats['eh_normal'] else "#e74c3c"
html_relatorio += f"""
<div style="background: white; padding: 25px; margin: 15px 0; border-radius: 12px; box-shadow: 0 4px 8px rgba(0,0,0,0.1); border-left: 6px solid #3498db;">
<h3 style="color: #2c3e50; margin: 0 0 20px 0; font-size: 1.5em; display: flex; align-items: center; justify-content: space-between;">
<span>📊 {col}</span>
<span style="background: {cor_normalidade}; color: white; padding: 5px 15px; border-radius: 20px; font-size: 0.7em;">{status_normalidade}</span>
</h3>
<div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); gap: 15px; margin-bottom: 20px;">
<div style="background: #ecf0f1; padding: 15px; border-radius: 8px;">
<strong style="color: #7f8c8d;">📈 Média:</strong> <span style="font-size: 1.2em; color: #2c3e50;">{stats['media']:.4f}</span>
</div>
<div style="background: #ecf0f1; padding: 15px; border-radius: 8px;">
<strong style="color: #7f8c8d;">📊 Mediana:</strong> <span style="font-size: 1.2em; color: #2c3e50;">{stats['mediana']:.4f}</span>
</div>
<div style="background: #ecf0f1; padding: 15px; border-radius: 8px;">
<strong style="color: #7f8c8d;">📉 Desvio Padrão:</strong> <span style="font-size: 1.2em; color: #2c3e50;">{stats['desvio_padrao']:.4f}</span>
</div>
<div style="background: #ecf0f1; padding: 15px; border-radius: 8px;">
<strong style="color: #7f8c8d;">📐 Coef. Variação:</strong> <span style="font-size: 1.2em; color: #2c3e50;">{stats['coef_variacao']:.2f}%</span>
</div>
</div>
<div style="background: #fff3cd; border-left: 4px solid #ffc107; padding: 15px; border-radius: 8px; margin-bottom: 15px;">
<h4 style="margin: 0 0 10px 0; color: #856404;">🎯 Limites 5-Sigma (Confiança: {stats['confianca_5sigma']})</h4>
<div style="display: grid; grid-template-columns: 1fr 1fr; gap: 10px;">
<div><strong>Limite Inferior:</strong> {stats['limite_inf_5sigma']:.4f}</div>
<div><strong>Limite Superior:</strong> {stats['limite_sup_5sigma']:.4f}</div>
<div><strong>IC 5σ Inferior:</strong> {stats['ic_5sigma_inf']:.4f}</div>
<div><strong>IC 5σ Superior:</strong> {stats['ic_5sigma_sup']:.4f}</div>
</div>
</div>
<div style="display: grid; grid-template-columns: repeat(3, 1fr); gap: 15px; margin-bottom: 15px;">
<div style="background: #d4edda; padding: 15px; border-radius: 8px; text-align: center; border: 2px solid #28a745;">
<div style="font-size: 2em; font-weight: bold; color: #155724;">{stats['outliers_iqr']}</div>
<div style="color: #155724; font-size: 0.9em;">Outliers IQR</div>
</div>
<div style="background: #fff3cd; padding: 15px; border-radius: 8px; text-align: center; border: 2px solid #ffc107;">
<div style="font-size: 2em; font-weight: bold; color: #856404;">{stats['outliers_3sigma']}</div>
<div style="color: #856404; font-size: 0.9em;">Outliers 3σ (99.7%)</div>
</div>
<div style="background: #f8d7da; padding: 15px; border-radius: 8px; text-align: center; border: 2px solid #dc3545;">
<div style="font-size: 2em; font-weight: bold; color: #721c24;">{stats['outliers_5sigma']}</div>
<div style="color: #721c24; font-size: 0.9em;">Outliers 5σ (99.99994%)</div>
</div>
</div>
<div style="background: #e7f3ff; padding: 15px; border-radius: 8px; border-left: 4px solid #2196f3;">
<div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 10px;">
<div><strong>Assimetria:</strong> {stats['assimetria']:.4f}</div>
<div><strong>Curtose:</strong> {stats['curtose']:.4f}</div>
<div><strong>Q1:</strong> {stats['q1']:.4f}</div>
<div><strong>Q3:</strong> {stats['q3']:.4f}</div>
<div><strong>IQR:</strong> {stats['iqr']:.4f}</div>
<div><strong>Amplitude:</strong> {stats['amplitude']:.4f}</div>
</div>
</div>
<div style="background: #f0f0f0; padding: 12px; border-radius: 8px; margin-top: 15px; font-size: 0.9em;">
<strong>📋 Teste Shapiro-Wilk:</strong>
Estatística = {stats['normalidade_shapiro_stat']:.6f},
p-valor = {stats['normalidade_shapiro_p']:.6f}
</div>
</div>
"""
html_relatorio += """
</div>
<!-- Insights Automáticos -->
<div style="background: linear-gradient(135deg, #a8edea 0%, #fed6e3 100%); padding: 30px; border-radius: 15px; margin-bottom: 30px;">
<h2 style="margin: 0 0 20px 0; text-align: center; font-size: 2em; color: #2c3e50;">💡 INSIGHTS AUTOMÁTICOS</h2>
<div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(350px, 1fr)); gap: 15px;">
"""
insights = self.gerar_insights_automaticos()
cores_insights = ['#3498db', '#e74c3c', '#2ecc71', '#f39c12', '#9b59b6', '#1abc9c']
for i, insight in enumerate(insights):
cor = cores_insights[i % len(cores_insights)]
html_relatorio += f"""
<div style="background: white; padding: 20px; border-radius: 10px; border-left: 5px solid {cor}; box-shadow: 0 2px 5px rgba(0,0,0,0.1);">
<p style="margin: 0; color: #2c3e50; line-height: 1.6;">{insight}</p>
</div>
"""
html_relatorio += f"""
</div>
</div>
<!-- Rodapé -->
<div style="text-align: center; margin-top: 40px; padding: 30px; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); border-radius: 15px; color: white;">
<h3 style="margin: 0 0 15px 0;">✨ DataAnalyzer Pro - Análise 5-Sigma</h3>
<p style="margin: 5px 0; opacity: 0.9;">Precisão Estatística de 99.99994% | Confiança de 5 Desvios Padrão</p>
<p style="margin: 5px 0; opacity: 0.85;">Relatório gerado em {datetime.now().strftime('%d/%m/%Y às %H:%M:%S')}</p>
<p style="margin: 15px 0 0 0; font-size: 0.9em; opacity: 0.75;">© 2025 DataAnalyzer Pro - Todos os direitos reservados</p>
</div>
</div>
"""
return html_relatorio
except Exception as e:
return f"<div style='padding: 20px; color: red;'>❌ Erro ao gerar relatório: {str(e)}</div>"
def gerar_insights_automaticos(self):
"""Gera insights automáticos com análise 5-sigma"""
insights = []
try:
if self.df is None or 'cinco_sigma' not in self.historico_analises:
self.analise_estatistica_cinco_sigma()
if 'cinco_sigma' not in self.historico_analises:
return ["✅ Execute a análise estatística para gerar insights automáticos"]
analise_sigma = self.historico_analises['cinco_sigma']
if 'erro' in analise_sigma:
return ["⚠️ Não foi possível gerar insights devido a erro na análise"]
for col, stats in analise_sigma.items():
# Insight sobre normalidade
if stats['eh_normal']:
insights.append(f"✅ <strong>{col}</strong>: Distribuição normal confirmada (p-valor Shapiro: {stats['normalidade_shapiro_p']:.4f}). Métodos paramétricos podem ser aplicados com segurança.")
else:
insights.append(f"⚠️ <strong>{col}</strong>: Distribuição não-normal detectada. Considere transformações ou métodos não-paramétricos.")
# Insight sobre variabilidade
cv = stats['coef_variacao']
if cv < 10:
insights.append(f"📊 <strong>{col}</strong>: Baixa variabilidade (CV: {cv:.2f}%) - Dados muito homogêneos.")
elif cv > 30:
insights.append(f"📈 <strong>{col}</strong>: Alta variabilidade (CV: {cv:.2f}%) - Considere segmentação dos dados.")
# Insight sobre outliers 5-sigma
if stats['outliers_5sigma'] > 0:
insights.append(f"🎯 <strong>{col}</strong>: {stats['outliers_5sigma']} valores extremos detectados fora dos limites 5-sigma (eventos raríssimos).")
elif stats['outliers_3sigma'] > 0:
insights.append(f"⚡ <strong>{col}</strong>: {stats['outliers_3sigma']} outliers moderados (fora de 3σ) mas dentro de 5σ.")
# Insight sobre assimetria
skew = abs(stats['assimetria'])
if skew > 1:
direcao = "positiva (cauda à direita)" if stats['assimetria'] > 0 else "negativa (cauda à esquerda)"
insights.append(f"📐 <strong>{col}</strong>: Assimetria {direcao} forte (|skew|={skew:.2f}). Considere transformação logarítmica.")
# Insight sobre curtose
if abs(stats['curtose']) > 3:
tipo = "leptocúrtica (caudas pesadas)" if stats['curtose'] > 0 else "platicúrtica (caudas leves)"
insights.append(f"📉 <strong>{col}</strong>: Distribuição {tipo} - valores extremos {'mais' if stats['curtose'] > 0 else 'menos'} prováveis que distribuição normal.")
# Insight geral sobre qualidade dos dados
total_outliers_5sigma = sum(s['outliers_5sigma'] for s in analise_sigma.values() if isinstance(s, dict))
if total_outliers_5sigma == 0:
insights.append(f"🏆 <strong>Excelente!</strong> Nenhum outlier 5-sigma detectado em {len(analise_sigma)} variáveis. Dados de altíssima qualidade estatística.")
return insights[:10] if insights else ["✅ Análise concluída com sucesso"]
except Exception as e:
return [f"⚠️ Erro ao gerar insights: {str(e)}"]
# ========== INTERFACE GRADIO ==========
analisador = AnalisadorDadosAvancado()
def interface_carregar_dados(arquivo, tipo_dados, json_texto):
"""Interface para carregamento de dados"""
try:
if tipo_dados == "json_arquivo" and arquivo is not None:
sucesso, mensagem = analisador.carregar_dados(arquivo, "json")
elif tipo_dados == "json_texto" and json_texto.strip():
sucesso, mensagem = analisador.carregar_dados(json_texto, "json")
elif tipo_dados == "csv" and arquivo is not None:
sucesso, mensagem = analisador.carregar_dados(arquivo, "csv")
elif tipo_dados == "excel" and arquivo is not None:
sucesso, mensagem = analisador.carregar_dados(arquivo, "excel")
else:
return None, "⚠️ Selecione um arquivo ou insira dados JSON"
if sucesso:
analise = analisador.analise_exploratoria()
if 'erro' in analise:
return None, f"❌ {analise['erro']}"
resumo = f"""
## ✅ Dados Carregados com Sucesso!
### 📊 Resumo Geral
- **Dimensões:** {analise['dimensoes']}
- **Variáveis Numéricas:** {len(analise['colunas_numericas'])}
- **Variáveis Categóricas:** {len(analise['colunas_categoricas'])}
- **Uso de Memória:** {analise['memoria_uso']}
### 🔍 Variáveis Detectadas
**Numéricas:** {', '.join(analise['colunas_numericas'][:5])}{'...' if len(analise['colunas_numericas']) > 5 else ''}
**Categóricas:** {', '.join(analise['colunas_categoricas'][:5])}{'...' if len(analise['colunas_categoricas']) > 5 else ''}
"""
return analisador.df.head(20), resumo
else:
return None, mensagem
except Exception as e:
return None, f"❌ Erro: {str(e)}"
def interface_visualizacoes():
"""Interface para geração de visualizações"""
try:
if analisador.df is None:
return None, None, "❌ Carregue dados primeiro na aba '1. Carregar Dados'"
figuras, mensagem = analisador.gerar_visualizacoes_interativas()
if figuras and len(figuras) > 0:
fig1 = figuras[0] if len(figuras) > 0 else None
fig2 = figuras[1] if len(figuras) > 1 else figuras[0]
return fig1, fig2, mensagem
else:
return None, None, mensagem
except Exception as e:
return None, None, f"❌ Erro: {str(e)}"
def interface_relatorio():
"""Interface para geração de relatório"""
try:
if analisador.df is None:
return "<div style='padding: 20px; color: red;'>❌ Carregue dados primeiro na aba '1. Carregar Dados'</div>"
relatorio = analisador.gerar_relatorio_executivo()
return relatorio
except Exception as e:
return f"<div style='padding: 20px; color: red;'>❌ Erro ao gerar relatório: {str(e)}</div>"
def interface_analise_estatistica():
"""Interface para análise estatística 5-sigma"""
try:
if analisador.df is None:
return "❌ Carregue dados primeiro na aba '1. Carregar Dados'"
analise = analisador.analise_estatistica_cinco_sigma()
if isinstance(analise, dict) and 'erro' in analise:
return f"❌ {analise['erro']}"
resultado = "# 📊 ANÁLISE ESTATÍSTICA 5-SIGMA\n\n"
resultado += "*Precisão de 99.99994% de confiança estatística*\n\n"
resultado += "---\n\n"
for col, stats in analise.items():
if not isinstance(stats, dict):
continue
status = "✅ Normal" if stats['eh_normal'] else "⚠️ Não-Normal"
resultado += f"## 📈 {col} {status}\n\n"
resultado += f"### Estatísticas Centrais\n"
resultado += f"- **Média:** {stats['media']:.6f}\n"
resultado += f"- **Mediana:** {stats['mediana']:.6f}\n"
resultado += f"- **Desvio Padrão:** {stats['desvio_padrao']:.6f}\n"
resultado += f"- **Coeficiente de Variação:** {stats['coef_variacao']:.2f}%\n\n"
resultado += f"### Análise 5-Sigma (Confiança: {stats['confianca_5sigma']})\n"
resultado += f"- **Limite Inferior 5σ:** {stats['limite_inf_5sigma']:.6f}\n"
resultado += f"- **Limite Superior 5σ:** {stats['limite_sup_5sigma']:.6f}\n"
resultado += f"- **IC 5σ Inferior:** {stats['ic_5sigma_inf']:.6f}\n"
resultado += f"- **IC 5σ Superior:** {stats['ic_5sigma_sup']:.6f}\n\n"
resultado += f"### Detecção de Outliers\n"
resultado += f"- **Outliers IQR (Método Tradicional):** {stats['outliers_iqr']}\n"
resultado += f"- **Outliers 3σ (99.7% confiança):** {stats['outliers_3sigma']}\n"
resultado += f"- **Outliers 5σ (99.99994% confiança):** {stats['outliers_5sigma']}\n\n"
resultado += f"### Forma da Distribuição\n"
resultado += f"- **Assimetria (Skewness):** {stats['assimetria']:.6f}\n"
resultado += f"- **Curtose (Kurtosis):** {stats['curtose']:.6f}\n"
resultado += f"- **Teste Shapiro-Wilk:** Estatística={stats['normalidade_shapiro_stat']:.6f}, p-valor={stats['normalidade_shapiro_p']:.6f}\n\n"
resultado += f"### Quartis e Dispersão\n"
resultado += f"- **Q1 (25%):** {stats['q1']:.6f}\n"
resultado += f"- **Q3 (75%):** {stats['q3']:.6f}\n"
resultado += f"- **IQR (Intervalo Interquartil):** {stats['iqr']:.6f}\n"
resultado += f"- **Amplitude Total:** {stats['amplitude']:.6f}\n\n"
resultado += "---\n\n"
return resultado
except Exception as e:
return f"❌ Erro na análise: {str(e)}"
# ========== CONFIGURAÇÃO DA INTERFACE GRADIO ==========
with gr.Blocks(
theme=gr.themes.Soft(
primary_hue="indigo",
secondary_hue="purple",
neutral_hue="slate",
),
title="📊 DataAnalyzer Pro - Análise 5-Sigma",
css="""
.gradio-container {
max-width: 1600px !important;
font-family: 'Inter', 'Segoe UI', sans-serif;
}
"""
) as demo:
gr.Markdown("""
# 📊 DataAnalyzer Pro - Sistema de Análise 5-Sigma
## *Precisão Estatística de 99.99994% | Análise de Dados de Nível Científico*
> **5-Sigma**: O padrão ouro em análise estatística - usado em descobertas científicas como o Bóson de Higgs.
> Representa uma confiança de 99.99994%, equivalente a apenas 1 falso positivo em 3.5 milhões de observações.
""")
with gr.Tab("📁 1. Carregar Dados"):
gr.Markdown("""
### 🔧 Importação de Dados
Suporte completo para **JSON**, **CSV** e **Excel** com validação automática e detecção de tipos.
""")
with gr.Row():
with gr.Column(scale=1):
tipo_dados = gr.Radio(
choices=["json_arquivo", "json_texto", "csv", "excel"],
label="📂 Formato dos Dados",
value="json_arquivo",
info="Escolha o formato do seu dataset"
)
arquivo_upload = gr.File(
label="📤 Upload de Arquivo",
file_types=[".json", ".csv", ".xlsx", ".xls"],
visible=True
)
json_input = gr.Textbox(
label="📝 Dados JSON (Colar aqui)",
placeholder='[{"variavel1": 100, "variavel2": "categoria"}, ...]',
lines=8,
visible=False
)
carregar_btn = gr.Button("🚀 Carregar e Analisar", variant="primary", size="lg")
with gr.Column(scale=2):
gr.Markdown("### 👁️ Pré-visualização dos Dados")
preview_tabela = gr.Dataframe(
label="Primeiras 20 linhas do dataset",
interactive=False,
wrap=True
)
info_carregamento = gr.Markdown(
value="💡 **Aguardando dados...** Faça upload de um arquivo ou cole dados JSON."
)
with gr.Tab("📈 2. Visualizações Interativas"):
gr.Markdown("""
### 🎨 Visualizações com Plotly
Gráficos interativos de alta qualidade incluindo limites 5-sigma, distribuições e análises multivariadas.
""")
with gr.Row():
gerar_viz_btn = gr.Button("🎨 Gerar Todas as Visualizações", variant="primary", size="lg")
with gr.Row():
with gr.Column():
visualizacao_1 = gr.Plot(label="📊 Visualização 1")
with gr.Column():
visualizacao_2 = gr.Plot(label="📊 Visualização 2")
info_visualizacoes = gr.Markdown(value="Clique no botão acima para gerar visualizações interativas")
with gr.Tab("🔬 3. Análise Estatística 5-Sigma"):
gr.Markdown("""
### 📐 Análise com Precisão Científica
**O que é 5-Sigma?**
- 📊 **Confiança:** 99.99994% (praticamente certeza absoluta)
- 🎯 **Aplicação:** Usado em física de partículas, controle de qualidade Six Sigma
- ⚡ **Outliers:** Detecta apenas eventos extremamente raros
- 🔬 **Comparação:** 3-sigma = 99.7% | 5-sigma = 99.99994%
""")
with gr.Row():
analise_estat_btn = gr.Button("📐 Executar Análise 5-Sigma Completa", variant="primary", size="lg")
resultado_estatistica = gr.Markdown(
label="📋 Resultados da Análise",
value="Clique no botão para iniciar a análise estatística com precisão 5-sigma"
)
with gr.Tab("📋 4. Relatório Executivo"):
gr.Markdown("""
### 📄 Relatório Automático Completo
Relatório HTML profissional com todos os KPIs, estatísticas 5-sigma, visualizações e insights automáticos.
""")
with gr.Row():
gerar_relatorio_btn = gr.Button("📄 Gerar Relatório Executivo Completo", variant="primary", size="lg")
relatorio_output = gr.HTML(
label="📊 Relatório Interativo",
value="""
<div style='text-align: center; padding: 100px 20px; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); border-radius: 15px; color: white;'>
<h2 style='margin: 0; font-size: 2em;'>📊 Relatório Executivo</h2>
<p style='margin-top: 20px; font-size: 1.2em; opacity: 0.9;'>Clique no botão acima para gerar o relatório completo</p>
<p style='margin-top: 10px; opacity: 0.8;'>✨ Análise 5-Sigma | KPIs | Insights Automáticos</p>
</div>
"""
)
# ========== EVENTOS E INTERAÇÕES ==========
def atualizar_inputs(tipo_dados):
if tipo_dados == "json_texto":
return gr.update(visible=False), gr.update(visible=True)
else:
return gr.update(visible=True), gr.update(visible=False)
tipo_dados.change(
atualizar_inputs,
inputs=[tipo_dados],
outputs=[arquivo_upload, json_input]
)
carregar_btn.click(
interface_carregar_dados,
inputs=[arquivo_upload, tipo_dados, json_input],
outputs=[preview_tabela, info_carregamento]
)
gerar_viz_btn.click(
interface_visualizacoes,
outputs=[visualizacao_1, visualizacao_2, info_visualizacoes]
)
analise_estat_btn.click(
interface_analise_estatistica,
outputs=[resultado_estatistica]
)
gerar_relatorio_btn.click(
interface_relatorio,
outputs=[relatorio_output]
)
# ========== EXECUÇÃO ==========
if __name__ == "__main__":
demo.launch(
server_name="0.0.0.0",
server_port=7860,
share=True,
show_error=True
)